Skip to content

Threat & Risk Model

Adversaries, trust boundaries, exactly what a compromised parent can and cannot do, and the residual risks you must mitigate

This page is the detailed threat and risk model. It defines the adversaries, draws the trust boundaries precisely, enumerates exactly what a compromised parent host can and cannot do in Nitro Enclave mode, and lists the residual risks you are responsible for mitigating.

For the higher-level summary of what is protected, read Security Model first. For component layout, see Architecture Overview.

Asset Why it matters At-rest protection
Validator BLS private keys Signing them is irreversible; misuse causes slashing AES-256-GCM under the master key (DynamoDB), or keystore passwords (filesystem)
Master key Decrypts every DynamoDB-stored validator key; derives the auth-token HMAC subkey Born in the enclave; never persisted in plaintext; Shamir shares are KMS-wrapped (attested Decrypt) and stored in the MASTER_KEY DynamoDB row, integrity-protected by a commitment hash and a share-binding HMAC
Auth tokens Authorize signing and management State-backed tokens are persisted only as HMAC-SHA256 hashes; stateless static_auth secrets are config-provided and hashed in memory at boot
Anti-slashing history A regression re-enables a slashable double-sign Monotonic high-water marks + per-record HMAC, strongly-consistent backend
Attestation / measurements The root of trust that a request reaches the genuine enclave NSM-signed; bound into the RA-TLS certificate

The trust boundary depends entirely on deployment mode.

Boundary Standard mode Nitro Enclave mode
Host / EC2 parent / pod Inside the boundary — trusted with plaintext keys Outside the boundary — untrusted
Decrypted keys & master key In host process memory Only inside enclave memory
AWS KMS Trusted to enforce key policy Trusted to enforce key policy and attestation conditions
Anti-slashing backend Trusted to preserve signing history Trusted to preserve signing history
Validator clients Authenticated, but fork choice not provable Authenticated, but fork choice not provable

In standard mode, a host-root attacker reads process memory or replaces the binary — there is no enclave boundary. Use host hardening and least privilege; choose Nitro mode when the host must not be trusted with plaintext key material.

The rest of this page focuses on Nitro Enclave mode, where the parent is explicitly the adversary and the question “what can it actually do?” has a precise answer.

In Nitro mode the parent EC2 instance / Kubernetes pod is the host the enclave depends on for everything external. It is the enclave’s only credential source, its only network path, and its config source. That gives it real power — and hard limits.

What the parent is (and therefore controls)

Section titled “What the parent is (and therefore controls)”
  • The enclave’s only credential source. AWS credentials are fetched from a parent-side bridge over vsock; the enclave has no other credential path. The parent chooses, and can substitute, the IAM principal the enclave uses for both KMS and DynamoDB.
  • The network path for every AWS call (vsock egress). It can drop or delay traffic and chooses which endpoints are reachable.
  • The config source (region, table, ports, telemetry, egress endpoints), streamed over vsock.
  • Full read/write/delete on DynamoDB, because it holds the role’s credentials.
  • KMS calls under that role — but operations gated by kms:RecipientAttestation are denied (it cannot produce the enclave’s attestation document).
  • Forge attestation for a tampered image. Measurements are signed by the Nitro hardware root.
  • Decrypt KMS-wrapped key material. When the key policy requires kms:RecipientAttestation, Decrypt/GenerateDataKey release plaintext only to the attested enclave — never to the parent.
  • Reverse HMAC-hashed auth tokens.
  • Extract the real master key or real validator keys. The confidentiality of existing key material holds even against a fully compromised parent, because plaintext is never returned outside the enclave.
  • Forge TLS responses from real AWS endpoints — it can relay or drop bytes, but end-to-end TLS to KMS and DynamoDB is preserved.

Its weapons are denial, destruction, and substitution — never silent theft of existing keys.

  • Denial of service. Drop traffic, withhold credentials, kill the enclave, stream bad config → the chamber fails closed and stops signing.
  • Metadata disclosure. Read every DynamoDB row — but the envelope means it learns only metadata (key counts, generation), never plaintext secrets.
  • Destruction. Delete the master-key row or the table → every envelope-encrypted validator key becomes permanently unrecoverable.
  • Substitution. Overwrite state rows. How far that substitution reaches is bounded by the integrity layer described below.

The static ceremony and its integrity layer

Section titled “The static ceremony and its integrity layer”

Containment Chamber uses a single custody model — kms_auto-static — in which the master key’s Shamir shares are KMS-wrapped and stored in DynamoDB. There are no operators, no passphrases, and no human in the unseal loop. The trust anchors that bound what a DynamoDB-write attacker can achieve are three independent checks:

The custody KMS key set is compiled into the binary (Nitro: measured in PCR0) or supplied via the trusted ceremony: config block — a surface the parent cannot rewrite at runtime. Before any KMS decryption the enclave checks that every share ARN in the MASTER_KEY row appears in that allowlist. A state-table-write attacker who repoints share ARNs at a key they control is rejected before any KMS work begins, because their key is not in the allowlist.

The MASTER_KEY row stores a hash of the master key itself (master_key_hash). After Shamir reconstruction the enclave verifies the reconstructed plaintext against this commitment before installing the key. A planted row whose shares decode to an attacker-chosen plaintext cannot pass this check unless the attacker can forge the commitment — which requires knowing the real master key.

The MASTER_KEY row stores a master-key-keyed HMAC over every share’s share_id and each wrap’s (kms_key_arn, blob). A DynamoDB-write parent that renumbers shares or splices shares from different rows fails this HMAC check on the next boot, because recomputing the correct tag requires the live master key.

Net effect by chamber state:

  • Populated chamber (validator keys already loaded): loud, no takeover. Each validator-key row carries a master-key-derived integrity HMAC. A planted or tampered master key fails the commitment check; a renumbered or spliced share set fails the share-binding HMAC; in either case the enclave refuses to boot with an explicit tamper error. Existing keys are stranded (never stolen), and the enclave stays down — a detectable outage, not a silent compromise.
  • Fresh chamber (no keys yet): bounded risk. A parent that rewrites the MASTER_KEY row but cannot get a non-ceremony key past the ARN gate gains nothing. A parent whose IAM role holds kms:Encrypt without the kms:RecipientAttestation condition on a custody key could in principle fabricate a row — this is the residual risk that attestation conditions on every custody key eliminate.

The signer has exactly two states:

direction: right
unsealed: Unsealed {
style.fill: "#16a34a"
style.font-color: "#ffffff"
}
sealed: Sealed (break-glass) {
style.fill: "#dc2626"
style.font-color: "#ffffff"
}
unsealed -> sealed: SEAL_OVERRIDE latch\nobserved by watcher
  • Boot → Unsealed: automatic — auto-init on a fresh table, KMS auto-unseal from the existing MASTER_KEY row. No human interaction required.
  • Unsealed → Sealed: the break-glass SEAL_OVERRIDE row is written by containment-chamber operator seal or observed by the background watcher on any running replica. The latch is keyed by a master-key subkey HMAC so peers can verify it is genuine.
  • There is no Sealed → Unsealed transition. Recovery from Sealed requires a manual IAM delete-item on the SEAL_OVERRIDE row (PK SEAL_OVERRIDE) followed by a restart of every replica.

The parent role should be IAM-denied PutItem and DeleteItem on the SEAL_OVERRIDE row as a first-line guard. If a forged latch is written despite that (e.g. via a misconfigured role or an IAM escalation), the watcher verifies the row’s HMAC against the live master-key subkey. A mismatch does not seal the replica — instead the watcher fails the freshness tick, which causes the signing endpoint to 503 until the row is removed. This separates a genuine operator seal (valid HMAC) from a DynamoDB-write tamper attempt (HMAC mismatch), preventing the parent from causing an unrecoverable fleet-wide stop with a garbage row.

Why DynamoDB access is not the trust boundary

Section titled “Why DynamoDB access is not the trust boundary”

It is tempting to assume that locking down DynamoDB protects key custody. It does not, because the parent already holds the credentials the enclave uses. Custody confidentiality is anchored in the crypto envelope, not in database access control:

  • KMS attestation is asymmetric. kms:RecipientAttestation gates only operations that deliver a secret to the enclaveDecrypt, DeriveSharedSecret, GenerateDataKey/GenerateDataKeyPair, GenerateRandom. Encrypt has no recipient parameter because its output is not secret, so it cannot be attestation-gated. KMS is the only AWS service whose authorization can require the attestation document; DynamoDB authorization is pure IAM, which the parent holds.
  • Therefore confidentiality of stored keys rests on attested Decrypt of KMS-wrapped shares — never on who can read or write the DynamoDB table.
  • Integrity of stored rows is anchored by the master-key commitment hash and the share-binding HMAC: a writer without the master key cannot forge a row the enclave will accept, which turns parent row-tampering into a detectable boot failure rather than a silent compromise.

The anti-slashing backend is trusted to preserve an accurate, monotonic signing history. Two deployment constraints make that trust sound:

  • Single-region / strongly-consistent. The DynamoDB anti-slashing backend uses strongly-consistent reads and conditional, monotonic TransactWriteItems (a new block must advance max_slot; an attestation must advance target_epoch while never decreasing source_epoch). Those guarantees hold only within a single region. Do not replicate the anti-slashing table with DynamoDB Global Tables: a stale local read in a second region can pass the monotonic guard and let two regions sign conflicting messages for one slot — a direct path to slashing. Keep it single-region (or single-writer).
  • Never restore it backwards. Point-in-time recovery is the right safety net for key state, but a point-in-time restore of the anti-slashing table regresses the high-water marks and re-enables an already-made double-sign. Recover slashing protection by importing the latest EIP-3076 interchange (never below the prior high-water mark) — never by a naive backup restore.
  • Losing the key state loses the keys. In DynamoDB mode the master key is recoverable only from the MASTER_KEY row (KMS-wrapped Shamir shares). Protect that table with point-in-time recovery and backups, restricted write access, and no destructive TTL/lifecycle rules on key rows.
  • Single-region is a deliberate availability trade. A regional DynamoDB outage stops signing because anti-slashing and key state cannot be confirmed. Failing closed (no signing) is the correct behavior for a slashing-protection system; DynamoDB is multi-AZ within a region, so intra-region availability remains high. Co-locate the enclave, both DynamoDB tables, and KMS keys in one region so the per-signature anti-slashing round-trip never crosses a region.
Risk Affected mode / component Outcome if unmitigated Your mitigation
Compromised standard-mode host Standard mode Plaintext key + memory access Host hardening; use Nitro mode for untrusted hosts
Custody KMS key(s) compromised at or above threshold DynamoDB key custody Master key reconstructable Spread shares across accounts/regions; set kms_threshold > 1; least-privilege key policies
Missing kms:RecipientAttestation on a custody key policy Nitro KMS Parent can decrypt shares directly; fresh-chamber silent takeover possible Enforce attestation conditions on every custody key (see RA-TLS)
Parent rewrites MASTER_KEY share ARNs to an attacker-controlled key DynamoDB key custody Rejected by ARN allowlist; if kms:RecipientAttestation also missing, silent takeover on fresh bring-up Enforce kms:RecipientAttestation on all custody keys
Forged SEAL_OVERRIDE latch written by a DDB-write parent All / break-glass path HMAC mismatch → watcher fails freshness tick (503s signing), does not seal IAM-deny PutItem/DeleteItem on SEAL_OVERRIDE PK for the parent role
Anti-slashing history tampered or restored backwards Anti-slashing Slashable double-sign approved Single-region, restricted write, EIP-3076 recovery only
DynamoDB key table lost DynamoDB key custody Permanent key loss PITR + backups + restricted delete
Malicious validator client Signing path Requests for unsafe messages Scope/key/operation/CIDR auth policies; anti-slashing still rejects slashable requests