---
title: "Register Agents"
description: "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."
source: "Guardian Platform"
---
## 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](#after-you-register) 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](./roles-and-permissions.mdx).

## Headless: API key and Viper

Use this path for CI, remote shells, and fleets.

### 1. Generate an enrollment key

From [Settings](./settings.mdx) → [API Keys](./api-keys.mdx):

1. Generate a key with a short expiration
2. 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
3. Copy the secret once (`ak_…`) and store it in a secrets manager. Prefer one key per agent or pipeline

![The Generate New API Key dialog with the name Agent enrollment, a 30-day expiration, Organization access, and the Register Agents scope selected under Agent Management.](../../../assets/api-keys/generate-api-key.png)

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.

```bash
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:

```console
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](./api-keys.mdx).

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](./agent-certifications.mdx#per-key-drift-and-the-cordon) 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:

```bash
viper did add --assign claude

GUARDIAN_API_KEY=ak_… viper did register --app claude --agent-id urn:uuid:3f2a…
```

```console
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.

1. Open the **Agent Catalog**
2. Select **Register Agent**
3. 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**
4. 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
5. 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](./operating-profiles.mdx), and associate it with a project. If nothing arrives within five minutes, it links to [Troubleshooting](./agent-onboarding.mdx#troubleshooting). If the token expires before the agent enrolls, it says so; select **Back** and register the agent again

![The Register Agent dialog after the token is created, showing the agent type, agent name, agent ID, and token expiry, then numbered steps: Install Viper, with the Cloudsmith install command, and Enroll the Agent, starting with export VIPER_GATEWAY_URL and viper did add --assign claude.](../../../assets/register-agents/registration-token.png)

For a coding agent or Proxy, the enroll step creates a key for the app and registers it:

```bash
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](./agent-inventory.mdx) 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](https://guardian-agent-sdk.docs.eqtylab.io/). 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.

```bash
viper agent add support-bot
VIPER_PROVISIONING_TOKEN='ggr1.…' viper agent register support-bot
```

```console
added 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](../../reference/control-plane/api-reference/). 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](./api-keys.mdx) with the **Register Agents** scope. The example reads the key from `GUARDIAN_API_KEY`:

```bash
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`:

```json
{
  "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:

```bash
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](./agent-inventory.mdx) 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](./associated-agents.mdx).

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](./agent-assessments.mdx).

## 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:

1. 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, run `viper did add`, then `viper did assign --app <app> --did <new DID> --force`
2. 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](./agent-inventory.mdx#revoke-and-restore-an-agent).

## 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.mdx) — install Viper and create the key you register
- [Run Agents](./run-agents.mdx) — start the registered agent through Viper
- [Associated Agents](./associated-agents.mdx) — link the registered agent to a project and manage its membership
- [API Keys](./api-keys.mdx) — generate, scope, and revoke the enrollment key
- [Agent Inventory](./agent-inventory.mdx) — find the new agent, and revoke or restore it
- [Roles and Permissions](./roles-and-permissions.mdx) — the Agent Operator role and the Register Agents permission