Agent Office v0.2.3 · POC Get started
Menu: Guides

Guides

Model credentials

Which model credential an office should use, how to store it, and which one a run picks.

Every agent run is a Claude Code process, so the office needs a model credential. It lives in the office's encrypted secret store, never in office.yaml, never on a command line, and never on screen.

Which credential to use#

A Claude subscription token (from claude setup-token) is fine for one person using an office for their own work.

When a company runs an office for its business, use Anthropic API keys: create them in a Console workspace with a spend limit.

Read the terms that apply to you: Consumer Terms and Commercial Terms. This page is not legal advice.

The same note is printed by officectl init, officectl secrets set (for any models.* secret) and officectl doctor, and shown on the Settings page.

The three secrets#

SecretKindPassed to the run as
models.anthropic_key.<slug>API key for one agentANTHROPIC_API_KEY
models.anthropic_keyAPI key for the whole officeANTHROPIC_API_KEY
models.claude_oauth_tokenClaude subscription token from claude setup-tokenCLAUDE_CODE_OAUTH_TOKEN

models.anthropic_key is the default name; models.key_secret in office.yaml changes it, and the per-agent name follows it (<key_secret>.<slug>).

Which one a run uses#

When a run is admitted, the office takes the first credential that exists:

  1. the agent's own API key, models.anthropic_key.<slug>
  2. the office API key, models.anthropic_key
  3. the subscription token, models.claude_oauth_token

If none exists, the run is refused with the reason model key missing (ledger run.refused). The kind used (api_key or subscription) is recorded in the run.started and run.finished ledger entries, never the value.

A per-agent key lets you give one agent its own Console workspace and spend limit, separate from the rest of the office.

Store a credential#

At setup, officectl init can store it for you:

officectl init … --model-credential-kind api_key \
    --model-credential-file ./api-key.txt
officectl init … --model-credential-kind subscription \
    --model-credential-file ./setup-token.txt

--model-credential-kind subscription stores the file's contents as models.claude_oauth_token; api_key stores it as models.anthropic_key. Pass - as the file to read stdin. Run interactively without these flags, init asks for a credential (input hidden; blank skips it).

Any time later, as the office user:

# office API key
officectl secrets set models.anthropic_key
# API key for the agent "cos" only
officectl secrets set models.anthropic_key.cos
# personal use: create a subscription token, then store it
claude setup-token
officectl secrets set models.claude_oauth_token
# names only, never values
officectl secrets list

secrets set reads the value from a hidden prompt, or from stdin when piped (printf '%s' "$KEY" | officectl secrets set models.anthropic_key). Values never go in argv.

Check what is in use#

  • officectl doctor reports model credential: API key or model credential: Subscription — personal use, and fails with a fix if there is none.
  • The Settings page (admins, settings.read) shows the credential as a label, Subscription — personal use or API key (or Not set), and never the value. In this release it looks only at the office key secret (models.key_secret), so an office that uses models.claude_oauth_token alone shows Not set there even though runs work; trust officectl doctor.
  • officectl init ends with a Model credential: line in its summary.

Spend#

Each agent also has a daily budget in its personnel file. With hard_stop: true, a run is refused once the day's spend reaches it, and an admitted run gets the remaining budget as a cap. A Console spend limit is a second, provider-side ceiling.