capsule.yaml
Complete manifest reference — every field that controls how your enclave application is built and run.
Minimal Manifest
version: v1
name: "my-app"
target: "my-app-enclave:latest"
sources:
app: "my-app:latest"
ingress:
- listen_port: 8080
api:
listen_port: 18000
version, name, target, and sources.app are strictly required. Defaults apply for CPU (2), memory (4096 MiB), and other settings.
Complete Reference
version: "v1" # Schema version (required)
name: "your-service" # Friendly name (required)
target: "repo/name:tag" # Release image tag (required)
sources:
app: "repo/app:tag" # Application image (REQUIRED)
capsule-runtime: "..." # Override runtime image (optional)
capsule-shell: "..." # Override shell image (optional)
signature:
certificate: ./path/to/cert.pem # EIF signing certificate
key: ./path/to/key.pem # EIF signing private key
defaults:
cpu_count: 2 # vCPU count (default: 2)
memory_mb: 4096 # Memory in MiB (default: 4096)
ingress: # Host → Enclave TCP listeners
- listen_port: 8080
egress: # Outbound HTTP proxy
proxy_port: 10000
allow:
- "api.example.com"
- "169.254.169.254" # IMDS
- "**.amazonaws.com" # Wildcard subdomains
- "0.0.0.0/0" # All IPv4
deny:
- "*.secret.internal"
api:
listen_port: 18000 # Capsule API port
aux_api:
listen_port: 18001 # Auxiliary API port (default: api + 1)
helios_rpc: # Trustless multi-chain RPC
enabled: true
chains:
- name: "L2-base-sepolia"
network_id: "84532"
kind: "opstack"
network: "base-sepolia"
execution_rpc: "https://sepolia.base.org"
local_rpc_port: 18545
consensus_rpc: "..." # Optional
checkpoint: "0x..." # Optional (ethereum only)
kms_integration: # Nova KMS + app wallet
enabled: true
use_app_wallet: true
kms_app_id: 49
nova_app_registry: "0x0f68..." # Registry contract address
storage:
s3: # S3 persistence
enabled: true
bucket: "my-app-data"
prefix: "apps/my-service/"
region: "us-east-1" # Optional
encryption:
mode: "kms" # plaintext | kms
key_scope: "object" # app | object
aad_mode: "key" # none | key | key+version
key_version: "v1"
accept_plaintext: true
mounts: # Host-backed directories
- name: "appdata"
mount_path: "/mnt/appdata"
required: true
size_mb: 10240
clock_sync: # Wall-clock synchronization
enabled: true # Default: true
interval_secs: 300 # Default: 300
Top-Level Fields
| Field | Required | Description |
|---|---|---|
| version | Yes | Schema version. Currently "v1". |
| name | Yes | Human-readable application name. |
| target | Yes | Docker image tag for the built capsule image. |
sources
| Field | Required | Description |
|---|---|---|
| sources.app | Yes | Docker image for your application. |
| sources.capsule-runtime | No | Override the Capsule Runtime image. Defaults to public ECR. |
| sources.capsule-shell | No | Override the Capsule Shell image. Defaults to public ECR. |
defaults
| Field | Default | Description |
|---|---|---|
| defaults.cpu_count | 2 | Number of vCPUs allocated to the enclave. |
| defaults.memory_mb | 4096 | Memory in MiB allocated to the enclave. |
Priority order
CLI flags (--cpu-count, --memory-mb) override manifest defaults, which override hardcoded defaults.
ingress
List of TCP ports that the enclave listens on. Each port is bridged from the host to the enclave over vsock.
| Field | Required | Description |
|---|---|---|
| listen_port | Yes | TCP port number. Must match a port your app listens on, or the Aux API port. |
egress
Outbound HTTP/HTTPS proxy configuration. The enclave has no direct network — all outbound traffic goes through this proxy.
| Field | Default | Description |
|---|---|---|
| egress.proxy_port | 10000 | Local port for the HTTP proxy inside the enclave. |
| egress.allow | [] | List of allowed destination hosts/IPs. Supports ** for wildcard subdomains, CIDR notation for IPs. |
| egress.deny | [] | List of denied destinations. Deny takes precedence over allow. |
Common allow entries
169.254.169.254 — AWS IMDS (required for S3 credentials)
**.amazonaws.com — AWS services (S3, etc.)
0.0.0.0/0 — All IPv4 addresses (use with caution)
helios_rpc
Helios light client for trustless on-chain reads. Each chain entry runs an independent light client instance.
| Field | Required | Description |
|---|---|---|
| enabled | No | Enable Helios when true. |
| chains[].name | Yes | Human-readable chain name. |
| chains[].network_id | No | Chain ID for reference. |
| chains[].kind | Yes | ethereum or opstack. |
| chains[].network | Yes | Network slug (e.g., mainnet, base-sepolia). |
| chains[].execution_rpc | Yes | Upstream execution RPC URL. |
| chains[].local_rpc_port | Yes | Local port on 127.0.0.1 for this chain. |
| chains[].consensus_rpc | No | Custom consensus RPC URL. |
| chains[].checkpoint | No | Weak subjectivity checkpoint (ethereum only). |
Supported Ethereum Networks
mainnet, sepolia, holesky
Supported OP Stack Networks
op-mainnet, base, base-sepolia, worldchain, zora, unichain
KMS + Helios
When kms_integration uses registry-backed discovery, one Helios chain must use local_rpc_port: 18545. Capsule Runtime waits for :18545 to be ready before starting the Capsule API.
kms_integration
Nova KMS integration for key derivation, key-value storage, and app wallets.
| Field | Default | Description |
|---|---|---|
| enabled | false | Enable Nova KMS integration. |
| use_app_wallet | false | Enable app wallet routes (/v1/app-wallet/*). |
| kms_app_id | — | App ID for registry-backed KMS discovery. |
| nova_app_registry | — | Registry contract address for KMS discovery. |
storage
storage.s3
| Field | Default | Description |
|---|---|---|
| enabled | false | Enable S3 storage API. |
| bucket | — | S3 bucket name. |
| prefix | — | Key prefix for all objects. |
| region | auto | AWS region (auto-detected if omitted). |
| encryption.mode | plaintext | plaintext or kms. |
| encryption.key_scope | app | app (single key) or object (per-object key). |
| encryption.aad_mode | none | none, key, or key+version. |
| encryption.key_version | — | Version tag for key rotation. |
| encryption.accept_plaintext | false | Allow reading unencrypted objects when encryption is on. |
storage.mounts
Host-backed directory mounts. Each mount is a persistent writable directory inside the enclave backed by a loopback ext4 image on the host.
| Field | Default | Description |
|---|---|---|
| name | — | Mount name. Used in --mount name=path CLI binding. |
| mount_path | — | Path inside the enclave (e.g., /mnt/appdata). |
| required | true | If true, startup fails if the mount binding is missing. |
| size_mb | — | Storage quota in MiB. Writes fail with ENOSPC when full. |
Host mounts are NOT trusted
The host controls the backing storage. The host can observe filenames, file sizes, and timing. It can tamper with bytes on disk. Never treat mounted content as trusted code or configuration. Add application-level encryption or integrity checks if needed.
clock_sync
| Field | Default | Description |
|---|---|---|
| enabled | true | Enable wall-clock synchronization with the host. |
| interval_secs | 300 | Seconds between periodic time sync updates. |
Omitting the clock_sync block entirely keeps the default behavior (enabled, 300s interval). Set enabled: false to explicitly disable.
signature
Optional EIF signing for build-time image integrity.
| Field | Required | Description |
|---|---|---|
| certificate | Yes (if signing) | Path to the PEM certificate file. |
| key | Yes (if signing) | Path to the PEM private key file. |