Privacy, control, and safety
A normal wallet authenticates one persistent identity to every Operator
A normal wallet authenticates the same durable identity to every Operator and queries each for that identity's leaves. Operator code can associate that pseudonym with connection metadata; structured request logging, when enabled, can also record request bodies and client details. 12345678
What the evidence shows
Technical and product details
- Documented behavior
Ordinary wallet initialization creates a client for every configured signing Operator. Authentication to each endpoint presents and signs with the same wallet identity key; a full leaf synchronization then queries every Operator for leaves owned by that identity. 123
Supporting material shown on this page
wallet initializationPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 468 "createClientsAndSyncWallet", 469 `initializing network=${this.config.getNetworkType()} coordinator=${formatUrlForLogs( 470 this.config.getCoordinatorAddress(), 471 )} signingOperators=${Object.keys(this.config.getSigningOperators()).length}`, 472 ); 473 await this.connectionManager.createClients();per-Operator identity authenticationPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 461 }); 462 const protectedChallenge = challengeResp.protectedChallenge; 463 const challenge = protectedChallenge?.challenge; 464 465 if (!challenge) { 466 throw new SparkAuthenticationError( 467 "Invalid challenge response",all-Operator leaf synchronizationPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 292 public async getLeaves(isBalanceCheck: boolean = false): Promise<TreeNode[]> { 293 const ownerIdentityPubkey = await this.config.signer.getIdentityPublicKey(); 294 const coordinatorId = this.config.getCoordinatorIdentifier(); 295 const network = this.config.getNetworkProto(); 296 297 let operators = Object.entries(this.config.getSigningOperators()); 298 if (isBalanceCheck) { - Documented behavior
Operator middleware places the verified identity into the request context and can resolve a client IP from trusted forwarding headers or the direct gRPC peer. 45
Supporting material shown on this page
identity-bound request contextPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 85// AuthnInterceptor validates session tokens and adds session info to the context. 86// Unauthenticated requests are rejected unless the method is explicitly marked as unauthenticated. 87// For unauthenticated methods, we still attempt to extract the session if a token is present. 88func (i *Interceptor) AuthnInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { 89 requireAuth := i.isAuthenticated(info.FullMethod)client-IP extractionPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 14// GetClientIP returns the client IP address from the request context. It first 15// tries the x-forwarded-for header (for production behind an ALB). If XFF is 16// entirely absent (e.g., local dev without ALB), it falls back to the gRPC peer 17// address. If XFF is present but parsing fails (misconfigured position), it does 18// NOT fall back — that's a configuration error that should surface loudly. - Documented behavior
When structured request logging is enabled, the reviewed logger can combine the identity with request bodies, origin, user agent, client environment, session ID, an authorization-token hash, and client IP. The generic protobuf formatter's automatic sensitive-field list contains only the exact field name
secret_share. 678Supporting material shown on this page
request and client-metadata loggerPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 143const omittedResponseMessagePlaceholder = "MSG_OMITTED" 144 145// High-volume read-only gRPC methods whose response body should be omitted from spark-requests, 146// as they dominate log storage and don't typically contain useful or interesting information for 147// debugging. 148var methodsWithoutResponseBodyLogging = map[string]struct{}{ 149 "/spark.SparkService/query_nodes": {},conditional request-logger activationPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 733 clientInfoProvider := sparkgrpc.NewGRPCClientInfoProvider(config.XffClientIpPosition) 734 var tableLogger *logging.TableLogger 735 if args.LogRequestStats && args.LogJSON { 736 tableLogger = logging.NewTableLogger(clientInfoProvider) 737 }protobuf redaction listPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 14// In logstash we have a limit of 131KB (???) for the size of a message, so we don't want to be 15// logging protos that are too big. So put a reasonable limit on this. 16var maxBytes = 32 * 1024 // 32KB 17 18var sensitiveFields = []string{"secret_share"}
Interpretation
Why this matters for Spark's trust model
A durable Spark pseudonym and connection metadata are simultaneously available at every Operator. Network-layer separation and a threshold signature do not make ordinary wallet activity Operator-blind. 23456
This section states the trust-model consequence of the cited evidence. Conditional or inferred claims remain bounded by the next section.
Scope control
What this does not establish
Sources and excerpts
Primary sources
The relevant details and available source-code excerpts appear alongside the claims above. This list preserves the complete original-source trail for independent verification.
wallet initialization
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
per-Operator identity authentication
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
all-Operator leaf synchronization
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
identity-bound request context
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
client-IP extraction
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
request and client-metadata logger
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
conditional request-logger activation
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
protobuf redaction list
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
How sources, absence findings, and limitations were evaluated