# Secrets Site secrets hold values your [functions](/functions) and [cron jobs](/cron-jobs) need at runtime — API keys, tokens, webhook signing keys — without ever writing them into source, config, or logs. ## Setting a secret Set secrets through the CLI, and always pass the value via **stdin** so it never lands in your shell history or process list: ```sh printf '%s' "$OPENAI_API_KEY" | interfold secrets set OPENAI_API_KEY --site ``` List the secrets on a site (names and metadata only — never values): ```sh interfold secrets list --site ``` Remove one: ```sh interfold secrets rm OPENAI_API_KEY --site ``` Secret names may contain letters, numbers, and underscores. Empty values are valid. ## Reading a secret in a handler Functions and cron jobs access secrets at runtime through `ctx.secrets`: ```ts export async function handler(req: Request, ctx: InterfoldContext) { const apiKey = await ctx.secrets.get('OPENAI_API_KEY') if (!apiKey) { return new Response('Not configured', { status: 503 }) } // Use apiKey to call an upstream service… return Response.json({ configured: true }) } ``` Never return a secret value in a response or log it. Treat `ctx.secrets.get(...)` output as sensitive. ## Verifying without revealing Prefer `secrets list` to confirm a secret exists. Only use `secrets get` when you explicitly need to reveal the value: ```sh interfold secrets list --site # check existence interfold secrets get OPENAI_API_KEY --site --raw # reveal (rare) ``` ## Good practice - Store third-party credentials as secrets, not in function source. - Rotate by re-running `secrets set` with the new value — it replaces in place. - Keep secret names descriptive and stable; functions reference them by name. --- Next: revisit [Functions](/functions) for a live endpoint · [Cron Jobs](/cron-jobs) for scheduled work.