# Agent authentication for Agent Ready

> How autonomous agents discover, claim, and use credentials to call the Agent Ready REST API and MCP server. Aligned to the WorkOS `auth.md` agent-authentication spec.

Last updated: 2026-05-28. Canonical URL: <https://agent-ready.dev/auth>.

## What is agent_auth?

`agent_auth` is the umbrella term for the patterns AI agents use to acquire and present credentials to third-party APIs. The conventions — `register_uri` for dynamic client registration, `identity_assertion` and `id-jag` for short-lived tokens minted by an upstream identity provider, and `WWW-Authenticate`-driven discovery — are collected in the WorkOS [auth.md draft](https://workos.com/auth-md). Agent Ready supports the subset needed for Bearer-token API access today; the rest will follow as agent runtimes standardise.

## Discover

Every agent_auth flow starts with the protected resource advertising how it should be talked to. Agent Ready publishes both halves of the RFC 9728 / RFC 8414 discovery pair:

- Protected Resource Metadata (PRM): <https://agent-ready.dev/.well-known/oauth-protected-resource>
- Authorization Server Metadata (AS): <https://agent-ready.dev/.well-known/oauth-authorization-server>

Fetch the PRM cold or follow the `WWW-Authenticate` header returned on any 401 response — both routes land in the same place. The PRM lists Agent Ready itself in its `authorization_servers` array; follow that pointer to the AS metadata document to find the human registration URL.

```bash
curl -s https://agent-ready.dev/.well-known/oauth-protected-resource | jq
curl -s https://agent-ready.dev/.well-known/oauth-authorization-server | jq
```

## Pick a method

Agent Ready offers a single credential type today: a long-lived Bearer API key issued from the human-owned dashboard. There is no dynamic client registration (`register_uri`) yet and no `identity_assertion` / `id-jag` token-exchange flow. The surface is intentionally minimal — pick the Bearer token method, register a key, and move on.

- supported_method: Bearer API key
- bearer_methods_supported: `header` (`Authorization: Bearer <key>`)
- grant_types_supported: `urn:ietf:params:oauth:grant-type:api-key` (out-of-band, human-mediated)

## Register

Agentic registration URI (RFC-style fields, surfaced for scanners and discovery clients):

- register_uri: <https://agent-ready.dev/dashboard/api-keys> (human-mediated key issuance — no dynamic-client-registration endpoint yet)
- registration_endpoint: not supported (no RFC 7591 dynamic client registration)
- registration_doc: <https://agent-ready.dev/auth#register>

Sign in at <https://agent-ready.dev/sign-in> with the human operator's account, then open <https://agent-ready.dev/dashboard/api-keys>. Click **Create key**, name the key after the agent or workload that will use it, and copy the secret. The secret is shown once. Store it in your agent's secret manager (1Password, Doppler, AWS Secrets Manager, GitHub Actions secrets) — never commit it to a repo. Pro plan required.

## Claim

Agentic claim URI (RFC-style fields):

- claim_uri: not supported (the Bearer key is the credential, issued at register time)
- identity_assertion_uri: not supported (no RFC 7521 assertion exchange endpoint yet)
- id-jag_exchange_uri: not supported (no JWT assertion grant exchange yet)

There is no separate claim step today — the Bearer key is the credential, issued at creation time. The claim phase is reserved for a future `identity_assertion` flow where an upstream IdP mints a short-lived `id-jag` that Agent Ready exchanges for an access token. When that ships, this section will describe the exchange contract and the resolved `identity_assertion_uri` will replace the "not supported" sentinel.

## Use the credential

Send every request with `Authorization: Bearer <key>`. The same token authenticates REST (`POST /api/v1/scans`, `GET /api/v1/scans/{id}`, `POST /api/v1/ask`) and the MCP endpoint (`POST /api/v1/mcp`). Treat it like a password: TLS only, never in URLs or logs.

```bash
curl -X POST https://agent-ready.dev/api/v1/scans \
  -H "Authorization: Bearer $AGENT_READY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'
```

## Errors

- **400 Bad Request** — Validation error. The JSON body names the offending field.
- **401 Unauthorized** — Missing or invalid Bearer token. The response carries `WWW-Authenticate: Bearer realm="agent-ready", resource_metadata="https://agent-ready.dev/.well-known/oauth-protected-resource"` so a fresh agent can recover without prior knowledge.
- **403 Forbidden** — Authenticated but the plan tier doesn't allow this endpoint (e.g. Free-tier key calling `/api/v1/scans`).
- **429 Too Many Requests** — Over the per-minute (10) or per-day (200) rate limit. Response carries a `Retry-After` header.

OAuth 2.0 canonical error codes are surfaced where applicable in the JSON body's `error` field per RFC 6749 §5.2:

- `invalid_request` — malformed body or missing required field (HTTP 400).
- `invalid_token` — Bearer token missing, malformed, expired, or revoked (HTTP 401).
- `insufficient_scope` — token valid but the plan tier lacks access to the requested resource (HTTP 403).

Example 401 response:

```http
HTTP/2 401
content-type: application/json
www-authenticate: Bearer realm="agent-ready", error="invalid_token", error_description="Missing or invalid Bearer token", resource_metadata="https://agent-ready.dev/.well-known/oauth-protected-resource"

{"error":"invalid_token","error_description":"Missing or invalid Bearer token"}
```

## Revocation

- revocation_endpoint: not supported (no RFC 7009 OAuth revocation endpoint; revocation is performed via the dashboard)
- revocation_uri: <https://agent-ready.dev/dashboard/api-keys> (human-mediated revocation)

Revoke a key from <https://agent-ready.dev/dashboard/api-keys>. Click the delete icon next to the row; the key is invalidated immediately. Any subsequent request returns HTTP 401 with `error="invalid_token"`. If a key is suspected leaked, revoke first, then rotate the replacement into your secret manager before redeploying. Revocation is instant and irreversible — there is no soft-expiry grace window.

## Step-by-step

### Step 1 — Discover the auth endpoint

Fetch https://agent-ready.dev/.well-known/oauth-protected-resource. The JSON document advertises this resource's authorization server, supported scopes, and Bearer token semantics (RFC 9728). Any unauthenticated request to a protected endpoint also returns a WWW-Authenticate header pointing at the same discovery document, so an agent that hits a 401 cold can recover by following the standard agent_auth handshake.

### Step 2 — Pick a method

Agent Ready offers a single credential type today: a long-lived Bearer API key issued from the human-owned dashboard. There is no dynamic client registration (register_uri) and no identity assertion (identity_assertion / id-jag) flow yet — the surface deliberately stays minimal until a clear demand for delegated agent auth emerges. If you are integrating with an agent platform that expects OAuth 2.1 authorization code flows, raise an issue.

### Step 3 — Register your agent

Sign in to https://agent-ready.dev/sign-in with the human operator's account and open the API keys page at /dashboard/api-keys. Click 'Create key', give it a name that identifies the agent or workload, and copy the secret. The secret is shown once. Store it in your agent's secret manager (1Password, Doppler, AWS Secrets Manager, GitHub Actions secrets) — never check it into version control.

### Step 4 — Claim a credential

There is no separate 'claim' step. The Bearer key is the credential, issued at creation time. (For future support of agent_auth identity_assertion / id-jag exchanges where an upstream IdP mints a short-lived token, the claim step will materialise here.)

### Step 5 — Use the credential

Send every request with the Authorization: Bearer <key> header. The credential authenticates both REST (POST /api/v1/scans, GET /api/v1/scans/{id}, POST /api/v1/ask) and the MCP endpoint (POST /api/v1/mcp). Use exactly the same token for both surfaces — the rate-limit budget is shared. Treat the key like a password: TLS only, never in URLs or logs.

### Step 6 — Handle errors

Missing or invalid credentials return HTTP 401 with a WWW-Authenticate: Bearer realm="agent-ready", resource_metadata="https://agent-ready.dev/.well-known/oauth-protected-resource" header. Exceeding the per-minute or per-day rate limit returns HTTP 429 with Retry-After. Plan-tier mismatches (e.g. a Free-tier key calling /api/v1/scans) return HTTP 403. Validation errors return HTTP 400 with a JSON body explaining which field is wrong.

### Step 7 — Revoke a credential

Revoke a key from the same /dashboard/api-keys page. Click the delete icon next to the row; the key is invalidated immediately and any subsequent request returns 401. If a key is suspected leaked, revoke first and rotate the replacement into your secret manager before redeploying. There is no soft-expiry — revocation is instant and irreversible.

## Frequently asked questions

### Does Agent Ready support OAuth 2.1 authorization code flow?

Not yet. The /.well-known/oauth-protected-resource document advertises Bearer token semantics per RFC 9728, but the only issuance path today is the human-mediated dashboard. If you need authorization code flow or dynamic client registration for an MCP gateway or agent platform, open an issue describing the integration — we'll prioritise based on demand.

### Where does agent_auth fit in?

agent_auth is the umbrella term for the emerging set of patterns that let an autonomous agent acquire and present credentials to a third-party API on a human user's behalf. The WorkOS auth.md spec collects the conventions (register_uri, identity_assertion, id-jag, WWW-Authenticate-driven discovery). Agent Ready's current API key surface is a strict subset — Bearer tokens with WWW-Authenticate discovery — and we will expand toward the fuller spec as agent runtimes standardise.

### What is the difference between an API key and an identity_assertion token?

An API key is a long-lived shared secret that authenticates the bearer. An identity_assertion is a short-lived, audience-scoped token (often an id-jag — id-jWT-assertion-grant) minted by an upstream identity provider that proves which human a request is acting on behalf of. Agent Ready accepts only API keys today; identity_assertion support depends on an IdP integration that maps assertions to billing accounts, which is on the roadmap rather than shipped.

### Can the same key be used for REST and MCP?

Yes — both surfaces accept the same Bearer key and share the same per-minute / per-day rate-limit budget. There is no separate "mcp_token" concept. A key created at /dashboard/api-keys works against POST /api/v1/scans and POST /api/v1/mcp interchangeably.

### How do I rotate a key without downtime?

Create a new key, deploy it to your secret manager, restart the agent (or wait for it to read the new value at next request), then revoke the old key. Because keys are independent (not versioned), the old and new keys coexist until you delete the old one — overlapping windows of any length are fine.

## Sitemap

See the full [sitemap](https://agent-ready.dev/sitemap.md) for all pages on agent-ready.dev.

---

Read the full guide on the web: <https://agent-ready.dev/auth>

Quickstart: <https://agent-ready.dev/quickstart>
