Skip to main content
GitHub Actions runners are Node-capable containers. You can run capy run in any workflow step that needs decrypted secrets - builds, tests, deploys, anything that reads process.env. Unlike a runtime platform, GitHub Actions is a CI vehicle: the two secrets live in your repo’s Actions secret store, and each workflow step wraps its command with capy run. capy deploy has a built-in connector that pushes those secrets for you over the gh CLI - no copy-paste.

Set it up with capy deploy

The connector uses the GitHub CLI you already have authenticated locally - Capy never sees a token. Make sure gh is installed and logged in first:
Then, from inside your repo:
  1. Pick GitHub Actions in the platform picker.
  2. Choose Push SECRETS_BLOB + PROJECT_KEY to GitHub secrets via gh.
  3. Pick a scope:
    • Repository secrets - every workflow and every environment can read them.
    • Environment secrets - scoped to one GitHub Actions environment (e.g. production). Pick an existing environment or create one on the spot.
  4. Capy mints a fresh deploy token, runs gh secret set for SECRETS_BLOB and PROJECT_KEY in the scope you chose, and prints the workflow patch to paste plus the deploy id (for revoking later).
The connector resolves the target repo from your current directory’s git remote (gh repo view), so run it from inside the checkout you’re deploying.
The Actions secrets are named SECRETS_BLOB and PROJECT_KEY - no CAPY_ prefix. If you set them up under different names in the past, update the env: block in your workflow to match, or re-run capy deploy to overwrite them.

Workflow

Paste the patch the connector prints into your workflow. It looks like this:
Every step under the job’s env: block inherits SECRETS_BLOB and PROJECT_KEY, so you don’t have to repeat them per step.

Per-environment secrets

When you pick Environment secrets scope, the secrets land on one GitHub Actions environment. Your deploy job must pin to that environment for ${{ secrets.* }} to resolve - the connector reminds you of this in its output:
To deploy different secrets to different targets (production vs. staging), run capy deploy once per environment and point each deploy job at the matching environment.

Non-interactive setup

Every prompt has a flag, so the connector runs unattended in scripts and CI bootstrap:

Manual setup (without gh)

If you’d rather not use the connector - or gh isn’t available - choose the token path and set the secrets yourself:
Then add them under Settings → Secrets and variables → Actions, or:
The workflow is identical to the one above.

One job, one decrypt

Each capy run invocation does its own service fetch. If you want to share a single decryption across steps, run capy run once to produce a file and have later steps read it. Example for Next.js builds that emit a .capy/next-env.js manifest:

Pull requests from forks

By default, GitHub Actions doesn’t pass secrets to workflows triggered by PRs from forks - a security baseline. Forked-PR builds can’t decrypt with Capy. Usually fine: run CI without decrypted secrets, use mock values, or gate deploy jobs on github.event.pull_request.head.repo.full_name == github.repository.

Revocation

capy deploy prints a deploy id when it finishes. The SECRETS_BLOB + PROJECT_KEY stored in GitHub are long-lived, so revoke the token server-side to cut them off:
Once revoked, the GitHub-stored blob is inert - new builds and cold starts can no longer decrypt. (Already-running processes that have reconstructed the key keep working until they recycle; see Deploying → Revocation.) The secrets stay in GitHub until you delete them; revoking just makes them useless.
Last modified on June 4, 2026