Skip to main content

Synopsis

Description

Sets up secret delivery for the current project. Capy asks in the terminal where the project deploys, then takes one of two paths: a deploy token plus platform-specific docs (works with any platform), or a connector that pushes the secrets for you (available for five platforms). Run 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.

Token and docs

The default path. Capy mints a deploy token, then serves a temporary page on 127.0.0.1 and opens it in your browser. That page carries the setup instructions for the platform you picked, plus two environment variables to copy into your platform’s secret store. It shuts down when you press Ctrl+C, or after five minutes. If the page can’t be served, Capy prints both values in the terminal instead.
  • SECRETS_BLOB - a base64 blob containing the deploy ID, an outer-wrapped key material blob (held by the Capy service), and the encrypted env vars. Self-contained.
  • PROJECT_KEY - a hex-encoded 32-byte key. Never leaves your platform’s env; never traverses the wire to the Capy service.
At build or boot time capy run detects both variables, sends only the outer-wrapped portion of SECRETS_BLOB to the service, receives a derived service key (the service verifies the deploy token isn’t revoked first), combines that with PROJECT_KEY locally to reconstruct the decrypt key, and decrypts the env vars in process memory. The service never learns the project key or the plaintext values.

Platforms

The picker is a terminal list of 31 platforms, and Capy ships setup instructions for each:
  • Managed runtimes: Vercel, Netlify, Cloudflare Pages, Cloudflare Workers, Render, Fly.io, Railway, Heroku, DigitalOcean App Platform, Google Cloud Run, Azure App Service, AWS App Runner.
  • Containers and orchestration: Docker, Docker Compose, Kubernetes, Helm, Nomad, AWS ECS.
  • CI/CD: GitHub Actions, GitLab CI, CircleCI, Jenkins.
  • Infrastructure tooling and self-hosted: Terraform, Pulumi, AWS CDK, Kamal, Dokku, CapRover, Coolify, systemd.
Pick your platform in the terminal; Other… sits at the top of the list for anything not covered. --platform <id> skips the picker - ids are the lowercase, hyphenated forms of the names, with a few shortened (e.g. fly for Fly.io, digitalocean for DigitalOcean App Platform). Capy remembers the platform you picked in .capy/config and offers it as the default next time.

Connector mode

Five platforms are marked (connector available) in the picker: Cloudflare Workers, Cloudflare Pages, Vercel, AWS ECS, and GitHub Actions. Picking one adds a second prompt - run the connector, or fall back to the token and docs path. Outside GitHub Actions, a connector deploy decrypts the current branch on your machine and pushes the plaintext values to the target platform. Cloudflare Workers uses wrangler secret bulk to write to the platform’s secret store; Cloudflare Pages instead inlines the selected build-time vars into a build Capy runs locally and uploads it via wrangler pages deploy — nothing is written into a Cloudflare store. Vercel uses the vercel CLI (vercel env add), and AWS ECS writes SSM SecureString parameters. In all cases, SECRETS_BLOB and PROJECT_KEY are not involved. Capy then either ships the code directly or commits keep.lock on a branch and opens a PR your CI deploys on merge, depending on how the target is configured. Capy saves each connector target to .capy/deploy.json. capy deploy <target> redeploys a saved target by name, capy deploy targets lists them, and capy deploy targets-remove <name> deletes one.

GitHub Actions connector

GitHub Actions has a built-in connector that pushes SECRETS_BLOB and PROJECT_KEY straight into your repo’s Actions secret store over the gh CLI - no copy-paste. gh must already be installed and authenticated (gh auth login). Pick GitHub Actions, then Push SECRETS_BLOB + PROJECT_KEY to GitHub secrets via gh, and choose repository or environment scope. When it finishes, Capy prints the workflow YAML to paste into your deploy job and the deploy id to revoke later. Flags let it run non-interactively:
See Deploying → GitHub Actions for the full walkthrough.

Flags

How it works at runtime

Wrap your app (or its build step) with capy run -- <your command>. capy run auto-detects deployed mode when both SECRETS_BLOB and PROJECT_KEY are set in process.env, runs the decrypt flow, and spawns the child with plaintext values in its environment. Set both or neither - with only one of them present, capy run refuses to guess which mode you meant and exits 1. For long-running servers (Fly, Render, Railway, Heroku, containers), set it as the entrypoint:
For build-time inlining (Vercel, Netlify, any build-then-deploy platform), wrap the build:
In both cases the two env vars are the only Capy-related things your platform holds. See Deploying → Vercel for the Next.js walkthrough.

Revocation

Every mint has a deploy id. List this project’s tokens, then revoke one by id (a prefix is enough):
capy deploy list prints each token’s id prefix, its active or revoked status, and the date it was created. Revocation is server-side: a revoked token immediately stops working for new builds and boots, because capy run can no longer fetch the service key it needs to reconstruct the decrypt key. Already-running processes that have reconstructed the key keep functioning.

See also

Last modified on August 11, 2026