Register Agents
Enroll a gateway agent with an API key or a registration token, and move an agent to a new signing key by registering it again.
About registering agents
Registration creates a gateway agent under your user account and attaches your local signing DID. The Guardian Platform mints the agent ID (urn:uuid:) — you do not choose it.
Enrollment is not the same as putting an agent on a project. After the agent is registered, associate it in Guardian when you need project policy to apply to it, or when you want to see its traffic in the project.
You need the Register Agents permission. Organization Owners have it, and you can also assign the organization-level Agent Operator role. Learn more about Roles and Permissions.
Headless: API key and Viper
Use this path for CI, remote shells, and fleets.
1. Generate an enrollment key
- Generate a key with a short expiration
- Select the Register Agents scope. The dialog requires at least one scope, and empty-scope keys — legacy keys, or keys created through the Auth Service API without
scopes— cannot register agents. A full-access (*) key also enrolls, but the dialog no longer offers it - Copy the secret once (
ak_…) and store it in a secrets manager. Prefer one key per agent or pipeline

The key’s Access level decides which scopes it may carry. Project access locks project-level access, such as viewing project data. Registering agents is an organization-level action, so a key bound to one project can still enroll — but Project access hides register_agents in the picker, so choose Organization access when you are minting an enrollment key. Organization access also lets the key use its project-level permissions on every project you can already access.
API keys cannot create other API keys, so generate this key while signed in.
2. Register
Create or assign a local DID, then register. Prefer the environment variable so the secret does not appear on the command line, and do not put the key in Viper’s config file.
viper did add --assign proxy
GUARDIAN_API_KEY=ak_… viper did register --app proxy --agent-name "checkout-bot"Viper prints the DID and the server-minted agent ID:
registered did:key:z6Mk… as agent urn:uuid:3f2a…To enroll an agent that runs through a wrapper instead, name its app, for example --app claude for Claude Code. One key can enroll more than one agent. Revoking the key stops new enrollments; agents already enrolled stay active until you revoke the agent.
Revoking or restoring an agent is an Organization Owner action. It is not a project-level permission, so it cannot be delegated to a project role or carried by an API key — see API Keys.
After a successful registration, start a proxy or wrapper (viper proxy, viper claude, and so on) and point the agent at that URL. The enrollment key is not a traffic credential.
Add a replica
An agent can run on more than one machine, such as a Claude Code agent on several laptops or CI runners. Each machine is a replica with its own key, and every replica’s key belongs to the one agent. The agent’s projects and certifications cover them all, and the gateway judges each key’s configuration on its own, so a replica that drifts is cordoned while the others keep working.
On the new machine, create a key for the agent’s app, then register it with the agent’s ID. Copy the ID from Agent ID on the agent’s page in Guardian:
viper did add --assign claude
GUARDIAN_API_KEY=ak_… viper did register --app claude --agent-id urn:uuid:3f2a…registered did:key:z6Mk… as a replica of agent urn:uuid:3f2a…VIPER_AGENT_ID works in place of --agent-id. Adding a replica takes an API key, since a registration token always creates a new agent. The key’s owner must operate the agent, and the replica must run the agent’s app: a Codex key can’t join a Claude Code agent. A replica keeps the agent’s name, so leave out --agent-name. The new key appears in the agent’s Keys list, added via API Key.
For a named agent, such as a LangGraph agent in several containers, use viper agent register with --agent-id in the same way. Viper records the container as a replica, so its later registrations leave the agent’s name alone too.
Guardian: registration token
Use this path when you are at a browser.
- Open the Agent Catalog
- Select Register Agent
- Pick an Agent Type: a coding agent (Claude Code, Codex, OpenCode, or OpenClaw), a framework (LangGraph, Deep Agents, or OpenShell), or Proxy for any other agent. Then enter an Agent Name
- Guardian mints a short-lived token and shows every command the agent needs, in order: install Viper, enroll the agent with the token, check the setup with
viper doctor, and run the agent. For LangGraph and Deep Agents, a Start the Proxy step comes before running the agent. Run them on the machine the agent lives on - The last step, Confirm the First Request, checks off the agent’s enrollment, then its first signed request through the gateway. It then links to the agent’s page, where you review its request logs and configuration, build its operating profile, and associate it with a project. If nothing arrives within five minutes, it links to Troubleshooting. If the token expires before the agent enrolls, it says so; select Back and register the agent again

For a coding agent or Proxy, the enroll step creates a key for the app and registers it:
export VIPER_GATEWAY_URL=https://gateway.example.com
viper did add --assign claude
viper did register --app claude --agent-name 'Research Assistant' --provisioning-token 'ggr1.…'The commands carry your deployment’s gateway address when your administrator has configured it in Guardian; otherwise the dialog shows https://gateway.example.com and asks you to replace it. If the app already has a key, viper did add asks before replacing it; answer before you run the registration command.
The token lasts 15 minutes and works once. The Guardian Platform does not register the agent for you; it mints the token and the ID, and the agent appears in the Agent Catalog only once the command succeeds. The name you entered travels in --agent-name, so keep that flag if you edit the command.
Named agents
A LangGraph, Deep Agents, or OpenShell agent registers under its own name with viper agent register. The LangGraph and Deep Agents quickstarts then run it with the Guardian Agent SDK. Choose its framework as the Agent Type, and the dialog uses the Agent Name as that name, so it must be 1 to 64 characters of lowercase letters, digits, ., _ or -, starting with a letter or digit. An OpenShell agent’s name also names its sandbox, so it is at most 19 characters of lowercase letters, digits and single hyphens, starting and ending with a letter or digit. The agent is recorded as Custom. The dialog links the framework’s quickstart for the rest of the setup, such as agent.py or the sandbox image.
viper agent add support-bot
VIPER_PROVISIONING_TOKEN='ggr1.…' viper agent register support-botadded agent `support-bot`
did:key:z6Mk…
registered agent `support-bot` (did:key:z6Mk…) as urn:uuid:3f2a…Headless: registration token from the API
Use this path when a pipeline should hand the agent’s machine a single-use token instead of a long-lived key. Mint the token from the Control Plane API. Its URL is the one Guardian is configured with for gateway features, usually on its own host and ending in /api; ask your administrator if you don’t know it. The call needs the Register Agents permission, and it accepts your sign-in token or an API key with the Register Agents scope. The example reads the key from GUARDIAN_API_KEY:
curl -X POST "https://control-plane.example.com/api/v1/agent-registration-tokens" \
-H "Authorization: Bearer $GUARDIAN_API_KEY" \
-H "Content-Type: application/json" \
--data '{"agent_name": "checkout-bot"}'agent_name is required. The response carries the server-minted agent_id, the token in registration_token, and its expires_at:
{
"agent_id": "urn:uuid:3f2a…",
"registration_ttl_seconds": 900,
"expires_at": "2026-10-16T15:15:00Z",
"registration_token": "ggr1.…",
"correlation_id": "…"
}Pass registration_token to Viper. Run the registration on the agent’s machine, in a shell where GUARDIAN_API_KEY is not set, since Viper refuses both credentials together:
VIPER_PROVISIONING_TOKEN='ggr1.…' viper did register --app proxy --agent-name "checkout-bot"Like the Guardian token, it lasts 15 minutes and works once.
After you register
Check the registration with viper doctor, which prints pass and is registered, and the gateway accepts its signature for the app. Then open the Agent Catalog and paste the agent ID into the search box to find it.
Associate the agent with a project: in the project’s sidebar, select Associated Agents, then Associate Agent. That step requires the Create Agent Memberships permission, held by Project Owners and Organization Owners. Until you associate it, the agent can still send traffic, but Guardian’s project views will not show it and project policies will not apply to it. See Associated Agents.
Where your organization requires certified agents, assess the agent against a Governance Program once it has sent a request through the gateway. See Agent Assessments.
Replacing a signing key
Viper has no command that swaps the key on an existing agent. To move to a new key, register a new identity:
- Create a key for the app with
viper did add --assign <app>. If the app already has a key, Viper asks you to confirm the replacement. In a non-interactive shell, runviper did add, thenviper did assign --app <app> --did <new DID> --force - Register it with a fresh registration token or an enrollment key, as above
This creates a new agent with its own agent ID. It does not inherit the old agent’s project associations or audit history, so associate it with its projects again. Once the new agent works, revoke the old one from its detail page in Guardian. See Agent Inventory.
Troubleshooting
When the Guardian Platform refuses a registration, Viper prints the Guardian Platform refused the registration:, the gateway’s message and code, and what to do about it.
| Error | What to do |
|---|---|
no DID configured for <app> | The app has no key yet. Run viper did add --assign <app>, then register again. |
API key must start with ak_ | The value is not a Guardian Platform API key. Copy the secret again from Settings → API Keys; it starts with ak_. |
no enrollment credential | Pass a registration token (--provisioning-token or VIPER_PROVISIONING_TOKEN) or an API key (--api-key or GUARDIAN_API_KEY). |
cannot combine --provisioning-token … with --api-key | Provide only one of the two. |
registration_invalid_token with an API key | The key is mistyped, expired, revoked, or was issued by a different Guardian Platform environment. Check the key, and that llm_gateway_api_url is the gateway of the environment that issued it. |
registration_invalid_token with a token | The token expired (Viper prints when, by this machine’s clock) or was already used, or it was issued by a different Guardian Platform environment. Tokens work once and last 15 minutes: mint a new one. |
registration_forbidden | The API key lacks the Register Agents scope, its owner lacks the Register Agents permission, or its owner does not operate the agent being joined. |
registration_conflict | If the DID is already registered to a different agent, create a new identity with viper did add --assign <app>, or for a named agent viper agent remove <name> then viper agent add <name>. If the agent is revoked, an Organization Owner must restore it first. A deregistered agent cannot register again. |
registration_agent_not_found | The agent ID you asked to join does not exist in this Guardian Platform environment. Check the ID and llm_gateway_api_url. |
registration_app_type_mismatch | The agent you asked to join runs another app; the message names both. A replica runs its agent’s app, so register the agent’s own app with --agent-id, or leave --agent-id out to register this app as an agent of its own. |
--agent-id … only applies with --api-key | A registration token always creates a new agent. Register the replica with an API key. |
--agent-name doesn't apply with --agent-id | A replica keeps the name of the agent it joins. Leave out --agent-name. |
registration_auth_unavailable | The Guardian Platform could not check the credential. Try again; if it persists, contact your Guardian Platform administrator. |
registration_unavailable with an API key | Viper prints that the gateway “has API-key registration turned off, or all registration”. Register with a provisioning token if the gateway takes them, or ask your Guardian Platform administrator. |
registration_unavailable with a token | Viper prints that the gateway “does not take agent registrations”. Registration is turned off on that gateway: check llm_gateway_api_url names the gateway you meant, or ask your Guardian Platform administrator. |
could not reach the gateway at <url> | The gateway is down or unreachable from this machine, or llm_gateway_api_url (or VIPER_GATEWAY_URL) names the wrong address. If the error says the TLS certificate was not accepted, check the address matches the certificate’s host and that this machine trusts the authority that issued it. If it says the TLS connection failed, check the address uses https only if the gateway does. |
did not answer as an Agent Gateway | llm_gateway_api_url points at a server that is not an Agent Gateway. Set it to your gateway’s address. |
failed to load agent `<name>`'s key | The agent’s key file is missing. Restore it, or run viper agent remove <name>, then viper agent add <name>, and register again. |
Related
- Install Viper — install Viper and create the key you register
- Run Agents — start the registered agent through Viper
- Associated Agents — link the registered agent to a project and manage its membership
- API Keys — generate, scope, and revoke the enrollment key
- Agent Inventory — find the new agent, and revoke or restore it
- Roles and Permissions — the Agent Operator role and the Register Agents permission