Best Practices for Administrators
These practices are for whoever deploys a confidential token and holds its privileged roles: the token's admin and compliance roles, the managers of the verifier and auditor registries, and the issuer of the underlying asset.
The testnet deployment guide walks through a complete deployment with the Stellar CLI. This page covers what changes between that guide and a production deployment.
Roles and Governance
- Give every role its own account. The testnet guide lets one account hold every role. In production, keep the token's admin, freezing, configuration, and seizure roles on separate accounts, and keep the registries' managers apart from the token's admin, so that no single key can both reconfigure the token and seize funds.
- Prefer immutability. The strongest posture fixes every verification key and the token's links to its
registries at deployment: register the keys in the verifier's constructor, make
update_verification_keyalways panic, and expose no path that callsset_verifierorset_auditorafter construction. See Updating a Verification Key. - Gate what stays mutable. A verification key update, a new verifier or auditor registry, and an auditor key rotation each change which proofs the token accepts or who can read its ciphertexts. Put each behind a multisig and a timelock, and publish enough material for anyone to check the change before it activates.
- Remember that wallets pin verification keys. Wallets must not fetch keys at runtime, so a key update breaks every wallet that hasn't shipped the new key, and every update fails the proofs in flight.
- Monitor configuration events. Watch
verification_key_updatedon the verifier registry,auditor_rotatedon the auditor registry, andverifier_set,auditor_setandcompliance_config_changedon the token. An event no one planned is an incident.
Deploying
- Choose the underlying token carefully. It must meet the underlying token requirements. Over a Stellar Asset Contract (SAC), the issuer can freeze or claw back the token contract's pooled balance, which affects every holder at once.
- Register the pinned keys, then check them. Register the
.vk.binfile of every circuit the deployment uses, from the release you build against, and theClawbackkey only with the clawback extension. Read each key back withget_verification_keyand compare it byte for byte with the pinned file. See Registering Verification Keys. - Never reuse example keys. The testnet guide registers the Grumpkin generator as its auditor key. Its secret is
1, so anyone can decrypt everything encrypted to it. Register only keys generated by the auditor that will hold them. - Restrict auditor selection if the deployment has designated auditors. An account's
auditor_idnever changes, soregisteris the only point where a deployment controls who may see an account's activity. See Restrict Auditor Selection.
Supporting Holders and Auditors
- Publish what users need to verify the deployment. That means the addresses of the token and both registries, the circuit source revision, the proving toolchain versions, the verification key files, the protocol documentation version, and the auditor ids holders may choose, with who operates each.
- Run or contract at least two independent archives that meet the indexer specification. Without one, holders cannot recover once events age out of Stellar RPC, and auditors lose the openings that exist only in events.
- Serve the whole contract stream alongside per-account queries, so wallets and auditors can sync without telling the archive which accounts they follow.
- Announce auditor key rotations. A rotation fails every proof in flight, and the new key holds no openings until each account's next checkpoint, so plan it with the auditor. See Key Rotation.
Compliance Operations
- Wire the hooks before enabling seizure. A token that implements
ConfidentialClawbackneedsComplianceHooks, or a customHooksthat forwards every callback it doesn't customize. Otherwise a freeze blocks nothing and the target can move its balance before the seizure lands. - Enable
sac_passthroughonly over a SAC. Over any other token, every checked operation fails. - Decide who may deposit for whom. By default anyone can deposit into any registered account. Unsolicited deposits complicate an auditor's bookkeeping, while outside payers may be part of your use case. The Compliance page has hooks for both directions.
- Follow the seizure order. Freeze the account, find its delegations from its
SetSpenderandRevokeSpenderevents, revoke each withforce_revoke_spender, and only then ask the auditor for the proof. Prefer adestination. Withdestination = None, seize first and extract the surplus at the SAC afterwards, never the other way round. See Clawback. - Plan the SAC flags before the first deposit. Extracting a surplus with the SAC's own
clawbackrequiresAUTH_CLAWBACK_ENABLEDon the issuer before the token contract's first deposit. Enabling it later doesn't apply to the contract's existing balance. - Expect compliance actions to be public. Freezes and clawbacks name the account, and a clawback publishes its amount and destination.