Browse the beta.3 manual
tools/ppops-payer/docs/THREAT-MODEL.md0.1.0-beta.3 / release

Payer threat model

Spending authority and the reference payer's trust assumptions.

This manual targets 0.1.0-beta.3. Read the source and availability policy before installing. Historical reports retain their original scope.

Security objective

ppops-payer should make one bounded RAILGUN payment requested by a trusted PPOps merchant without exposing payer spending material or silently changing the recipient, token, chain, amount, memo or intent.

Gate A is diagnostic. It does not hide the public EVM address that signs and pays gas for submission. Gate B removes that self-signer from submission by using an operator-pinned RAILGUN Waku Broadcaster, but does not provide network-layer anonymity.

Assets

  • payer RAILGUN recovery mnemonic and spending authority;
  • self-signing EVM private key and its Arbitrum ETH;
  • ephemeral shield ownership key when separate funding tooling is used;
  • encrypted RAILGUN wallet database and its encryption key;
  • payer RAILGUN address, balances, transaction history and private memos;
  • merchant signer identity and signed PPOps request;
  • Broadcaster fee-signer trust configuration, quote identity and maximum fee;
  • reserved transaction nullifiers used to recover an ambiguous submission;
  • RPC and PPOI credentials/metadata.

Trust boundaries

local secret files -> payer process -> RAILGUN Wallet SDK/artifacts
                                  -> RPC providers/PPOI nodes
PPOps request URL  -> signature verification -> bounded transaction
operator trust file -> Waku fee authorization -> selected Broadcaster
encrypted transaction -> Waku peers/Broadcaster -> Arbitrum

The operator trusts the local host, installed dependency lockfile, independently pinned merchant signer, Arbitrum/RAILGUN contracts and configured external providers. RPC and PPOI services are not assumed confidential or continuously available.

Main threats and controls

Threat Control Residual risk
Malicious checkout changes recipient or amount Exact EIP-712 verification against an independently pinned signer; request/descriptor field equality A compromised trusted merchant signing key can authorize a malicious request
Accidental wrong/large/expired payment Arbitrum/native-USDC pinning, fresh OPEN request, exact intent confirmation, independent maximum atomic amount, and full live-request revalidation after proof generation Operator can deliberately confirm the wrong valid intent; mining can still occur after expiry
Secret disclosure through arguments/logs File-only secrets, owner/permission/symlink checks, stable redacted failures, executable privacy check Compromised host/dependencies can read process memory
Incorrect shield-key derivation Tested fixed-message signature validation followed by keccak256; raw signatures and derived keys are never printed Public funding/shielding remains outside the payment harness and links its EVM sender onchain
Secret committed to Git secrets/, config, data and common key extensions ignored Manually forcing an ignored file can still publish it
Wrong payer wallet imported Persistent wallet identity plus mandatory expected 0zk address at submission Operator can copy an already-wrong address instead of checking it out of band
Wrong public signer or excessive RPC fee Mandatory expected EVM address, explicit maximum gas cost and public gas-balance check A malicious dependency could still alter behavior after checks
Malicious/stale Broadcaster quote or excessive token fee Owner-pinned trusted fee signers, native-USDC quote validation, reliability/lifetime floors, SDK-authorized fee range, explicit atomic fee ceiling and payment + fee balance check; after proof, exact quote is preferred and rotation is accepted only with identical Broadcaster/token/fee rate Trusted fee signers, Waku client and selected Broadcaster remain external dependencies; a compatible fee-ID rotation still relies on the Broadcaster retaining that authorized quote
Broadcaster redirects the populated call Local proof/population pins the RAILGUN proxy, zero ETH value, exact recipient/memo/token/amount and pre-transaction PPOI data before encrypted submission A compromised payer dependency can execute inside the secret-bearing process
Scan starts too late and misses funds Explicit creation block at or before first relevant note Incorrect operator input can produce an incomplete balance
Concurrent payer processes Owner-only runtime lock spans wallet load, sync, proof generation and submission A stale lock whose PID was reused can require operator cleanup
RPC outage, wrong chain or gas-price outlier At least two distinct configured origins; 15-second local deadlines; strict healthy majority; upper-median gas selection; explicit fee ceilings; strict identical-receipt quorum RAILGUN SDK fallback behavior, a high outlier in a two-provider profile and correlated providers remain dependencies
PPOI delay/block Balance buckets are reported; finalize-poi binds proof generation to an exact MINED journal record and requires node acknowledgement; PPOps requires receiver Spendable External list policy and node availability are outside the harness; chain mining does not imply PPOI completion
Transaction response lost after submission The raw transaction is signed locally; its hash and nonce are persisted before broadcast, reuse is blocked, and receipt state advances through SUBMITTED, MINED or REVERTED RPC/receipt failure still requires resolving the recorded public hash before any new intent is paid
Broadcaster lies about, rejects or loses the response after Waku submission Intent, payer, exact quote, bounded fee and nullifiers are persisted before Waku; the returned hash remains only a report; recovery first derives canonical identity from those nullifiers; a strict RPC majority must agree on receipts. An explicit ambiguity retry must preserve the signed request, payer and complete nullifier set, exclude every attempted Broadcaster identity and stay within a three-retry cap. Any unresolved nullifier is barred from a different intent The reservation can remain unresolved indefinitely after the cap; distinct 0zk identities need not be independent operators; a compromised full-wallet SDK could misderive identity; the operator must not delete or bypass the journal to force a fresh spend
Public sender correlation Explicit Gate A warning and separate Gate B path Inherent to Gate A self-signing; Gate B demonstrates submission without a payer EVM self-signer
Network metadata correlation Broadcaster transaction content is encrypted, but RPC, PPOI, artifact, DNS/Waku and Broadcaster connections originate from the payer host No Tor/mixnet guarantee; timing and IP-layer analysis remain possible
Supply-chain compromise Exact dependency lockfile, build/tests, audit gate Official RAILGUN tree retains low/moderate legacy transitive findings and downloaded proving artifacts remain trusted inputs

Explicit non-goals

  • protecting secrets on a compromised payer host;
  • anonymous network access to RPC, PPOI, artifact or Waku services;
  • hiding Gate A’s public self-signing EVM address;
  • hiding payer host network metadata or proving resistance to timing analysis;
  • key recovery, hardware-wallet custody or multi-user wallet management;
  • bypassing RAILGUN PPOI/standby rules;
  • guaranteeing merchant fulfillment after PPOps reconciliation.

Operational rules

  1. Never place payer spending material on the PPOps merchant host.
  2. Keep runtime config, secrets, LevelDB and evidence outside public artifacts.
  3. Back up the recovery mnemonic independently; the encrypted local database is a cache, not the sole wallet backup.
  4. Use a fresh intent and verify the expected signer immediately before payment.
  5. Treat the self-signed path as Gate A evidence only; a passing Broadcaster payment can support only the narrower claim that the payer self-signer was not used for submission.
  6. After mining, finalize PPOI from the existing journal record; never resend the payment merely because the receiver still reports MissingExternalPOI.
  7. Review Broadcaster signer rotation independently and preserve the local trust fingerprint. Never fetch mutable trust configuration inside a payment.
  8. Treat reportedTransactionHash as diagnostic metadata only. Continue recovery until canonicalTransactionHashResolved is true; never inspect the reported hash and infer that payment succeeded.
  9. After an ambiguous Gate B response, run recover-broadcaster before any retry. Use retry-broadcaster only when the command reports it available; it regenerates a conflicting variant for the exact same nullifiers and excludes identities already attempted.
  10. Never pay a different intent with nullifiers held by a nonterminal Broadcaster journal record. The journal enforces this locally; do not delete or edit it to bypass the check.
  11. After three retry reservations, stop. There is no timeout after which an unknown external submission becomes safe to ignore; resolve it manually or obtain definitive rejection/reversion evidence before releasing the notes.