FIDUCY

Self-hosting

Self-hosting is free. You pay AWS for one Graviton instance with enclaves (about $50 a month for c6g.large) and a KMS key ($1 a month).

What gets created

infra/aws/stack.yaml is one CloudFormation stack:

  • an S3 bucket for releases and logs
  • a KMS key whose policy only allows kms:Decrypt from the enclave image you built
  • a c6g.large instance with Nitro enclaves on, an Elastic IP, and ports 80 and 443 open
  • a DynamoDB table (KeysTable) for sealed key records, on demand billing, with deletion protection and point-in-time recovery
  • an IAM role limited to the bucket, the key and the table

The host runs Postgres, the dashboard, the demo and Caddy for TLS. The gateway runs in the enclave and reads and writes sealed records in KeysTable directly.

The landing page and these docs are not part of the stack. They deploy to Vercel from apps/site.

Deploy with GitHub Actions

  1. Create an IAM user with admin rights for the first deploy.
  2. Add repository secrets: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and optionally AWS_REGION (default us-east-1).
  3. Run the AWS deploy workflow.

The workflow builds the enclave on the host, reads its PCR0, locks the KMS key to it, starts everything, and checks the endpoints. The run summary lists your URLs:

Gateway (in the enclave): https://gw.<your-ip>.sslip.io
Dashboard:                https://app.<your-ip>.sslip.io
Demo chat:                https://demo.<your-ip>.sslip.io

Deploy from your machine

export AWS_REGION=us-east-1
bash infra/aws/deploy.sh

Needs the AWS CLI, jq and admin credentials.

Tear down

Run the AWS teardown workflow, or bash infra/aws/teardown.sh. The KMS key enters a 7 day deletion window; every key it wrapped becomes unrecoverable after that.

Run locally

No AWS needed. A local master key stands in for KMS:

bun install
bun run prototype --mock

This starts the dashboard on :3000, the demo chat on :3001 and the gateway on :8787. --mock uses a fake OpenAI that logs the last four characters of the key it received, so you can see decryption happen.

Gateway environment

VariablePurpose
FIDUCY_KMS_KEY_IDKMS key ARN. When unset, FIDUCY_MASTER_KEY is used instead (local only)
FIDUCY_MASTER_KEY32 random bytes, base64url. Local development only
AWS_KMS_ENDPOINTKMS proxy inside the enclave. Default http://127.0.0.1:9999
FIDUCY_CONTROL_PLANE_URLDashboard URL for app configs, usage and key events
FIDUCY_KEYS_TABLEDynamoDB table for sealed key records. When unset, records stay in memory (local only)
AWS_REGIONRegion for KMS and DynamoDB. Default us-east-1
FIDUCY_GATEWAY_TOKEN_CIPHERTEXTControl plane token, KMS-encrypted
FIDUCY_ENCLAVE_API_URLEnclaver API, for /attestation
FIDUCY_APPS_JSONStatic app list when there is no control plane
PORTDefault 8787