Secrets
Prerequisites
@org/fluffy-chainsaw. Deployed runners read values from GCP Secret Manager;@google-cloud/secret-managermust be installed for that path.
Declare and read
import { secret } from "@org/fluffy-chainsaw";
const key = await secret.get("stripe-key"); // async — returns the value as a string
- Build time: the marker declares that secret
stripe-keymust exist. - Runtime: resolves the injected descriptor; deployed, that means reading the secret's latest version from Secret Manager with the runner's own identity.
Grant it to a runner
secrets:
stripe-key: {}
runners:
orders-api:
uses:
secrets: [stripe-key] # grants read access + injects the descriptor
A secret declared in code that no runner lists under uses.secrets fails
validation (E_USES_SECRET_UNKNOWN) — either grant it or opt out explicitly with
defaults: { secrets: { unused: true } }.
Where the value comes from
fluffy-chainsaw provisions the secret container and the runner's access — never the value. Set the value out-of-band:
printf '%s' "sk_live_..." | gcloud secrets versions add stripe-key --data-file=-
Locally, fluffy-chainsaw local wires an env-backed descriptor, so the value comes from
your local environment instead of Secret Manager.
Field reference
secrets.<name>—existing(bool: a secret another app owns — granted onto, never created or destroyed),unused(bool: suppress the declared-but-ungranted check).
Gotchas
secret.getis async (it may call Secret Manager) — alwaysawaitit.- Don't cache-bust per request; read once at startup for hot paths.
- Secrets never ride in env vars or descriptors — the descriptor only says where to fetch from.