Runtime identity

Bind every request to a verified human, agent, team, work mode, and task.

Where to run this

Every command on this page runs from a clone of the AgentBox repository on the trusted host — never inside the agent workspace. If you haven't cloned it yet, start with the quickstart.

By default (identity.mode: "static") the broker serves the single runtime identity from its config file. In assertion mode, each workspace presents a signed Ed25519 assertion minted on the trusted host.

Create an issuer key

Only the public key goes to the broker. The private key never goes to the broker or any workspace.

umask 077
openssl genpkey -algorithm ed25519 -out issuer.pem
openssl pkey -in issuer.pem -pubout -out issuer.pub.pem

Configure the broker

Replace runtime in config.local.json with:

"identity": {
  "mode": "assertion",
  "audience": "agentgate:acme",
  "issuers": [{ "kid": "k1", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n" }]
}

Issue an assertion

Bound to the workspace's client token, valid for at most 24 hours:

node scripts/issue-runtime.js --key issuer.pem --kid k1 \
  --client-token-file ~/.agentgate-client-token --audience agentgate:acme \
  --runtime-id rt-42 --human [email protected] --agent claude-code --team payments \
  --mode build --task jira:PAY-12 --ttl 28800 --out ~/.agentgate-runtime-assertion

The workspace sends it as the x-agentgate-runtime header. The broker checks signature, kid, audience, lifetime, token binding, claim formats, and revocation on every request. Invalid assertions get 401 ASSERTION_INVALID.

Bounded by the developer

An assertion doesn't grant permissions; it names who is delegating. Everything the agent can do is then derived from that human — their directory groups, GitHub team memberships, and Jira assignments — and narrowed by the assertion's mode, task, and the policy's repository, ref, and operation scopes. The agent ends up with at most the developer's authority, and usually a small slice of it. See Entitlements.

What changes

  • Audit records carry the verified runtime, including runtimeId and jti — never the raw assertion.
  • Approvals bind to the jti, so a renewed assertion needs fresh approvals.
  • The assertion's human can't approve their own requests.
  • Entitlement modes and teams requirements become available.

Renewal

Re-run issue-runtime.js before expiry, then agentgate renew in the workspace. The entrypoint also renews on every container start.

Revocation

Without a control plane, set AGENTGATE_REVOCATIONS_FILE to an owner-only JSON file:

{ "jtis": ["…"], "runtimeIds": ["rt-42"] }

It's re-read on SIGHUP; a malformed file is rejected and the previous list stays enforced. With a control plane, revocations come from signed bundles instead.

Warning

Whoever holds the issuer key can mint any identity. The binding proves possession of the client token, not the integrity of the workload — a stolen token-plus-assertion pair works until expiry or revocation.