TokensConfidentialBest Practices

Best Practices for Auditors

These practices are for whoever holds the secret of an auditor key registered in an auditor registry. Auditing explains what an auditor can see and what its software has to do; this page covers operating that capability safely.

The protocol trusts the auditor with two things: protecting its secret key, and using its access only on legitimate request. Nothing on-chain enforces either.

Key Management

  • Generate the key yourself. Generate the key pair with an auditor client, from a cryptographically secure random source, and hand the registry manager only the public point. Never accept a key generated by someone else, or a test key such as the one in the testnet deployment guide, whose secret is 1.
  • Custody it at least as carefully as a viewing key. The key decrypts every ciphertext addressed to it, for every account bound to its id. The openings it yields are self-verifying: anyone who receives one can check it against the chain.
  • Keep every historical key. Each key decrypts only the events produced while it was active, so a replaced key is still needed for as long as its events may be reviewed. The registry's auditor_rotated events record when each key took over.

Losing the auditor key is permanent. Ciphertexts can't be re-encrypted to a new key, so everything encrypted to a lost key stays unreadable. Until a replacement key has collected fresh openings, the auditor also cannot produce clawback proofs for its accounts. Back up each key before it is registered.

  • Rotate immediately if the key is compromised. A compromised key reveals the amounts and balances of every bound account for as long as it stays active, but it can't spend and it can't read events from before it became active. Rotation protects only what comes after it.
  • Expect a gap after every rotation. A rotation fails every proof in flight, and the new key holds no openings until each account's next withdrawal, outgoing transfer, or set_spender. See Key Rotation.

Running the Auditor Client

  • Ingest continuously and archive everything. The blinding of each allowance is escrowed only in the event that wrote it, so an event missed now can't be recovered later. Run or contract an archive that meets the indexer specification, rather than relying on Stellar RPC's limited window.
  • Check every opening against the chain. Re-commit each opening and compare it with the stored commitment. A mismatch means a missed, reordered, or pruned event. Where you audit both parties of a transfer, also check that the amount decrypts to the same value on both channels.
  • Don't reveal your scope. Asking an RPC provider or a third-party archive for specific accounts tells it which accounts you audit. Fetch the whole contract stream, or run your own node and archive.
  • Use software built for the auditor role. An auditor client must not be able to build a spending witness, and must keep its key and openings out of logs and crash reports. See the Auditor Client specification.

Using Access

  • Decrypt only on legitimate request. The key makes everything in scope readable; whether a given read is justified is a policy question. Keep a record of each access and its reason.
  • Answer narrow questions narrowly. Hand a requester only what it asked for. Where the deployment supports selective disclosure, a D-auditor proof discloses one transfer's amount to one recipient, bound to its request, instead of decrypted records that can be passed on.
  • Attest to completeness only with a gap-free history. A holder can disclose some transfers and withhold others, so requests for completeness come to the auditor. Confirm that the archive reports a complete history for the whole range first.

Supporting Seizures

In a deployment with the clawback extension, the auditor produces the proof that fixes the seized amount and its destination.

  • Prove only after the freeze and every forced revocation. Any change to the account's commitments between proving and submission fails the proof, and each revocation changes the spendable balance.
  • Verify both openings and read the current clawback_nonce before proving. A proof built on stale state or an old nonce is rejected.
  • Check the destination. The proof binds the destination you were asked for, and the admin can't change it. On a SAC, the destination has to be authorized for the asset (for a G... account, an authorized trustline), or the whole seizure reverts.
  • Apply the Clawback event like a merge followed by a debit of its public amount. It carries no encrypted balance, so it is not a checkpoint.