Review of Spark's trust model

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

3 sourcesEvidence reviewed through July 14, 2026

What the evidence shows

Technical and product details

  1. Documented behavior

    A gated wallet receives the same gRPC PermissionDenied code and exact message as an ordinary session-identity mismatch. The tests enforce this indistinguishability invariant. 13

    Supporting 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	ErrorCodeWalletKillSwitched
    indistinguishability 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)
  2. Documented behavior

    Only the Operator's internal error code, warning log, and spark.so.killswitch.blocked_total metric reveal that the kill switch fired. 12

    Supporting 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	ErrorCodeWalletKillSwitched
    killswitch.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

  • Concealment is proven. The comment frames it as resistance to probing and does not identify compliance or sanctions as the motive. 12

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.

1

authz.go

Pinned source code · github.com · Pinned or archival · checked 2026-07-14

Open original source
2

killswitch.go

Pinned source code · github.com · Pinned or archival · checked 2026-07-14

Open original source
3

indistinguishability test

Pinned source code · github.com · Pinned or archival · checked 2026-07-14

Open original source

How sources, absence findings, and limitations were evaluated