Skip to content

Secrets Broker

The Secrets Broker hands agent sessions the secret values they need, one request at a time, so an agent never holds a long-lived API key. An agent asks for a secret by name; the broker decides from the secret’s owner and tier whether to grant it at once, refuse it, or ask a person; and the person approves or denies it on the broker’s own page, which their Dispatch Inbox links to, unless a model judge the deployment configured approves it first. A granted value reaches only the session that asked, in the environment of the command it runs, and every request, decision and use is recorded. That command is the agent’s choice and can read the value, so approve a secret only for a session you would trust with the value itself. The command keeps the value in its environment for as long as it runs; the grant’s expiry or revocation stops the session from reading the value again, not a command that already has it, and once the session’s own person revokes a grant it got without asking, that session asks before it gets those secrets again.

Terminal window
agent-secrets DEMO_API_KEY --reason "Deploy the example service" -- ./deploy.sh

That one command is all an agent runs. Everything else on this page explains what happens behind it.

  • No long-lived keys in agents. An agent’s environment, transcript and tools are the easiest place for a key to leak. With the broker, an agent session holds only a signing key of its own that dies with the session, and fetches a value for exactly the command that needs it.
  • A person approves what needs approval. Each secret’s owner and tier, two tags on the secret itself, say who gets it automatically and who needs a person’s yes. The request waits in that person’s Dispatch Inbox, where they already work, and one click there opens its page on the broker, where one more click approves it. A deployment may also run a model judge over one narrow class of those requests — one secret, 15 minutes at most, a reason naming an open Dispatch issue, and a secret the airlock rules let the judge decide — which the judge approves or leaves for that person (Concepts).
  • Every grant is recorded. Each approval rests on a signed, content-addressed record of who asked, for what, why, and who decided, which the broker re-verifies every time it releases a value.
sequenceDiagram
    participant Agent as Agent session
    participant CLI as agent-secrets
    participant Helper as agent-secrets-helper
    participant Broker as Secrets Broker
    participant Model as The judge's model
    participant Dispatch
    actor Person as Approver
    Agent->>CLI: agent-secrets DEMO_API_KEY --reason 'deploy the demo service' -- ./deploy.sh
    CLI->>Helper: sign this request as my session
    Helper-->>CLI: signed request and proof
    CLI->>Broker: POST /v1/requests
    Broker->>Broker: read the secret's owner and tier
    alt granted at once
        Broker-->>CLI: granted
    else a person must approve
        Broker-->>CLI: pending, the approver its record names, and its page on the broker
        opt the airlock rules let the judge decide this secret
            Broker->>Dispatch: is the issue the request's reason names open?
            Broker->>Model: the request and that issue, as data to judge
            Model-->>Broker: approve, or refer it to a person
        end
        Note over Broker,Person: a request the judge referred, or never took, waits for its approver
        Dispatch->>Broker: pending requests for the person signed in
        Person->>Dispatch: open the request in the Inbox
        Dispatch-->>Person: a link to the request's page on the broker
        Person->>Broker: Approve, signed in to the broker
        CLI->>Broker: poll until granted
    end
    CLI->>Broker: POST /v1/grants/{id}/values
    Broker-->>CLI: the values, read fresh from the secret store
    CLI->>Agent: run ./deploy.sh with DEMO_API_KEY in its environment

The judge’s step is there only where a deployment configures one. It takes a narrow class of the requests that wait: one secret, a lifetime of 15 minutes or less that the secret’s airlock rules entry lets the judge decide, and a signed reason naming a Dispatch issue that is not done. It approves such a request or leaves it for the approver, and it never denies, so a request outside that class, and one the model refers, waits exactly as it does today (Concepts).

On a machine, agent-secrets-helper holds each agent session’s key and signs for it. In a container (a box) the container holds its own key, and in Kubernetes each Legion worker pod does; the request flow is the same. Run an agent in a container shows a box’s setup.

Piece What it does Where it runs
Secrets Broker (envoy-broker) Enrolls sessions, decides each request from the secret’s owner and tier, records requests and decisions, and releases granted values. One or more identical stateless processes behind one address, beside Postgres and the secret store.
agent-secrets The command an agent runs to use a secret, the tool people and launchers use to log machines in and inspect sessions, the tool people list and revoke their machine logins and live grants with (machine list, grant list), and the tool that manages the secrets themselves, under whatever cloud credential the store’s IAM lets write them. Wherever agents run, and a person’s own machine.
agent-secrets-helper A per-user daemon that holds each host agent session’s key, enrolls it, and signs for it. Each machine that runs agents directly.
Dispatch Shows people the requests waiting on them, each secret request linking to its page on the broker; takes a machine login’s typed code and relays the person’s decision; lists the grants people can revoke; and answers the broker’s judge with the issue a request’s reason names and that issue’s spec document. Dispatch’s server and web app.
Legion Enrolls every worker pod it runs on Kubernetes, so a phase worker can use agent-secrets like any other session. Legion’s daemon.

Dispatch is where people see what waits on them: its Inbox lists Credential requests beside the asks waiting on them, each secret request a link to its page on the broker, its machine-login page takes a machine’s code, and its Settings page lists the live grants a person can revoke. A person approves a secret request on the broker’s own page, signed in to the broker itself, never through Dispatch. The broker writes nothing in Dispatch: Dispatch’s server reads what waits on the signed-in person, and relays that person’s machine-login decisions and revokes. The broker’s one read of Dispatch is the judge’s: it reads the issue a request’s reason names, its title and status and the text of its spec document, and nothing that belongs to a person.

Legion runs agents. When its Kubernetes runtime is configured with the broker, the Legion daemon logs itself in with its own Kubernetes ServiceAccount token, which no person approves, and enrolls every worker pod it starts, so each pod’s agent gets only the grants of that pod. See how Legion, Dispatch and the broker fit together.