Introspector Enclave is a CLI framework and runtime SDK for deploying applications inside AWS Nitro Enclaves with hardware-backed secret management, cryptographic attestation, and reproducible builds. It enables any Go HTTP server to run inside a Nitro Enclave with zero enclave-specific application code — the framework handles all infrastructure concerns (secret lifecycle, attestation, TLS, networking, upgrades).
The framework provides an irreversible security guarantee: once a KMS key is locked, only an enclave with the exact same binary measurements (PCR0) can decrypt its secrets — not even the AWS root account can override this.
Internet (HTTPS :443)
│
┌─────────────────────────────▼────────────────────────────────┐
│ AWS EC2 Instance (Host) │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ gvproxy │ │ IMDS vsock │ │ enclave-watchdog.svc │ │
│ │ (Docker) │ │ proxy :8002 │ │ (manages EIF) │ │
│ └────┬─────┘ └──────┬───────┘ └────────────────────────┘ │
│ │ vsock:1024 │ vsock:3:8002 │
└───────┼────────────────┼────────────────────────────────────┘
│ │
┌───────▼────────────────▼────────────────────────────────────┐
│ AWS Nitro Enclave (Isolated VM) │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ nitriding (TLS terminator + attestation) │ │
│ │ :443 external → :7073 internal │ │
│ └──────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────┐ │
│ │ enclave-supervisor (SDK runtime) │ │
│ │ • Secret loading (KMS + attestation) │ │
│ │ • Response signing (Schnorr BIP-340) │ │
│ │ • PCR management │ │
│ │ • Management API (/v1/*) │ │
│ │ • Reverse proxy → user app │ │
│ └──────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────┐ │
│ │ User Application (plain HTTP server :7074) │ │
│ │ • No enclave-specific code needed │ │
│ │ • Secrets available as env vars │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌────────────┐ │
│ │ viproxy │ → IMDS credentials via vsock │
│ └────────────┘ │
└──────────────────────────────────────────────────────────────┘
enclave init → enclave setup → enclave build → enclave deploy → enclave verify
→ enclave status
→ enclave lock
→ enclave destroy
Generates the enclave/ directory with all framework files needed to build and deploy:
| File | Purpose |
|---|---|
enclave.yaml |
Configuration (secrets, app source, region, etc.) |
start.sh |
Enclave boot sequence |
gvproxy/Dockerfile |
Outbound networking proxy |
gvproxy/start.sh |
gvproxy startup |
scripts/enclave_init.sh |
Host-side enclave launcher |
systemd/enclave-watchdog.service |
Enclave lifecycle management |
systemd/enclave-imds-proxy.service |
AWS credential forwarding |
systemd/gvproxy.service |
Network proxy service |
user_data/user_data |
EC2 cloud-init script |
On subsequent runs, validates the configuration and reports errors.
Detects the GitHub remote, computes Nix source and vendor hashes for the user's app, and writes them to enclave.yaml.
Builds the Enclave Image File (EIF) using Nix inside Docker for full reproducibility:
- Generates
build-config.jsonfromenclave.yaml - Runs
nix build .#eif(fetches user app + SDK from GitHub, pins all dependencies) - Outputs
enclave/artifacts/image.eif+enclave/artifacts/pcr.json(PCR0/1/2 measurements)
Anyone can rebuild the same EIF and get identical PCR values, proving the binary hasn't been tampered with.
Handles both fresh deployments and upgrades:
Fresh deploy:
- Synthesizes and deploys a CDK stack (VPC, EC2, KMS, SSM, IAM, EIP)
- Applies KMS key policy with PCR0 attestation condition
- Waits for instance readiness
Upgrade (unlocked KMS):
- Calls old enclave's
/v1/prepare-upgradeto record PCR0 attestation - Updates KMS policy with new PCR0
- Hot-swaps the EIF on the running instance
Upgrade (locked KMS — irreversible key):
- Creates temporary KMS key bound to new PCR0
- Old enclave re-encrypts all secrets with temporary key via
/v1/export-key - New enclave boots with migrated secrets
- Old KMS key scheduled for deletion
Three independent verification checks:
- NSM attestation — Fetches hardware-signed attestation document, validates nonce and PCR0
- Attestation key binding — Verifies the supervisor's signing key is registered in the attestation document (SHA256 of pubkey in UserData)
- PCR0 chain — Verifies the upgrade history (each enclave records its predecessor's PCR0 + attestation)
Shows instance state, KMS key state, lock status, and enclave version.
Removes kms:PutKeyPolicy and kms:ScheduleKeyDeletion from the admin, making the KMS policy permanent and irrevocable. After locking, only an enclave with the correct PCR0 can decrypt secrets — even the AWS root account cannot override this.
Destroys all AWS infrastructure via cdk destroy.
┌─ First Boot ─────────────────────────────────────┐
│ 1. Generate 32 cryptographically random bytes │
│ 2. Encrypt with KMS (RSA-OAEP via attestation) │
│ 3. Store ciphertext in AWS SSM Parameter Store │
│ 4. Extend PCR16+i with SHA256(secret_pubkey) │
└────────────────────────────────────────────────────┘
┌─ Subsequent Boots ───────────────────────────────┐
│ 1. Read ciphertext from SSM │
│ 2. Generate ephemeral 2048-bit RSA keypair (NSM) │
│ 3. Request NSM attestation document │
│ 4. KMS.Decrypt() with attestation + RSA pubkey │
│ 5. KMS validates PCR0 → wraps plaintext to RSA │
│ 6. Decrypt locally with ephemeral RSA key │
│ 7. Set as environment variable (hex-encoded) │
└────────────────────────────────────────────────────┘
- Secrets never leave the enclave in plaintext — KMS wraps the response to a one-time RSA key generated inside the enclave's NSM hardware
- PCR0-gated decryption — KMS policy condition
kms:RecipientAttestation:PCR0ensures only the correct enclave binary can decrypt - Configurable secret list — Defined in
enclave.yaml, each with anameandenv_var - SSM path convention:
/{deployment}/{appName}/{secretName}/Ciphertext
| Layer | What It Proves | Mechanism |
|---|---|---|
| NSM Hardware Attestation | Enclave binary identity (PCR0) | AWS Nitro hardware signs CBOR COSE_Sign1 document |
| Attestation Key Binding | Response authenticity | Ephemeral secp256k1 key hash embedded in NSM attestation UserData |
| Response Signing | Per-request integrity | BIP-340 Schnorr signature on every HTTP response |
| PCR | Content |
|---|---|
| PCR0 | Enclave image measurements (firmware, kernel, rootfs) |
| PCR1 | CPU microcode |
| PCR2 | Kernel parameters |
| PCR16 | SHA256(secret_0_pubkey) |
| PCR17 | SHA256(secret_1_pubkey) |
| ... | Additional secrets |
| PCR16-31 | User-extensible via POST /v1/extend-pcr |
Each enclave records its predecessor's PCR0 and the hardware-signed attestation proving it. This creates an immutable chain from genesis to the current version, verifiable by any external party via enclave verify.
The supervisor is the main process inside the enclave. It:
- Boots non-blocking — HTTP server starts immediately (health checks available)
- Loads secrets — Retries KMS decryption until all secrets are available
- Generates attestation key — Ephemeral secp256k1, registered with nitriding
- Extends PCRs — Commits secret public keys to user PCR registers
- Spawns user app — Runs the user's binary as a child process with secrets as env vars
- Reverse proxies — Routes all non-management traffic to the user app
- Signs responses — Schnorr BIP-340 signature on every response
- Handles upgrades —
/v1/export-keyand/v1/prepare-upgradeendpoints
| Endpoint | Method | Purpose |
|---|---|---|
/v1/enclave-info |
GET | Version, PCR0 history, attestation pubkey, init status |
/v1/extend-pcr |
POST | Extend user PCR (16-31) with custom data |
/v1/lock-pcr |
POST | Lock a user PCR against further extension |
/v1/export-key |
POST | Re-encrypt secrets for migration (upgrade) |
/v1/prepare-upgrade |
POST | Store PCR0 + attestation for upgrade chain |
/health |
GET | Readiness probe (200 ready, 503 initializing) |
Deployed via Go CDK (cdk.go):
| Resource | Purpose |
|---|---|
| VPC | Public + private subnets, NAT gateway |
| EC2 Instance | Nitro Enclave-enabled, configurable instance type |
| Elastic IP | Static public address surviving reboots |
| KMS Key | Attestation-gated encryption, auto-rotation |
| SSM Parameters | Secret ciphertext storage + migration state |
| IAM Role | Instance profile with SSM, KMS, ECR, S3 access |
| VPC Endpoints | KMS, SSM, ECR (private connectivity) |
| Security Group | HTTPS ingress, all egress |
| ECR Image | gvproxy Docker image for outbound networking |
The Nix flake (flake.nix) pins every dependency:
| Component | Source |
|---|---|
| User app | Fetched from GitHub at pinned commit + Nix hash |
| enclave-supervisor | Fetched from GitHub at pinned SDK rev + hash |
| nitriding | Brave's TLS terminator at pinned commit |
| viproxy | Brave's vsock proxy at pinned version |
| Base image | busybox + CA certificates |
The EIF is built deterministically — same inputs always produce the same PCR0/1/2 values. This enables third-party verification: anyone can run enclave build and confirm the deployed enclave matches the source code.
SDK coordinates (rev, source hash, vendor hash) are:
- Computed via
make sdk-hashes REV=<tag>and stored insdk-hashes.json - Injected into the CLI binary at build time via Go ldflags
- Automatically populated into
enclave.yamlduringenclave init - Verified by CI on every tagged release
| Property | How It's Achieved |
|---|---|
| Secret confidentiality | KMS decryption gated by hardware-attested PCR0 |
| Binary integrity | Reproducible Nix builds → verifiable PCR0 |
| Response authenticity | BIP-340 Schnorr signature on every HTTP response |
| Upgrade auditability | PCR0 chain with hardware-signed attestation documents |
| Irreversible lockdown | KMS policy removes admin's own PutKeyPolicy permission |
| No operator access | Enclave memory is inaccessible from host, even to root |
| Network isolation | Enclave has no direct network — vsock only |
A developer using this framework:
- Writes a standard Go HTTP server (no enclave code)
- Runs
enclave initto scaffold the project - Configures secrets and app source in
enclave.yaml - Runs
enclave build→enclave deploy→enclave verify - Their app runs inside a Nitro Enclave with hardware-attested secrets, signed responses, and an immutable upgrade chain
The framework abstracts away all Nitro Enclave complexity — NSM sessions, vsock networking, attestation documents, KMS recipient attestation, PCR management, and upgrade key migration.