Privacy, control, and safety
The kill-switch response is deliberately disguised as a different error
When the wallet gate fires, the affected client receives the same PermissionDenied response and message used for a session-identity mismatch. Tests enforce that external indistinguishability; internal logs, metrics, and error codes retain the actual reason. 123
What the evidence shows
Technical and product details
- Documented behavior
A gated wallet receives the same gRPC
PermissionDeniedcode and exact message as an ordinary session-identity mismatch. The tests enforce this indistinguishability invariant. 13Supporting material shown on this page
authz.goPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 38 ErrorCodeIdentityMismatch 39 // ErrorCodeWalletKillSwitched is returned when the wallet kill switch knob 40 // is set for the caller's identity public key. The on-wire response is 41 // deliberately identical to ErrorCodeIdentityMismatch so that probing 42 // callers cannot distinguish a kill-switched wallet from any other 43 // permission failure. SO logs and tests differentiate via this code. 44 ErrorCodeWalletKillSwitchedindistinguishability testPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 65 // EnforceSessionIdentityPublicKeyMatches into its mismatch branch. 66 // Building the Error by hand would only assert that the kill-switch 67 // constant matches itself; calling the real function asserts that the 68 // kill-switch wire surface matches whatever production code actually 69 // emits for identity mismatch. 70 mismatchCtx := authn.InjectSessionForTests(t.Context(), walletB.ToHex(), 0) 71 mismatchErr := EnforceSessionIdentityPublicKeyMatches(mismatchCtx, &simpleConfig{authzEnforced: true}, walletA) - Documented behavior
Only the Operator's internal error code, warning log, and
spark.so.killswitch.blocked_totalmetric reveal that the kill switch fired. 12Supporting material shown on this page
authz.goPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 38 ErrorCodeIdentityMismatch 39 // ErrorCodeWalletKillSwitched is returned when the wallet kill switch knob 40 // is set for the caller's identity public key. The on-wire response is 41 // deliberately identical to ErrorCodeIdentityMismatch so that probing 42 // callers cannot distinguish a kill-switched wallet from any other 43 // permission failure. SO logs and tests differentiate via this code. 44 ErrorCodeWalletKillSwitchedkillswitch.goPinned source code · github.com · checked 2026-07-14 Relevant lines from the pinned source · open raw file 27// gRPC code, same message — so probing callers cannot distinguish a kill 28// switch from any other permission failure. The internal ErrorCode is 29// ErrorCodeWalletKillSwitched so SO logs and unit tests can differentiate. 30// 31// Call this from every state-mutating user-facing handler immediately after 32// EnforceSessionIdentityPublicKeyMatches. Read-only RPCs must NOT call this. 33func EnforceWalletNotKillSwitched(ctx context.Context, identityPublicKey keys.Public) error {
Interpretation
Why this matters for Spark's trust model
The affected user cannot determine from the wire response whether it made an authentication mistake or was deliberately targeted. That obstructs detection, evidence collection, and accountability for selective denial. 123
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.
authz.go
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
killswitch.go
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
indistinguishability test
Pinned source code · github.com · Pinned or archival · checked 2026-07-14
How sources, absence findings, and limitations were evaluated