Skip to content

PaidK: no client provisioning path leaves registered devices permanently 0/K #661

Description

@cryptskii

A fully registered, authenticated device can never satisfy the PaidK spend gate, because nothing on the client side obtains or submits payment receipts.

Evidence

Found during ADR 0003 two-phone hardware validation. A healthy device — registered, publishing successfully, device tree visible on 3/3 nodes (quorum ok), TLS-verified against the fleet CA — was refused by all three storage nodes:

Submit failed 402 Payment Required via https://<node-1>:8080
Submit failed 402 Payment Required via https://<node-2>:8080
Submit failed 402 Payment Required via https://<node-3>:8080
B0x submission failed: quorum not met: 0/3 (K=3)

Querying GET /api/v2/paidk/status/{device_id} on each node returned identically:

satisfied=false  distinct_operators=0  required_k=3

Zero operator receipts on every node — not partial, not drifted. The gate is behaving as written; the device simply has no way to ever satisfy it.

Cause

/api/v2/paidk/receipt and /api/v2/paidk/status/{device_id} are implemented only in dsm_storage_node/src/api/vault/paidk.rs. Searching the tree, there is no client-side caller of either endpoint — no flow that acquires operator receipts, and none that submits them.

require_paidk gates device-initiated writes (b0x/submit, object put/delete) after authentication and envelope decode but before storage admission, with cert-resync as the explicit exception. So the failure mode is: everything works right up to storage admission, then fails permanently with a status code that reads like a billing problem rather than a missing feature.

Impact

Any device that reaches the b0x/submit path on a PaidK-enforcing node is blocked indefinitely. There is no user-facing or programmatic remedy short of direct database intervention on each node.

Note this is per-node: submit_receipt writes only to the local database with no replication, so a K-of-N quorum write path requires PaidK state established independently on every node in the quorum.

What is needed

A defined client provisioning flow that obtains legitimate operator receipts and submits them — plus a sensible surfacing of the unsatisfied state, since a bare 402 during a send is not diagnosable by a user.

The security properties that flow must have are tracked separately.

Workaround used for testing

For the hardware smoke only, devices.paidk_satisfied was set directly on the three test-fleet nodes for the two devices involved. No payment-receipt rows were created. This is recorded as a test-environment override and is not a fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions