v1.20Grok Build CLI support →

Secrets and deploy

Updated May 29, 2026

Touch-ID-gated bundles inject keys into a single command. Nothing touches disk in plaintext.

Why secrets exist as a CLI surface

Agents need credentials. To deploy, they need cloud API keys. To open a PR, they need a GitHub token. To hit a third-party API, they need that API's key. The wrong design is the line every engineer has typed at least once: export STRIPE_SECRET_KEY=sk_live_... in a dotfile that gets committed by accident next Tuesday.

The right design is named bundles stored in macOS Keychain, owner-readable only, that the user unlocks with Touch ID exactly once per session. The agent never reads the file. The shell history never sees the value. The dotfile contains nothing.

Create a bundle

agents secrets create stripe-prod
agents secrets add stripe-prod STRIPE_SECRET_KEY

A bundle is a named group of environment variables. The first command registers the name. The second prompts for the value — it is read off the tty with echo disabled, written straight to Keychain, and never appears in your shell history. Add as many keys to a bundle as the deploy needs: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, DATABASE_URL all under stripe-prod.

Inject the bundle into a single command

agents secrets exec stripe-prod -- bun run deploy.ts

The first invocation per session prompts for Touch ID. Keychain releases the bundle to the exec process; the keys are materialized as environment variables for the lifetime of the child process and nothing else. The child — bun run deploy.ts — runs with full credentials. When it exits, the keys are gone from memory. They were never on disk.

List and audit

agents secrets list
agents secrets show stripe-prod

list prints every bundle name and the count of keys in each. show prints the key names in one bundle — never the values. To inspect a value, you would have to call exec with printenv, and that requires Touch ID. The audit surface is intentionally cheap; the read surface is intentionally gated.

Rotate without restarting the agent

agents secrets add stripe-prod STRIPE_SECRET_KEY

Adding a key that already exists overwrites the value. No flag, no confirmation prompt beyond Touch ID, no config file to edit. The next agents secrets exec picks up the new value. The agent's prompts, scripts, and AGENTS.md do not change because they never referenced the value — only the bundle name.

Why this belongs in the harness

Hashimoto's framing of the harness is: programmed tools the agent can invoke, one per failure mode you have seen. The failure modes around credentials are well known — leaked keys in commits, agents that paste a token into the wrong file, mocked deploys that pass and then break in production because the real keys were never wired up.

agents secrets exec is the programmed tool that closes all three. The agent calls a real bun run deploy.ts against real production credentials, then verifies the deploy with a real health check. There is no mocked path. There is no plaintext on disk. The mistake is structurally impossible because the surface that would have allowed it does not exist.