Secrets
Secrets and environment variables are the entire credential story: there are no per-service connect flows to manage. Declare a name, fetch it in code, and the engine worries about where the value lives.
Declare, then get
export const meta = {
slug: "morning-digest",
title: "Morning Digest",
triggers: [{ kind: "cron", expr: "0 9 * * 1-5" }],
permissions: { secrets: [{ name: "GITHUB_TOKEN" }] },
};
const token = await secrets.get("GITHUB_TOKEN");The declaration is an allowlist: secrets.get() on an undeclared name fails, and so does a run whose declared secret is missing, with an error that says exactly what to set. Fail-closed, both ways.
Where secrets resolve from
boardwalk dev: your project's.envfile (override with--env). Nothing leaves your machine.- Boardwalk:the org's secrets vault, managed in the dashboard (Settings → Secrets). Values are encrypted at rest and released to a run only for the names its manifest declares.
- Self-hosted:the server's environment. Your hardware, your values.
The program code is identical in all three.
The redaction guarantee
Secret values live only in your deterministic code; they are redacted from everything the model sees: prompts, tool arguments, tool results, the transcript. Fetch with the token, then hand the model the data, never the credential. Because the model can't see a secret, prompt injection can't exfiltrate one.
Secrets in env vars
env: {
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}",
},When a subprocess needs a credential (a CLI you shell out to, for instance), meta.env may reference a declared secret. The reference must be the whole value, exactly as above; partial interpolation inside a longer string is not supported.