TILLSECRETS · AGENT TOKENS

Let an agent use secrets it can never read.

Beta

If an agent runs the CLI on your login, it has everything you have: it can reveal values, allow new hosts and consent to its own spends. An agent token (ta_…) is a separate credential for the agent. It can use secrets through the broker, inside a scope and a daily budget you set, and nothing more.

01What it can do

Spend, request, list. Nothing else.

An agent token canIt can never
Spend a secret through the broker (secrets spend, migrate, deploy-worker)Reveal or pull a value, or resolve one into a process
Ask a person for a value (secrets request), unless minted with --no-requestGrant consent, including to itself
List projects, environments and keys its patterns reachAllow a destination or change its rules
Read its own requests and its own spend ledgerCreate presigned calls, service tokens or other agent tokens
Sign with an SSH key through the SSH agent, each signature approved by the person who made the tokenRead the SSH private key

Each API route opts in to agent tokens by name, and a test fails the build if one is added without review. Everywhere else a ta_ bearer is rejected as if it were no login at all.

02Setup

Mint one and consent

An owner or admin mints the token, from the CLI or Secrets → Agents in the console. The token is shown once. Consent is still per secret and host: the agent spends as agent:<name>, and only a person can create that grant.

mint + consent
# Scope it to what the job needs. * is a whole part; DO_* is a prefix.
tilldev secrets agents create deploy-bot \
  --refs 'infra/prod/DO_*,infra/prod/CF_API_TOKEN' \
  --budget 50 --expires 7 --quiet > deploy-bot.token

# Consent, once, for each secret and host the agent may use.
tilldev secrets broker allow secretref://infra/prod/DO_TOKEN api.digitalocean.com --methods GET,POST,DELETE
tilldev secrets broker grant create secretref://infra/prod/DO_TOKEN \
  --agent agent:deploy-bot --host api.digitalocean.com --scope ttl --ttl-minutes 1440
PatternReaches
infra/prod/DO_TOKENExactly that secret.
infra/*/DO_TOKENDO_TOKEN in every environment of infra.
infra/prod/STRIPE_*Keys starting STRIPE_ in infra/prod.
*/*/*Everything the creator can reach. Avoid it.

A wildcard matches within one part and never crosses a /, so infra/prod/* does not reach infra-old/prod/….

03In the agent

Use it

agent host
# Where the agent runs. The CLI and the Node broker SDK use it ahead of any login.
export TILLDEV_AGENT_TOKEN="$(cat deploy-bot.token)"

tilldev secrets agents whoami          # scope, spends left today, expiry
tilldev secrets spend GET https://api.digitalocean.com/v2/account \
  --bearer secretref://infra/prod/DO_TOKEN

# Needs a value nobody stored yet? Ask a person for it.
tilldev secrets request CF_API_TOKEN --env prod --note "Workers deploy, one account"

For a coding agent working in your own terminal, --save keeps the token on the machine instead of printing it. The CLI recognises Claude Code, Codex, Gemini CLI, Cursor and opencode, and uses the saved token whenever that agent runs a command, while your own commands keep using your sign-in. Set TILLDEV_AGENT_MODE=<name> for an agent it doesn't recognise.

save for a coding agent
# Inside the agent's session: the CLI sees which agent is running and names the token after it.
tilldev secrets agents create --refs 'shop/dev/*' --save     # 8 hours unless --hours or --expires

# From now on, that agent's commands on this machine act as the token.
tilldev secrets agents forget claude-code                     # back to your sign-in
A lane, not a wall
The saved token keeps a well-behaved agent to what the token allows. It is not a boundary against an agent that sets out to get around it: anything running as you can still reach your sign-in. Keep the secrets that matter most at tier 7 or above, where every reveal asks you.
broker SDK
import { createBroker, secretref } from '@tillstack/secrets-node'

// Reads TILLDEV_AGENT_TOKEN. No agentKey: the token names the agent.
const broker = createBroker()
const res = await broker.fetch('https://api.digitalocean.com/v2/droplets', {
  headers: { authorization: `Bearer ${secretref('infra', 'prod', 'DO_TOKEN')}` },
})
04Limits

Budget, expiry and whose access it carries

  • Daily budget. Each spent reference, and each SSH signature, counts one against the token's daily limit (default 100, up to 10,000). It resets at 00:00 UTC. Over the limit the broker refuses with budget_exhausted.
  • Scope. A reference outside the patterns is refused with out_of_scope before anything is decrypted.
  • Expiry. 1 hour to 90 days, default 30 days.
  • Live role. The token acts with its creator's current role. If they leave the workspace or lose access to a secret, the token loses it too.
watch + revoke
tilldev secrets agents ls
tilldev secrets broker spends --agent agent:deploy-bot   # every use, spent or refused
tilldev secrets agents revoke deploy-bot                 # immediate
Audit
Minting and revoking are in the audit log as agent.create and agent.revoke. Requests the agent makes are logged with actor type agent and the person it acts for.