Skip to content

Seal & Unseal Operations Guide

This runbook covers the commands operators use to initialize, unseal, seal, and rotate a DynamoDB-backed chamber. For the design model, see Seal & Unseal. For request and response schemas, use the API Reference.

The seal/unseal flow only applies when using the DynamoDB key source.

Before running a ceremony, confirm:

  • containment-chamber is installed on the operator machine.
  • The signer is reachable with --signer-url.
  • The DynamoDB key-source table and signer-state table exist.
  • The signer’s IAM role can use the configured KMS keys and DynamoDB tables.
  • You have the setup, registration, or auth token required by the command.

Use env:VAR_NAME for sensitive flags so secrets do not appear in process listings:

Terminal window
export CC_AUTH_TOKEN="cc_token_..."
containment-chamber operator status \
--auth-token "env:CC_AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Start the signer:

Terminal window
containment-chamber server --config config.yaml

While uninitialized, the signer logs a one-time setup token. Save it from the logs:

WARN Setup token generated (save securely, one-time use) setup_token=cc-setup-...

Use this when restarts should be fully automated.

Terminal window
containment-chamber operator init \
--setup-token "$SETUP_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--kms-key-arns "arn:aws:kms:us-east-1:111111111111:key/aaa...,arn:aws:kms:eu-west-1:222222222222:key/bbb...,arn:aws:kms:ap-southeast-1:333333333333:key/ccc..." \
--kms-threshold 2

The signer transitions directly to unsealed. On later restarts, it reconstructs the master key automatically when enough KMS keys are reachable.

Use this when operators must approve unseal.

Terminal window
containment-chamber operator init \
--setup-token "$SETUP_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--kms-key-arns "arn:aws:kms:us-east-1:111111111111:key/aaa...,arn:aws:kms:eu-west-1:222222222222:key/bbb..." \
--kms-threshold 2 \
--quorum-threshold 2 \
--operators "alice,bob,carol"

The response includes one registration token per operator. Send each operator only their own token, over a secure channel.

Each operator registers:

Terminal window
containment-chamber operator register \
alice \
--registration-token "$ALICE_TOKEN" \
--credential-id password-1 \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

After all operators register, the chamber becomes sealed. Continue with the unseal ceremony.

In operator quorum mode, KMS unseal happens first and the signer moves to kms_unsealed. Signing is still disabled until enough operators submit passphrases.

Check status:

Terminal window
containment-chamber operator status \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Each operator submits their passphrase:

Terminal window
containment-chamber operator unseal \
alice \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Operators can submit in any order. Once the threshold is reached, the signer returns to unsealed and signing resumes.

To clear accumulated shares and restart the ceremony:

Terminal window
containment-chamber operator unseal-reset \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Operators can register more than one credential for the same share. A practical setup is one password credential plus one YubiKey backup.

Terminal window
containment-chamber operator add-credential \
alice \
--existing-credential-id password-1 \
--new-credential-id yubikey-1 \
--yubikey \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

The chamber rejects removal of an operator’s last credential.

Seal immediately to stop new signing requests:

Terminal window
containment-chamber operator seal \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

The master key is zeroized from memory and new signing requests return 503. To resume, restart the signer and complete the normal unseal path for your mode.

Rotation commands require an auth token with the relevant chamber-management scope. Signing continues during rotation.

Terminal window
containment-chamber operator rotate kms \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--kms-key-arns "arn:aws:kms:us-east-1:111111111111:key/new-aaa...,arn:aws:kms:eu-west-1:222222222222:key/new-bbb..." \
--kms-threshold 2

Keep the old KMS keys available until you have confirmed the signer can restart with the new set.

Terminal window
containment-chamber operator rotate quorum \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--quorum-threshold 2 \
--operators "dave,eve,frank"

Distribute the returned registration tokens to the new operators. Each new operator runs operator register. When registration completes, the new quorum replaces the old one.

Cancel an in-progress rotation:

Terminal window
containment-chamber operator rotate quorum-cancel \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer
Terminal window
containment-chamber operator rotate mode \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--mode operator-quorum \
--quorum-threshold 2 \
--operators "alice,bob,carol"
Terminal window
containment-chamber operator rotate mode \
--auth-token "$AUTH_TOKEN" \
--signer-url http://localhost:9000 \
--allow-plaintext-signer \
--mode kms-auto

Switching to operator quorum starts a registration phase. Switching to KMS-only takes effect immediately and deletes operator share rows.

Generate a management token through an operator quorum ceremony:

Terminal window
containment-chamber operator generate-root-token \
alice \
--signer-url http://localhost:9000 \
--allow-plaintext-signer

Each required operator runs the same command with their own operator name. The token is returned once when the threshold is reached. Store it in a secrets manager.

In Nitro Enclave mode, the first successful unseal can create a TEE auto-unseal blob. Later restarts can auto-unseal when enclave measurements still match. A binary upgrade changes measurements, so the chamber falls back to this operator ceremony and writes a new blob after success.

For PCR rotation and attestation troubleshooting, see Nitro Enclave Operations.

SymptomAction
Signing returns 503Check operator status; the signer is sealed or waiting for operators.
already initializedUse rotation commands instead of operator init.
Unseal timeout expiredOperators must submit shares again.
KMS decrypt deniedCheck IAM role policy and KMS key policy.
Wrong passphraseClear partial shares with operator unseal-reset, then retry.

For broader diagnostics, see Troubleshooting.

If KMS keys and operator credentials are both lost, the master key is unrecoverable. The recovery path is the age-encrypted mnemonic backup created during key generation, if enabled. See DynamoDB Key Source.