Pull secrets in a deploy
Load a deployment's secrets from the vault when the process starts, with a vault key in production.
This example loads the storefront's secrets when its server starts. In production it pulls with a
vault key that can read only the storefront's production secrets; in staging it pulls with an
ordinary API key. Each pull is one GET request that returns a JSON map of name to value.
Before you begin
- The storefront is deployed to
productionandstaging, and its secrets are set. See Secrets vault and CLI. - You are an admin or owner of the workspace, to create the vault key.
1. Create a vault key
A vault key (ctvk_…) names the products and production environments it may pull. Create one for
the storefront in production, on the website under Secrets vault › Vault Keys, or with the CLI:
clanker vault key create --name "Storefront runtime" --product storefront --env production{ "id": "Vk8MtR3pLx6N", "name": "Storefront runtime", "productIds": ["Pr4GtY9sLm3B"], "environmentIds": ["En1MwX6cTb7F"], "secret": "ctvk_7HqP2mXv9LsR4tWc8NbK3dFj6YgZ1aQe" }
Copy secret now; it is never shown again. Store it in your hosting platform's secret store as
CLANKER_VAULT_KEY, next to the deployment that uses it.
2. Pull when the process starts
Pull an environment's secrets with the key as a bearer token:
curl --fail-with-body \ https://api.clankertest.com/v1/workspaces/acme/products/storefront/environments/production/secrets/pull \ -H "Authorization: Bearer $CLANKER_VAULT_KEY"
{ "DATABASE_URL": "postgres://storefront@db.acme.dev:5432/storefront", "SESSION_SECRET": "9c1f…" }
Unset names are left out, and a deployment with nothing set returns {}.
In a Node server, load the values into process.env before anything reads them:
// load-secrets.ts: import this first in the server's entry point. // DEPLOY_ENV is your own setting: production or staging. const environment = process.env.DEPLOY_ENV ?? "staging"; const key = environment === "production" ? process.env.CLANKER_VAULT_KEY : process.env.CLANKER_API_KEY; const response = await fetch( `https://api.clankertest.com/v1/workspaces/acme/products/storefront/environments/${environment}/secrets/pull`, { headers: { Authorization: `Bearer ${key}` } }, ); if (!response.ok) { const error = await response.json(); throw new Error(`Could not pull secrets (${response.status} ${error._tag}): ${error.message}`); } Object.assign(process.env, (await response.json()) as Record<string, string>);
From a shell entry point, export each value with jq, which quotes it for the shell:
eval "$(curl --fail-with-body -sS \ https://api.clankertest.com/v1/workspaces/acme/products/storefront/environments/production/secrets/pull \ -H "Authorization: Bearer $CLANKER_VAULT_KEY" \ | jq -r 'to_entries[] | "export \(.key)=\(.value | @sh)"')" exec node server.js
Pull once when the process starts, not on every request.
Staging and other non-production environments
Vault keys cannot pull non-production values. Pull staging with a user API key, an account API key or a CLI login instead:
curl --fail-with-body \ https://api.clankertest.com/v1/workspaces/acme/products/storefront/environments/staging/secrets/pull \ -H "Authorization: Bearer $CLANKER_API_KEY"
On a developer's computer, the CLI does the same with the saved login:
clanker vault pull --product storefront --env stagingWhen a pull fails
The pull answers with an error and no values. Fail the start instead of running without secrets.
| Status | _tag | Why |
|---|---|---|
401 | Unauthorized | The key is missing, wrong or revoked |
403 | Forbidden | An ordinary key pulled production, or a vault key pulled non-production, or the vault key does not name this product and environment |
404 | NotFound | No such product or environment, or the product is not deployed there |
409 | Conflict | The product or the environment is archived |
Every production pull, including a refused one, is recorded in the vault's audit log with the key that made it, never the values.
Rotate the key
Create a new key with the same scope, deploy it, then revoke the old one:
clanker vault key list clanker vault key revoke Vk8MtR3pLx6N
The next pull with a revoked key fails with 401.