Skip to content

Signer State Backend

Persistent control-plane state for seal/unseal, runtime auth, and replica coordination

The signer state backend stores Containment Chamber control-plane state. It is separate from validator key storage and anti-slashing storage, even when all three use DynamoDB.

Use this page when enabling DynamoDB-backed keys, runtime auth policies and tokens, operator quorum seal/unseal, Nitro auto-unseal, or multiple signer replicas.

Deployment shapeState backend required?Why
Filesystem-only signer with static authNoKeys and auth policy are loaded from local config at boot.
Runtime auth policies and tokensYesPolicy and token changes must survive restarts and propagate across replicas.
DynamoDB key sourceYesThe master key and operator ceremony state must survive restarts.
Operator quorum seal/unsealYesOperator registration, encrypted shares, and quorum progress are persisted.
Nitro Enclave auto-unsealYesThe enclave auto-unseal blob and related state are stored here.
Multiple signer replicasYes for stateful featuresReplicas use the backend to converge on seal state, auth changes, and rotation progress.
signer_state:
backend: dynamodb
table: containment-state
refresh_interval_seconds: 1
unseal_timeout_minutes: 30
max_watcher_staleness_seconds: 3

Use a distinct DynamoDB table for signer state. Do not reuse the validator-key table or the anti-slashing table.

DataWhy it exists
Master-key metadataKMS-wrapped Shamir shares and integrity data used during unseal
Operator quorum configOperator names, threshold, and rotation staging
Operator credentialsEncrypted per-operator shares for passphrase or YubiKey unseal
Auth policies and tokensRuntime access-control data
TEE auto-unseal blobNitro Enclave auto-unseal state
StorageHoldsUsed by
Key sourceValidator private keys or encrypted key materialSigning and key-management operations
Signer state backendSeal state, operator credentials, runtime auth records, and replica coordination stateChamber control-plane operations
Anti-slashing backendSlashing-protection historyEthereum signing safety checks

The signer state backend does not store validator private keys. Those live in the configured key source. It does not store slashing-protection records. Those live in the anti-slashing backend.

Every replica polls the state backend on signer_state.refresh_interval_seconds. That polling lets a fresh process observe:

  • An initialization completed by another replica.
  • KMS or TEE auto-unseal state.
  • Auth policy and token changes.
  • Quorum rotation progress.

Set the refresh interval low enough for operational changes to propagate at an acceptable speed. Avoid setting it to 0 in production unless you intentionally want to disable cross-replica refresh behavior.

signer_state.max_watcher_staleness_seconds (default 3) is a separate guard. If a replica’s watcher snapshot grows older than this bound — because the watcher stalls on a DynamoDB outage or a panic-recovery loop — the signing handler starts refusing requests with 503 rather than signing against possibly-stale seal state. refresh_interval_seconds sets how fast a replica observes a cluster-wide seal; max_watcher_staleness_seconds sets how fast signing fails if the watcher itself stops advancing. Set it to 0 to disable the freshness check.

SymptomCheck
Signer starts as uninitialized unexpectedlyThe signer may be pointed at the wrong state table.
Auth edits do not propagateCheck refresh_interval_seconds and DynamoDB read permissions.
Unseal never reaches thresholdConfirm every operator credential row exists and belongs to the expected state table.
TEE auto-unseal never worksConfirm the TEE auto-unseal blob exists and that Nitro measurements still match.