Skip to content

Sidecar Daemon

teton-sidecar runs inside the enclave container. It holds the ephemeral Ed25519 workload key in memory, requests hardware attestation, and exposes a loopback HTTP API to the workload.

Setting Default Rule
Bind 127.0.0.1:8080 Only 127.0.0.1 or ::1. Other addresses fail closed.
DRY_RUN true Build transactions. Submit only when DRY_RUN=false.
Enclave mode mock amd-sev-snp, aws-nitro, gcp-confidential-space, mock
Renewal buffer 5,000 slots Heartbeat re-attests before expires_slot
Poll interval 30 s Slot poll for the heartbeat task
Payer keypair unset Fee payer only. Never the workload signer.
Terminal window
teton-sidecar \
--bind-addr 127.0.0.1:8080 \
--enclave-mode aws-nitro \
--solana-rpc-url https://api.devnet.solana.com

Environment mirrors the flags: TETON_BIND_ADDR, TETON_ENCLAVE_MODE, TETON_SOLANA_RPC_URL, TETON_PAYER_KEYPAIR_PATH, TETON_CONTAINER_IMAGE_DIGEST, DRY_RUN.

Mode amd-sev-snp issues SNP_GET_REPORT on Linux. The accepted report is exactly 1,184 bytes. REPORT_DATA must echo the 64-byte user data (pubkey ‖ slot hash or commitment). A size or echo failure is HardwareUnavailable. The sidecar does not synthesize a production report.

Mode aws-nitro issues NSM_REQUEST_ATTESTATION with user_data = workload_signer.to_bytes() and nonce = slot_hash. Missing device, open failure, ioctl failure, or a non-Linux host returns SidecarError::IoctlError (@spec TETON-NITRO-003). Mock mode is a separate EnclaveMode::Mock path for tests.

Mode gcp-confidential-space fetches an OIDC token. eat_nonce is unpadded base64url. Mode A uses two 43-character strings (pubkey, slot hash). Mode B uses one 43-character commitment. When TETON_CONTAINER_IMAGE_DIGEST is set (sha256: plus 64 hex), a mismatched image_digest fails closed.

Routes:

Method Path Action
GET /v1/status Pubkey, expiry, remaining slots
POST /v1/attest Re-attest the current key
POST /v1/sign Sign a payload with the workload key
POST /v1/renew Rotate the key, zeroize the old secret, attest

Heartbeat calls attest on the current key. POST /v1/renew rotates first.

bins/teton-sidecar/Dockerfile is a two-stage image (@spec TETON-SIDECAR-006):

  1. rust:1.82-slim-bookworm builds teton-sidecar and strips the binary.
  2. gcr.io/distroless/cc-debian12:nonroot copies the binary. User nonroot (uid 65532). ENTRYPOINT binds 127.0.0.1:8080.

From the workspace root:

Terminal window
docker build -f bins/teton-sidecar/Dockerfile -t teton-sidecar:local .

Pin the image digest in TETON_CONTAINER_IMAGE_DIGEST and on the PolicyRegistry measurement allowlist.