Skip to content

API Concepts

API surfaces, authorization flow, scopes, and chamber ceremony behavior

Containment Chamber exposes six logical API surfaces on a single HTTP server. Understanding how they relate — and how a request moves from the network boundary to a signature — makes the configuration and auth model easier to reason about.

SurfaceRoute PrefixPurpose
Signing/api/v1/eth2/*Web3Signer-compatible BLS signing and key discovery
Key Manager/eth/v1/keystoresEIP-3076 hot keystore loading and removal
Chamber Ceremony/api/v1/chamber/init, /api/v1/chamber/unseal, /api/v1/chamber/generate-root-token, /api/v1/chamber/attestationInitialization, operator registration, unseal, root-token generation, and attestation
Chamber Operations/api/v1/chamber/status, /api/v1/chamber/seal, /api/v1/chamber/rotate/*, /api/v1/chamber/modeStatus, emergency seal, mode changes, KMS rotation, and operator quorum rotation
Chamber Keys/api/v1/chamber/keys/*DynamoDB-backed key generation, import, and lifecycle
Auth/api/v1/auth/*Runtime policy and token management
Health/upcheckLiveness probe — no auth required

Metrics are served on a separate port (default 3000) and are not part of the main API surface.

Signing, Key Manager, Chamber Keys, Chamber Operations, and Auth routes participate in policy-based auth evaluation. Chamber Ceremony routes use ceremony-specific credentials instead: setup tokens, registration tokens, operator passphrases, optional ceremony CIDR filtering, and rate limits. The Key Manager API uses the same auth engine as the Chamber APIs, but it is accessed by validator clients that speak the standard EIP-3076 protocol.

Use the API Reference for the exact endpoint list, request schemas, response schemas, and error responses for each surface.

  1. HTTP ingress

    Axum receives the request. Tower middleware applies backpressure (LoadShedLayerConcurrencyLimitLayerTimeoutLayer). If the queue is full, the client receives 503 before any auth or signing logic runs.

  2. Token extraction

    The Authorization header is parsed. Bearer tokens are primary; HTTP Basic is accepted as a compatibility shim (username ignored, password treated as the token). No header → unauthenticated request.

  3. CIDR check

    If the token is CIDR-bound, the source IP is checked against the allowed ranges. Failure returns 403.

  4. Policy evaluation

    The evaluator loads the token’s bound policies and checks each rule against the request:

    • Does the route’s required scope match an allowed scope?
    • Does the requested public key match an allowed key list?
    • Does the requested signing operation match an allowed operation list?

    Matching rules use deny-overrides-allow semantics. Any matching deny rejects the request; otherwise at least one matching allow is required. If no rule matches, the default is deny.

  5. Signing pipeline (signing routes only)

    • Network guard validates fork_info against the configured network. Mismatch → 400.
    • Anti-slashing checks the request against the protection database. Slashable → 412.
    • Key lookup finds the private key. Missing → 404.
    • BLS signing produces the signature and returns it.

Tokens are created at runtime and never stored in plaintext. The server only persists the HMAC-SHA256 hash of the token secret.

The operator CLI is the normal way to manage tokens. If you are integrating directly, the API Reference documents the token-create, lookup, renew, and revoke schemas.

  1. Creation

    A management token holder creates a client token with the operator CLI:

    Terminal window
    containment-chamber operator auth token create \
    --policies validator-client-alpha \
    --ttl-seconds 86400 \
    --token env:ROOT_TOKEN

    Add --token-bound-cidrs 10.0.10.0/24 when the validator client has a stable egress CIDR and the token should fail outside it.

    The server returns the token secret once. Save it immediately — it is never shown again.

  2. Use

    The client sends the token on every request:

    Authorization: Bearer <secret>

    The server hashes the incoming secret and compares it against the stored hash using constant-time comparison.

  3. Expiry

    Tokens with a TTL auto-expire. The server rejects expired tokens with 401. Tokens without a TTL live until explicitly deleted.

  4. Rotation

    To rotate a token, create a new one with the same policies, update your validator clients, then delete the old token. There is no “update secret” operation — rotation is always create-then-delete.

  5. Deletion

    containment-chamber operator auth token revoke --accessor <accessor> removes the token immediately. In-flight requests using the old token may fail mid-stream.

Scopes are coarse-grained capabilities that map to route families. They are not fine-grained HTTP-method permissions — a scope grants access to an entire functional area.

ScopeGrants access to
signAll signing routes (/api/v1/eth2/sign/*)
public_keysKey discovery (/api/v1/eth2/publicKeys)
list_keysEIP-3076 keystore listing (/eth/v1/keystores)
import_keystoresEIP-3076 keystore import (/eth/v1/keystores)
delete_keysEIP-3076 keystore deletion (/eth/v1/keystores)
chamber_statusSeal state and health details
chamber_sealEmergency seal operation
chamber_rotateKMS and operator rotation
chamber_keys_listChamber key inventory
chamber_keys_generateDynamoDB key generation
chamber_keys_importRuntime key import
chamber_keys_patchActivate / deactivate chamber keys
chamber_keys_deleteRemove chamber keys
auth_policies_manageCreate, update, delete policies
auth_tokens_manageCreate, delete, list tokens

Why scopes instead of HTTP methods? Because the API is resource-oriented, not CRUD-oriented. A validator client needs sign and public_keys — it does not care about GET vs POST. Scopes express intent, not mechanics.

For the precise endpoint-to-scope mapping, use the API Reference. This page explains the model; Scalar is the source of truth for path-level details.

The chamber routes are not all governed by normal auth policies. The split matters operationally because some routes are used before a management token exists, while the signer is sealed, or while operators are proving quorum.

Ceremony routes use ceremony-specific credentials:

  • Initialization uses the setup token.
  • Operator registration uses registration tokens.
  • Unseal and root-token generation use operator quorum proof.
  • Attestation is exposed as a ceremony route and can be protected by the ceremony CIDR guard.

Operational chamber routes use normal auth scopes:

  • chamber_status for seal state and operational status.
  • chamber_seal for emergency seal.
  • chamber_rotate for KMS rotation, quorum rotation, and mode changes.

For exact paths, request bodies, and responses, use the API Reference. For operator commands, use the Seal & Unseal Operations Guide. For state-machine details, see Seal & Unseal.

Policies use deny-overrides-allow semantics:

  1. Deny overrides allow — any matching deny rule rejects the request, even if another rule or policy would allow it.
  2. Key restrictions — if a rule lists keys, the request must target one of them.
  3. Operation restrictions — if a rule lists operations, the request must be one of them.
  4. Scope match — the route’s required scope must be in the rule’s allowed scopes.

Example: a policy with two rules

{
"rules": [
{ "effect": "deny", "operations": ["VOLUNTARY_EXIT"] },
{ "effect": "allow", "scopes": ["sign"], "keys": ["0xabc..."] }
]
}

A VOLUNTARY_EXIT request for 0xabc... is denied because the deny rule matches first. An ATTESTATION request for 0xabc... is allowed because the deny rule does not match and the allow rule does.

Anonymous requests are denied unless static_auth.anonymous references named policies that allow them. This keeps the evaluator deny-by-default while still letting stateless deployments grant token-less access from the config file.

Modestatic_auth.anonymousAnonymous request
StatelessNot configured401
StatelessConfiguredChecked against the referenced named policies
State-backedNot configured401
State-backedstatic_auth setInvalid config; startup rejects it

State-backed deployments use runtime policies and tokens from the Auth API. Stateless deployments cannot persist those, so they declare auth in config via static_auth — named policies, an optional anonymous binding, and static tokens.