onebox

Guide 06 of 30

For your agent: .md · all guides

On this page
  1. The rules, whatever tool you pick
  2. Pick a tool
  3. How the skills read a secret
  4. 1Password: a separate vault for your agent
  5. Doppler: one config per environment
  6. Where the values go
  7. Check it works
  8. Common errors

Secrets: for your app and for your agent

Runs on: your Mac, the box and GitHub Actions.

You have two kinds of secrets, and they need the same care:

Both stay out of git and out of the chat. This guide helps you pick one place for them, and set it up so an agent can read a secret without ever seeing your other passwords.

The rules, whatever tool you pick

Pick a tool

ToolWhat it costsGood forWatch out
.env filesFreeYour first weeks, on one MacOne copy per machine, no history, easy to commit by mistake
1PasswordNothing extra if you already pay for itYou already keep your passwords thereAgents need a separate vault and a service account (below)
DopplerFree for up to 3 usersApp secrets per environment (dev, staging, production), for the box and GitHub ActionsA cloud service; your secrets live there
InfisicalFree cloud tier for up to 5 identities; the open-source version is free to run on your boxYou want secrets on your own boxRunning it yourself is one more service to update and back up
Bitwarden Secrets ManagerFree for 2 users, 3 projects and 3 machine accountsYou already use Bitwarden

Prices checked on 2026-09-28.

A simple default: if you already pay for 1Password, use it for both kinds. If not, start with .env files on your Mac, and move the app secrets to Doppler when you add staging or GitHub Actions.

How the skills read a secret

Whatever tool you pick, the skills look in three places, in this order (CONFIG.md, “Secrets”):

  1. The environment. Start your agent through your tool, and it has every secret: doppler run -- claude, op run --env-file=agent.env -- claude, infisical run -- claude, bws run -- claude. You approve a prompt once, when it starts, never in the middle of a run. This works with any tool.
  2. Your command in the onebox config (~/.config/onebox/config.json), secrets.command: one shell command that prints a secret, with {ref} where its name goes. "secrets": { "tool": "doppler" } and "secrets": { "tool": "1password" } are ready-made commands.
  3. A .env file, the nearest one walking up from the folder.

1Password: a separate vault for your agent

Plain op asks for Touch ID through the 1Password app. In an agent run nobody answers that prompt, so the run hangs. A service account reads without a prompt. It can only see the vaults you give it, and 1Password never lets it see your Personal or Private vault. So you give agents their own vault, with only what they need.

Service accounts work on Families, Teams and Business plans. On an Individual plan, check your account settings first.

  1. Make a vault called agent-secrets. Move or copy in only the secrets agents need: the App Store Connect key, the Expo token, the Cloudflare token, API keys. Leave everything else where it is.

  2. Make a service account in the 1Password web app, under Developer, then Service accounts. Give it read access to agent-secrets only. Copy the token. 1Password shows it once.

  3. Store the token in the macOS Keychain, not in a file or a shell profile:

    security add-generic-password -s agent-op -a service-account-token -w

    It asks for the token. Paste it there, not in the chat.

  4. Give agents a helper for their own commands. It uses the token for one command only. Put it in ~/.zshenv, so the shells agents start also have it:

    opa() { OP_SERVICE_ACCOUNT_TOKEN="$(security find-generic-password -s agent-op -a service-account-token -w)" op "$@"; }

    Do not export OP_SERVICE_ACCOUNT_TOKEN globally. Your own op would then see only the agent vault.

  5. Tell your agent the rule. Add this to AGENTS.md or CLAUDE.md:

    Secrets: read them with `opa read "op://agent-secrets/<item>/<field>"`,
    never with plain `op`. Never print a secret. Put it in a variable or pipe
    it to the command. If an item is not in agent-secrets, ask me to move it.
  6. Point the onebox config at it. The skills’ scripts run in /bin/sh, where opa does not exist, so give them the same command in full:

    "secrets": { "command": "OP_SERVICE_ACCOUNT_TOKEN=$(security find-generic-password -s agent-op -a service-account-token -w) op read {ref}" }

    Then use op://agent-secrets/... references for each key. Or start your agent with op run, and keep plain names.

On the box and in GitHub Actions there is no Keychain. Use a second service account for each, so you can revoke one without breaking the others:

Doppler: one config per environment

  1. Make a project for the app, with the configs dev, stg and prd.
  2. On your Mac, run doppler login once, then doppler setup in the repo. After that, agents read without a prompt: doppler secrets get NAME --plain -p <project> -c dev.
  3. For the box and GitHub Actions, make a service token per config (doppler configs tokens create). A token for stg cannot read prd.
  4. Set "secrets": { "tool": "doppler", "doppler": { "project": "<project>", "config": "dev" } } in the onebox config. Or start your agent with doppler run -- claude: then every secret is in its environment, and the skills need no config.

Where the values go

SecretWhere it livesWho reads it
App Store Connect key, Expo token, Cloudflare token, media API keysagent-secrets vault, Doppler dev, or .env on your MacYour agent, through the skills
Database password, token signing key, webhook secrets, AI provider keyDoppler prd or a 1Password vault for the app; the box reads them at deployThe API on the box
The same for staging, with new valuesDoppler stg, or a separate vault or itemThe staging API
Anything EXPO_PUBLIC_*eas.json or EAS environment variablesEveryone. It is not a secret

Check it works

Common errors

Wrong or out of date? Fix it on GitHub.