capy deploy generates a double-wrapped deploy token - one half ships to your platform, the other is derived by the Capy service on demand, and the service never sees your project key. At build or boot time your app presents the service-wrapped half, gets the derived half back, and reconstructs the decrypt key in memory.
The flow
capy in the project first - capy deploy needs a keep.lock and at least one secret in .env. The command is disabled in local-only mode.
- Capy asks in the terminal where the project deploys, and remembers your answer in
.capy/deploy.jsonas next time’s default. - The CLI generates a fresh deploy token, wraps your project key with it, and has the Capy service outer-wrap the result.
- It serves a temporary setup page on
127.0.0.1and opens it in your browser. - That page carries the platform’s setup instructions plus the exact environment variables -
SECRETS_BLOBandPROJECT_KEY- to paste into your platform’s secret store. Press Ctrl+C to close it, or leave it and it shuts down after five minutes. If the page can’t be served, Capy prints both values in the terminal instead.
capy run decrypts them at build or boot time.
Four platforms - Cloudflare Workers, Cloudflare Pages, Vercel, and AWS SSM Parameter Store - are marked (connector available) in the picker. Picking one adds a second prompt, defaulting to the connector: let Capy push the secrets into the platform for you, or fall back to the deploy-token path above. See capy deploy for what each connector does.
What gets injected
Two env vars on your platform:SECRETS_BLOB- base64 of the deploy ID, an outer blob only the Capy service can unwrap, and the encrypted env map. Self-contained.PROJECT_KEY- hex-encoded 32-byte project key. It never traverses the wire to the Capy service.
capy run detects both vars, sends the outer blob to the Capy service (the service verifies the deploy token isn’t revoked and returns a derived service key), combines it with PROJECT_KEY locally to reconstruct the decrypt key, and decrypts the env map in process memory. See Cryptography → Deploying for the exact construction.
Two deployment patterns
The split is dictated by whether you control the process entrypoint. Platforms that invoke your handler directly (serverless, Edge) don’t let you wrap with
capy run at request time, so you decrypt at build and inline the results.
Revocation
Every mint has a deploy id. List this project’s tokens, then revoke one:capy deploy list prints each token’s id prefix, its active or revoked status, and the date it was created; pass that id prefix to capy deploy revoke.
Revocation is server-side, so a revoked token stops bootstrapping new builds or cold starts immediately - capy run can no longer fetch the service key it needs. Any process that already decrypted keeps serving traffic until it recycles: capy run resolves the key once at startup, hands the plaintext values to its child process, and nothing re-checks revocation after that.
Practical timing:
- Long-running servers - revocation propagates on next deploy or restart.
- Containers (Fly, Kubernetes, Docker) - propagates on the next image build or pod cycle.
- Edge / serverless isolates - propagates as isolates recycle (seconds to minutes under load, longer when idle).
capy rotate covers the credentials you set up with capy connect - then mint a new deploy token.
Platform walkthroughs
Vercel
Next.js + Vercel with build-time env inlining.
Cloudflare Pages / Workers
Framework build on Pages, Workers via build-time inline.
Docker
capy run as the container entrypoint.VPS / droplet
Deploy tokens and
capy run on a box you manage yourself.Fly.io
Machines +
flyctl secrets set.Railway / Render / Heroku
Long-running hosts with
capy run in the start command.GitHub Actions
Wrap build steps with
capy run in CI.AWS Lambda
Container-image Lambdas and zip-deploy patterns.
What’s next
capy deploy (CLI reference)
Command flags and flow details.
Cryptography
The deploy token double-wrap in full.