Secrets
A secret is a credential your functions need but your repository must never hold — a third-party API key, a signing key, a webhook token. The name is declared in project.toml (and can name exactly which functions may read it); the value is set with the CLI and stored by the platform, never committed.
Splitting the name from the value is what makes a credential reviewable. The diff shows that a new function wants STRIPE_SECRET_KEY and that only checkout may read it; the value itself never appears in a pull request, a log line, or the console. A reviewer can reason about blast radius without ever seeing the thing they're protecting.
It also means a rotation is not a deploy. Values live outside the immutable version your project publishes to, so setting a new one takes effect on the running runtimes without rebuilding or republishing anything.
Declaring one#
[[secrets]]name = "OPENAI_API_KEY"functions = ["chat"] # omit to let every function read itdescription = "Model access for the caddie assistant" [[secrets]]name = "STRIPE_WEBHOOK_SECRET"optional = true # publish can proceed before you have itNames follow environment-variable rules (letters, digits, underscores). functions is the allowlist — a function not named there has no such property on its capabilities.secrets, so a leak can't come from code that was never supposed to hold the credential. optional = true lets snoozestack publish succeed while a credential is still being obtained, instead of blocking the whole release on one pending key.
Setting values#
snoozestack secrets set OPENAI_API_KEY=sk-… # the hosted defaultsnoozestack secrets set OPENAI_API_KEY=sk-test… --dev # local-only overridesnoozestack secrets set OPENAI_API_KEY=sk-… --preview stagingsnoozestack secrets list # names + which namespaces overridesnoozestack secrets unset OPENAI_API_KEY| Namespace | Set with | Used by |
|---|---|---|
dev | --dev | Your machine, under snoozestack dev — never sent anywhere |
| a preview | --preview <name> | That preview only; falls back to the default when unset |
default | no flag | Live, and any preview without its own override |
secrets list prints names and which namespaces override them — never values. A value cannot be read back out of the platform by any surface: not the CLI, not the console, not the management API. If you lose one, rotate it at the provider and set the new value.
| Surface | Availability |
|---|---|
| Portal UI | Read-only: declared names and which namespaces override them, never values |
| CLI | snoozestack secrets set/list/unset, scoped by --dev / --preview |
| SDK / HTTP | None, deliberately — a secret that reached a client wouldn't be one |
Reading one in a function#
export default async function handler(req: Request, capabilities) { const key = capabilities.secrets.OPENAI_API_KEY; // declared for this function // … call the vendor with it; the value never leaves the runtime}The function must also declare the secrets capability — see Permissions. Changing a value reaches the runtimes already running, so a rotation needs no republish; what a container cannot pick up without being recreated is a change to its declaration.
- A third-party API key
- The model, payment, or email provider your function calls. Name it for the one function that calls it, and nothing else in the project can reach it.
- Provider credentials for sign-in
- An auth provider's client secret or signing key. The provider entry references the secret by name —
secret_name— so the key itself stays out of the file. - A different value per namespace
- Test credentials under
--devand a preview, the real ones on live, with the same code and the same declared name throughout.