---
title: "The Agent Provider Is the IdP: A Standards Reading of WorkOS auth.md"
date: "2026-05-22T12:00:00-07:00"
lastmod: "2026-05-22T12:00:00-07:00"
description: "WorkOS auth.md frames a real pattern for one-click agent setup with third-party services. The useful standards question is not whether agents need runtime signup, but how the Agent Verified path composes ID-JAG, OAuth client registration, metadata, lifecycle, and trust establishment."
summary: "WorkOS auth.md is an agent-readable registration document for one-click setup, with Agent Verified, user-claimed, and anonymous paths. In the Agent Verified path, most pieces already exist across OAuth and OpenID standards: ID-JAG, OAuth metadata, dynamic client registration, standard token endpoints, and SSF/CAEP/OPC. The standards gap is a profile for runtime agent onboarding and trust establishment, not a new grant protocol."
slug: "agent-provider-is-the-idp-standards-reading-of-workos-auth-md"
tags:
  - "OAuth"
  - "Agentic Identity"
  - "ID-JAG"
  - "IAM"
  - "OpenID Connect"
  - "Standards"
  - "auth.md"
  - "Agent Verified"
---


When WorkOS published [auth.md](https://workos.com/auth-md/docs), it named a real problem. Agents need an agent-readable way to register with third-party services at runtime, then operate against those services' APIs and tools. The parent `auth.md` file is the service's setup guide for agents: where to discover protected resource metadata, which registration methods are supported, how to claim or verify the relationship, how credentials are used, and how errors and revocation work.

The [agent provider guide](https://workos.com/auth-md/docs/agent-providers) is one part of that larger system. It covers the Agent Verified path, where an agent provider such as OpenAI, Anthropic, Cursor, or a similar platform asserts a user's identity to a downstream service with an ID-JAG. This is the same topology I sketched in [ID-JAG Beyond the Enterprise IdP](/notes/id-jag-beyond-the-enterprise-idp/): the IdP Authorization Server is whoever the resource has chosen to trust for SSO and subject resolution, not just a workforce IdP. That path is the focus of this post because it is where the standards question is most interesting: how should an agent provider perform one-click setup, client establishment, and delegated API access without inventing a new grant layer?

auth.md is useful as an agent-readable onboarding document. Its Agent Verified path already makes the most important standards choice: it reuses ID-JAG. Agent Verified should be an OAuth and OpenID profile, not a new grant surface. The opportunity is to lean further into the ID-JAG choice so auth.md increases the value of the OAuth and OpenID work already underway instead of becoming a long-lived parallel surface. The deployment is new. The grant surface does not have to be.

The most important thing auth.md gets right is the assertion. When auth.md specifies `assertion_type: "urn:ietf:params:oauth:token-type:id-jag"` in its registration request, it is adopting an IETF draft (the [Identity Assertion JWT Authorization Grant](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/), which I co-author) that defines exactly this kind of cross-domain identity hop. ID-JAG names the IdP Authorization Server, the Resource Authorization Server, the audience binding, the typed JWT (`oauth-id-jag+jwt`), the validation rules for the assertion, and the JWT-bearer presentation path that turns the assertion into an access token. It also names the claims the assertion is expected to carry: subject, issuer, audience, jti, expiry, plus the OIDC identity claims (`email`, `email_verified`, `phone_number`, `phone_number_verified`, and so on). Picking the right primitive is the load-bearing decision in any one-click agent setup design, and auth.md picked it.

This post is not arguing for a different assertion. It is arguing for completing the adoption. The agent provider is already signing an ID-JAG; the resource should accept it through the JWT-bearer grant ID-JAG was designed for, at the standard token endpoint, with the standard OAuth error model. The verified-contact requirement should be expressed as a claim predicate on the ID-JAG, not as a parallel assertion type. The revocation surface should ride on the shared identity-event channel ID-JAG's same issuer already authorizes. The hard part is done. The rest is composition.

There is an ecosystem maturity caveat. ID-JAG is still a draft. CIMD is still a draft. OPC is still a draft. A symmetric trusted-issuer discovery mechanism is not written yet. auth.md is therefore not wrong to move ahead of the finished standards stack; products have to ship while standards are catching up. The question is how to move ahead without making the bridge permanent.

Call the missing piece the Agent Onboarding Profile: a profile for runtime agent signup, account linking, client establishment, consent capture, delegated token issuance, events, and lifecycle. It should say how the existing OAuth and OpenID machinery composes into one click. It should not rename the token endpoint, fork the error model, or create a parallel credential exchange. If a deployment needs a setup endpoint, that endpoint should own account and client establishment, not token issuance.

If the user asks an agent to update a CRM record, file a support ticket, or inspect a project board, and that service has never been connected to the agent provider before, the service needs more than an access-token exchange. The default today is for the user to paste an API key into the agent, which moves the consent prompt, the revocation UX, and the delegation audit trail to whichever side the key was generated on. What is needed instead is the agent version of "Sign up with Google": establish the user or tenant relationship, create or bind the OAuth client the agent will use, obtain delegated API access for the relevant tools, and keep the lifecycle manageable after setup.

The OTP-based user-claimed and anonymous paths are useful, but they solve a different bootstrap problem: how an agent can start a registration on behalf of a user who has not yet proved control of an address or account, claim it later when the user does prove control, and upgrade access from there. That is closer to invitation, account-claim, and partial-trust registration work than to ID-JAG. This post focuses on the Agent Verified path.

# What Is Actually New

The deployment is a self-service signup flow where an agent provider, not the user's workforce SSO IdP, is the identity issuer that bootstraps a downstream service relationship. The agent provider acts as the IdP Authorization Server in ID-JAG's terms, even though it is not where the user originally authenticated for workforce SSO. That is exactly what the ID-JAG draft already permits: the IdP Authorization Server is whoever the Resource Authorization Server has chosen to trust for SSO and subject resolution for this hop.

The OpenID Foundation's [FastFed Core 1.0](https://openid.net/specs/fastfed-core-1_0-03.html) tried a version of this for the SaaS era: an IT admin clicks through a handshake at a SaaS that configures SSO and SCIM provisioning in one ceremony. It did not become the default deployment pattern because the admin lane already had vendor-specific console flows and the consumer lane already had Sign in with Google, Sign in with Microsoft, and email signup. The scale was forgiving: a large enterprise federated with hundreds of SaaS apps over its lifetime, each set up once.

The agent onboarding case is a third lane, and the volume is different by orders of magnitude. It is not admin-initiated like FastFed; the user clicks "Connect Notion" at runtime. It is not user-direct like Sign in with Google; the agent acts on the user's behalf and the agent provider attests the user's identity to Notion. Agents may need to connect to many services on demand and establish each relationship in seconds. Human-in-the-loop setup does not scale to that shape. The trust relationship is between the agent provider and the resource, established at the user's request.

Inside that third lane, what is new at the protocol layer is the packaging: one click that creates or links the downstream account, establishes the agent's OAuth client identity, and obtains delegated API access. That is more than a JWT-bearer grant, but it is still a composition of existing standards.

That distinction matters because the OAuth ecosystem's response should be to make the onboarding pattern easy to express in existing standards, not to fork the grant surface for it.

# One-Click Agent Setup

Here is the shape in concrete terms. A user tells Claude, "Connect Notion." Claude is the agent, Anthropic is the agent provider, and Notion is the downstream service. The names are illustrative; the pattern is general.

```mermaid
sequenceDiagram
    actor U as User
    participant A as Agent
    participant AP as Agent Provider / IdP AS
    participant N as Notion Resource + AS
    participant EL as Events / Lifecycle

    U->>A: Connect Notion
    A->>N: Discover PRM + AS metadata
    N-->>A: Metadata + onboarding profile
    A->>AP: Request ID-JAG for Notion context
    AP->>U: Prompt for scoped Notion setup consent
    U-->>AP: Approve setup
    AP-->>A: ID-JAG
    A->>N: Begin onboarding with ID-JAG, consent, and client metadata
    N->>N: Verify issuer trust
    N->>N: Link or create account
    N->>N: Register or bind client
    N->>N: Record consent and scope
    N-->>A: Setup result
    A->>N: JWT-bearer grant with ID-JAG
    N-->>A: Access token
    A->>N: Call tools and APIs with delegated token
    N-->>EL: SSF / CAEP events
    EL-->>N: OPC lifecycle / RFC 7009 revocation
```

In wire-traffic terms, Claude discovers Notion's RFC 9728 Protected Resource Metadata and RFC 8414 Authorization Server Metadata. Notion advertises an agent onboarding profile and the agent providers or trust mechanisms it accepts. Claude asks Anthropic for an ID-JAG scoped to Notion, Anthropic prompts the user for this specific setup, and Anthropic returns the assertion. Notion verifies the ID-JAG issuer, resolves or creates the local account relationship, registers or binds the agent client, records the user's consent, and returns a setup result. Only after that does Claude use the standard RFC 7523 JWT-bearer grant at Notion's token endpoint to obtain delegated access.

`/agent/auth` is not replaced by a single endpoint. It is decomposed into a profile: discovery, trust, identity assertion, account linking, client establishment, credential issuance, events, and lifecycle. The token endpoint handles token issuance. A setup endpoint, if present, handles the resource-local signup state. Neither endpoint should be forced to carry the whole ceremony.

Layered, the composition looks like this:

| Layer | Standards-based shape |
| --- | --- |
| Discovery | RFC 9728 + RFC 8414 + profile metadata |
| Trust | Federation, registry, or user-mediated trust |
| Identity assertion | ID-JAG issued by the agent provider |
| Account linking | Resource-local user or tenant relationship |
| Client establishment | DCR, CIMD, federation metadata, or client binding |
| Credential issuance | RFC 7523 JWT-bearer grant at the token endpoint |
| Events | SET / SSF / CAEP |
| Lifecycle | OPC |

The same question surfaces in the OAuth-for-MCP conversation. The [MCP authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization) already leans on OAuth protected resource metadata, authorization server metadata, client ID metadata documents, and dynamic client registration. What it does not define is the same onboarding ceremony at issue here: agent provider trust, account linking, client establishment, consent capture, and delegated tool access as one setup flow. auth.md is one proposed product shape for that problem. [MCP Enterprise Managed Authorization](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization) is another, currently deferring trust setup to manual admin configuration because no discovery mechanism exists yet. The standards answer should make these cases converge, not create separate onboarding rituals for each ecosystem.

# What auth.md Already Gets Right

Before mapping the layers, it is worth being specific about what the proposal gets right, because it is more than the framing.

**The parent artifact.** The top-level `auth.md` file is useful because it gives agents a human-readable but structured setup guide at the service boundary. Protected Resource Metadata remains the runtime source of truth for endpoint URLs and supported flows, while auth.md explains the registration ceremony in a form agents can parse and users or developers can inspect. That is a good product shape.

**Multiple onboarding paths.** auth.md is not only an agent-provider protocol. It includes Agent Verified, user-claimed, and anonymous paths. The user-claimed and anonymous flows are closer to account-claim, invitation, OTP, and partial-trust product ceremonies. The Agent Verified path is the one where the agent provider becomes an identity issuer and where ID-JAG, OAuth metadata, client registration, and federation standards apply directly.

**An opinionated profile.** WorkOS is also right that "just use OAuth" is not enough guidance for integrators. OAuth is a toolbox. One-click agent setup needs a named ceremony that says which documents to fetch, which endpoints to call, what state transitions happen, what the user sees, and how revocation works. WorkOS is optimizing for immediate integrator comprehension: one file, one block, one endpoint, one credential response. That product simplicity is the right instinct. The critique in this post is not that auth.md is too opinionated or that it ignored standards. It is that the profile becomes more valuable if each piece that can be OAuth or OpenID is expressed that way as the ecosystem catches up.

**What "Agent Verified" actually claims.** The brand carries weight because an agent provider can attest things a workforce IdP usually cannot: identity (the user behind this request), agent identity (the registered agent client), agent-user binding (the user linked this agent to their account), and fresh user authorization for this setup action. Only the first is what a generic OIDC IdP attests. The other three are why an agent provider is a credible IdP role, not a marketing label. All four signals fit in ID-JAG's claim space. None of them justifies a new grant type.

**The consent step is real.** In workforce SSO, IT consents on behalf of the user. In "Sign up with Google," the user explicitly chose Google as their issuer for the new account. In Agent Verified, the user consented to the agent at the agent provider, not to the agent provider acting as identity issuer to this specific downstream service. The onboarding profile should make that consent step explicit, scoped to the resource, and revocable independently of the agent's overall access.

auth.md has the right instincts. The mechanics need to be framed as an onboarding composition, not as a new replacement for OAuth's grant and metadata model.

# Discovery and Metadata Are Mostly Already Covered

The parent `auth.md` file points agents at Protected Resource Metadata and the authorization server metadata. The Agent Verified path then introduces a custom `agent_auth` block in the authorization server metadata document. Some fields map directly to existing OAuth metadata. Others are trying to describe the one-click setup profile and should be treated as profile metadata, not as a new parallel discovery system:

| auth.md (custom) | Native standard |
| --- | --- |
| `agent_auth.skill` | Profile identifier URI; native equivalent is a profile URI in `authorization_grant_profiles_supported` (the same shape ID-JAG uses for `urn:ietf:params:oauth:grant-profile:id-jag`) |
| `agent_auth.register_uri` | Onboarding profile endpoint, or a composition of Dynamic Client Registration (RFC 7591), account/tenant creation, and token issuance |
| `agent_auth.claim_uri` | `token_endpoint` for the ID-JAG JWT-bearer grant, once the relationship and client are established |
| `agent_auth.revocation_uri` | `revocation_endpoint` (RFC 8414 plus RFC 7009) |
| `agent_auth.identity_types_supported` | `grant_types_supported` (RFC 8414), plus profile-specific advertising from the ID-JAG draft |
| `agent_auth.identity_assertion.assertion_types_supported` | Resource AS: `authorization_grant_profiles_supported` includes `urn:ietf:params:oauth:grant-profile:id-jag` (ID-JAG §7.2), with `grant_types_supported` listing `urn:ietf:params:oauth:grant-type:jwt-bearer`. IdP AS: `identity_chaining_requested_token_types_supported` includes `urn:ietf:params:oauth:token-type:id-jag` (ID-JAG §7.1) |
| `agent_auth.identity_assertion.credential_types_supported` | Bearer credential profile semantics; API-key-shaped credentials need lifecycle, display, rotation, and revocation rules, not a new grant type |
| `agent_auth.events_supported` | RFC 8417 SET event types advertised via SSF and CAEP metadata |

At the resource side, [RFC 9728 Protected Resource Metadata](https://datatracker.ietf.org/doc/html/rfc9728) already solves the protected-resource discovery problem, and auth.md correctly adopts it. At the authorization server, [RFC 8414 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414), extended by the ID-JAG and Identity Chaining drafts, covers the grant and token-exchange advertising.

What remains is profile metadata for agent onboarding: where setup starts, which agent providers are accepted, which client-registration modes are supported, which account-linking semantics apply, and which delegated scopes or tool surfaces can be requested. That metadata should extend the OAuth discovery model rather than replace it.

Discovery should name the ceremony. It should not rename the OAuth endpoints.

# Credential Issuance Should Use the JWT-Bearer Grant

Once setup is complete, auth.md's access exchange uses a custom JSON request to a custom endpoint:

```http
POST /agent/auth HTTP/1.1
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "eyJhbGc...",
  "requested_credential_type": "access_token"
}
```

The native equivalent, defined by [RFC 7523 JWT Profile for OAuth 2.0 Authorization Grants](https://datatracker.ietf.org/doc/html/rfc7523) and profiled by [ID-JAG §4.4](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/), is a form-encoded request to the Resource Authorization Server's standard token endpoint, with the ID-JAG JWT (typed `oauth-id-jag+jwt` per §3.1) carried in the `assertion` parameter:

```http
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=eyJhbGc...
```

For the access-token step, every parameter in the auth.md request collapses into the standard JWT-bearer grant. The `type` parameter, the `assertion_type` parameter, the `requested_credential_type` parameter, and the JSON content type all disappear. Form encoding is the OAuth norm, and the wider OAuth toolchain (client libraries, gateways, audit pipelines) is already wired for it.

The response is a standard OAuth token response: `access_token`, `token_type`, `expires_in`, `scope`. Implementation fields like `registration_id` and `registration_type` are useful inside a deployment but do not belong in the token response surface. An API key is a bearer credential with a long lifetime. Its lifecycle, display, rotation, and revocation are profile concerns, not a reason for a second grant type.

That does not mean runtime signup is solved by the token endpoint alone. It means the token issuance part of runtime signup should use the token endpoint, while account or tenant creation and OAuth client establishment should be profiled explicitly around it.

The token endpoint issues authority. It should not become the signup engine.

# Client Establishment Is Part of Setup

The place auth.md is pointing at something real is the moment before the first token is issued. WorkOS models this as a service-side agent registration and issued credential. A standards profile should say how that registration maps onto OAuth concepts: which client or client instance represents the agent for this user or tenant, how that client is bound to the agent provider, and how the resulting credential is constrained.

In traditional SaaS, the equivalent step is hidden inside signup: the user clicks "Sign up with Google," the SaaS creates the account, and any application-level integration state is created behind the scenes. For agents, that hidden state includes a service-side registration plus an OAuth client, client instance, or client binding that the agent will later use to call APIs.

The standards pieces exist. [OAuth Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) defines how a client can be registered with an authorization server. The [OAuth Client ID Metadata Document](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/) draft lets a stable `client_id` point at a signed or hosted metadata document, which is a good fit for agent providers that rotate keys and publish client identity at scale. [OpenID Federation](https://openid.net/specs/openid-federation-1_0.html) can also carry metadata and policy for automated trust and registration in federated deployments.

What is missing is a profile that says how these pieces compose for one-click agent setup: whether the downstream service dynamically registers a per-agent-provider, per-user, or per-tenant client or binds to an existing one; how the ID-JAG subject and tenant context link to the created account; how the client metadata document is validated and bound to the setup transaction; and which scopes, tools, or APIs the user approved during setup.

Beyond that, the profile also has to handle the operational shape: how claim-token or partial-trust state is represented when setup is not yet complete, what audit events are emitted for registration state transitions, which rate limits and abuse controls apply, and how the resulting client and delegated token are revoked, rotated, or migrated later.

That is useful standards work. But it is not a new credential type and not a new grant. It is a runtime onboarding profile around existing OAuth client registration, metadata, identity assertion, and token issuance.

# Revocation Is Two Different Standards Depending on Intent

auth.md collapses two distinct operations into a single `/agent/auth/revoke` endpoint that accepts a `logout+jwt`. Those two operations have separate standards because they answer different questions.

**Revoke a specific token, right now.** That is [RFC 7009 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009) against the standard `revocation_endpoint`. A form-encoded token parameter, no JWT envelope, no event semantics. The endpoint is already advertised by RFC 8414 metadata.

**Signal a cross-domain identity event the resource should care about.** That is the actual semantic auth.md is reaching for: the agent provider knows the user was deprovisioned, or the agent's authority was withdrawn, and downstream services should react. That is [RFC 8417 Security Event Tokens](https://datatracker.ietf.org/doc/html/rfc8417) delivered via [RFC 8935 push](https://datatracker.ietf.org/doc/html/rfc8935) or [RFC 8936 poll](https://datatracker.ietf.org/doc/html/rfc8936), profiled by the OpenID Foundation's [Shared Signals Framework](https://openid.net/specs/openid-sharedsignals-framework-1_0.html) and [CAEP](https://openid.net/specs/openid-caep-1_0.html). A `logout+jwt` is just a SET carrying a logout event, already covered by [OpenID Connect Back-Channel Logout](https://openid.net/specs/openid-connect-backchannel-1_0.html).

auth.md acknowledges this directly: "Expect this surface to extend with SET / CAEP / RISC event communication." The long-term standards path should move this surface onto SSF and CAEP rather than keep a bespoke revocation endpoint. Resources that already integrate Shared Signals for workforce IdPs should be able to receive agent provider events through the same channel.

# Lifecycle Beyond Revocation

The lifecycle surface in auth.md is one operation wide: the `logout+jwt` revocation. An agent provider acting as the identity issuer for a downstream resource needs to do more than tell the resource a session is over. It needs to provision the user when the relationship starts, update claims when they change, suspend the account when the user is deprovisioned at the agent provider, and delete it when the relationship ends.

[OpenID Provider Commands (OPC)](https://openid.github.io/openid-provider-commands/main.html), a draft I co-author with Dick Hardt, defines a directive channel from the OP to the RP for the full account lifecycle: Activate, Maintain, Suspend, Reactivate, Archive, Restore, Delete, Invalidate, and Migrate. Commands are signed JWTs typed `command+jwt` posted to an RP-advertised `command_endpoint`, with synchronous and asynchronous variants and metadata-based capability negotiation. Tenant-level variants exist for bulk operations across an organizational scope.

The important property for the agent provider case is that **OPC requires no new trust relationship**. The OPC issuer is the same OP that signs ID-JAGs. The same `iss`, the same JWKS, the same key material the resource is already validating for setup and token exchange. Once the resource has decided to trust the agent provider as an IdP Authorization Server for ID-JAG, it has also decided to trust it as the OPC sender. One issuer, one trust relationship, one set of keys.

SSF and CAEP are right for cross-domain risk signals and session-end notifications. OPC is right for lifecycle directives: provisioning, claim updates, suspension, deletion, and migration. Together they cover the event and lifecycle work auth.md points toward without requiring a bespoke revocation surface.

# Claim Negotiation Has a Pending Standards Answer

auth.md treats `verified_email` as a separate `assertion_type` alongside ID-JAG, and pairs it with a `missing_verified_email` error code. The name is narrower than the behavior: WorkOS says a service needs at least one verified contact, such as `email_verified` or `phone_number_verified`, to match or provision a user. Both surfaces are solving the same underlying problem: the resource cannot complete account resolution or JIT account creation without certain identity claims or claim predicates in the assertion, and there is no interoperable way for the resource to tell the IdP which claims it needs.

ID-JAG already carries `email`, `email_verified`, `phone_number`, and `phone_number_verified` per OpenID Connect Core. A "verified email only" assertion is an ID-JAG with `email_verified: true`. The signature, audience, issuer, and replay protections are identical to any other ID-JAG. Treating it as a separate assertion type splits the validation path without adding a new security property.

The real problem is not verified email. It is claim negotiation. Different resources need different claims: email, phone, department, employee number, license tier, custom identifiers. Some requirements are simple claim presence checks. Others are predicates, such as "email must be verified" or "either verified email or verified phone is present." The IdP has no standardized signal from the client about what the target resource requires.

That gap is being addressed inside the ID-JAG draft itself. [Issue #83](https://github.com/oauth-wg/oauth-identity-assertion-authz-grant/issues/83) proposes a small, symmetric extension:

- A new error code, `insufficient_identity_claims`, that the Resource Authorization Server returns when the assertion is cryptographically valid but lacks the claims needed for account resolution or JIT provisioning. The naming follows the RFC 9470 `insufficient_user_authentication` pattern: valid, but not enough.
- A `required_claims` parameter on that error response, naming the missing claims as a space-separated list of claim names, in the same shape OAuth already uses for `scope`.
- A `required_claims` parameter on the client's Token Exchange request to the IdP, letting the client pass the resource's requirement straight through without transformation.

The end-to-end flow becomes: present a minimal ID-JAG, receive `400 insufficient_identity_claims` with `required_claims=email email_verified department employee_number` or a profile-defined verified-contact requirement, ask the IdP for an enriched ID-JAG subject to its own policy, and retry. No separate `verified_email` assertion type. No bespoke `missing_verified_email` error. The same mechanism handles resource-specific identity requirements instead of hard-coding one verified-email branch.

# The Error Catalog Is Already Small on Purpose

auth.md introduces several error codes. Most should map to existing OAuth errors at the protocol layer, even if the onboarding profile keeps product-level recovery states:

| auth.md | RFC 6749 or RFC 9470 |
| --- | --- |
| `invalid_issuer` | `invalid_grant` |
| `invalid_signature` | `invalid_grant` |
| `expired` | `invalid_grant` |
| `replay_detected` | `invalid_grant` |
| `invalid_audience` | `invalid_grant` |
| `invalid_client_id` | `invalid_client` |
| `missing_verified_email` | `insufficient_identity_claims` with `required_claims=email email_verified`, or a profile-defined verified-contact requirement ([ID-JAG draft issue #83](https://github.com/oauth-wg/oauth-identity-assertion-authz-grant/issues/83)) |
| `unsupported_credential_type` | `unsupported_grant_type` or `invalid_scope` |
| `insufficient_user_authentication` | Already RFC 9470, keep as-is |

OAuth deliberately keeps the top-level error catalog small and pushes specifics into `error_description`. The profile may still define recovery states for onboarding, account linking, claim completion, and user-visible remediation. But it should avoid inventing new names for cryptographic, token, and grant failures OAuth already defines. The one row that justifies a distinct protocol signal is `missing_verified_email`, where issue #83 proposes `insufficient_identity_claims` as an interoperable way for the client to retry against the IdP. For the rest, `invalid_grant` plus `error_description` is the OAuth norm, and clients should not branch on error reasons that the spec asks them to treat identically.

# Profile Requirements

ID-JAG is the grant. The Agent Onboarding Profile is the ceremony around it. They are not competitors; they are layers. The profile composes existing specs into a coherent one-click agent-setup flow without adding a new credential exchange. Some profile metadata is still useful, because a client needs to know whether the resource supports this ceremony and which trust, account-linking, and client-establishment modes apply. The constraint should be pragmatic rather than absolutist: use profile glue where the ecosystem has a real gap, but avoid new grant types, new token endpoints, new revocation endpoints, and duplicate names for failures OAuth already defines.

What the deployment profile specifies for each requirement area:

1. **Discovery.** How RFC 9728, RFC 8414, and existing profile metadata advertise setup support.
    - PRM and AS Metadata carry endpoint discovery. Profile metadata carries only the ceremony-specific parts: setup support, supported trust mechanisms, account-linking modes, client-establishment modes, delegated credential types, and lifecycle/event support.
    - ID-JAG support is advertised with `urn:ietf:params:oauth:grant-profile:id-jag` in `authorization_grant_profiles_supported`. That URI tells a client the resource speaks the protocol. It does not tell the client which issuers, tenants, clients, subjects, audiences, or authorization requests the resource will actually accept. Trust discovery is a separate problem, and the ID-JAG draft is explicit about it.

2. **Trust.** How the service decides which agent providers it accepts.
    - Resolved via a companion trusted-issuer-discovery mechanism (see below), OpenID Federation, registry membership, signed metadata, or user-mediated trust.
    - If a new `untrusted_issuer` error is needed, it should belong to that companion trust-discovery work, not to the onboarding profile.

3. **Assertion.** How ID-JAG carries the user, tenant, agent-provider, consent, and client-binding context needed for setup.
    - ID-JAG draft §4 covers validation and claims. The deployment profile clarifies that consent and scope claims attest the user's approval at the agent provider for this audience.

4. **Account linking.** How the service decides whether this is a new relationship, an existing user, or an existing tenant connection.
    - Resource resolves the ID-JAG `sub` to a local account or tenant, or JIT-provisions one on first use of (`iss`, `sub`).
    - Missing claims return `insufficient_identity_claims` with `required_claims` (defined by ID-JAG issue #83, not this profile).

5. **Client establishment.** How service-side registration maps to a client identity.
    - The profile should prefer [CIMD](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/) for client identity when there is no prior relationship. The `client_id` is a URL whose document publishes client metadata, and the resource fetches and validates it on first use.
    - DCR, pre-registration, federation metadata, or client binding remain valid deployment choices. Client identity can stay singular per agent while per-user or per-tenant state lives in the ID-JAG `sub`, tenant context, and the resource's local account record.
    - Because ID-JAG is intended for confidential clients, the profile should say how the agent client proves possession: private-key client authentication, DPoP-style binding, attestation, or another asymmetric mechanism. A public URL-shaped `client_id` is identity metadata, not proof by itself.

6. **Credential issuance.** How the resource authorization server issues delegated access through the JWT-bearer grant.
    - Agent presents an ID-JAG at the standard `token_endpoint` via the RFC 7523 JWT-bearer grant (`assertion=<ID-JAG>`). Standard OAuth token response.
    - API-key-shaped bearer credentials, when supported, are returned in the same response with `expires_in` omitted and profile-defined rotation rules.

7. **Lifecycle and events.** How RFC 7009, SET / SSF / CAEP, OPC, and RFC 9470 handle revocation, events, lifecycle directives, and step-up.
    - Token revocation uses RFC 7009 at the standard `revocation_endpoint`.
    - OPC commands (Activate, Maintain, Suspend, Reactivate, Archive, Restore, Delete, Invalidate, Migrate) ride on the same trust anchor that validated the ID-JAG.
    - SET / SSF / CAEP carry cross-domain identity events.
    - RFC 9470 `insufficient_user_authentication` carries step-up challenges.

8. **Audit and abuse control.** How consent records, rate limits, security events, and conformance tests are represented.
    - Resource records the ID-JAG consent context (issuer, subject, `client_id`, granted scope, time, ID-JAG `jti`) for user review and independent revocation.
    - Rate limits at the token endpoint. Replay protection on the ID-JAG `jti`. Security events for first-use JIT provisioning.
    - The profile draft defines the conformance test matrix.

The deployment profile's contribution is the choreography: which metadata is read, how trust is established, how the client identity is bound, how the user or tenant relationship is linked, which consent record is created, which token exchange happens, and which lifecycle channels apply. New protocol surface should be limited to the parts existing OAuth and OpenID specs do not already cover, and it should have an obvious migration path into the relevant owning spec. `insufficient_identity_claims` belongs in ID-JAG. `untrusted_issuer` belongs in the companion trust-discovery draft. A setup endpoint, if needed, belongs in the profile, but it owns account and client establishment, not token issuance.

## The trusted-issuer-discovery dependency

The Trust requirement above depends on a discovery surface that does not exist yet.

When a Resource Authorization Server accepts ID-JAGs, it has chosen to trust some set of IdP issuers. There is no standardized way for a client to discover that set. The closest existing surface, [`draft-mcguinness-token-xchg-target-svc-disco`](https://datatracker.ietf.org/doc/draft-mcguinness-token-xchg-target-svc-disco/), defines the inverse direction: an IdP Authorization Server advertises which target services it can issue tokens for, via a new `token_exchange_target_service_discovery_endpoint` metadata field. That solves the IdP-to-client direction.

The symmetric inverse, a Resource Authorization Server publishing which ID-JAG issuers it trusts, is not yet defined. It is a generic ID-JAG ecosystem need. The same gap shows up in [MCP Enterprise Managed Authorization](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization), which currently defers to manual admin configuration because no published discovery mechanism exists for this direction. It also shows up in Identity Chaining and any cross-domain SSO-to-API deployment where a resource consumes assertions from multiple issuers.

The right standards move is a small companion spec defining the symmetric inverse, parallel in shape to the existing target-service-discovery draft. The known security and privacy considerations carry over: enumeration attacks, trust-relationship leakage, rate limiting, and TLS posture all need the same treatment the existing draft already applies. That work belongs in its own draft, not inside the Agent Onboarding Profile. Once the companion exists, the Agent Onboarding Profile reuses it.

# Why This Matters

Each custom protocol surface that ships into the agent ecosystem creates the same costs the OAuth ecosystem has spent fifteen years learning to avoid: a new validation path, a new error catalog, a new revocation surface, a new metadata vocabulary, and a new fork of integrator effort. Some temporary product glue is inevitable while the standards work matures. The risk is letting temporary glue become permanent protocol. Resource services that today need to implement OAuth metadata, dynamic client registration, JWT-bearer grants, SETs, and revocation should not also need to implement a parallel `agent_auth` vocabulary that does the same things by different names.

The pattern auth.md describes is real and important. One-click setup for agents acting on behalf of users against third-party services is going to be a defining shape of authorization over the next several years. The way to get there is not a parallel grant surface. It is to put the agent provider in the IdP Authorization Server role that ID-JAG already defines, discover the service through RFC 9728 and RFC 8414, establish or bind the OAuth client through existing client-registration machinery, and issue delegated access through the standard token endpoint. Then deliver events through SSF and CAEP, drive lifecycle through OPC on the same trust relationship, and profile the runtime onboarding step explicitly.

auth.md should become the agent-readable ceremony document. PRM and AS metadata should remain authoritative for endpoints. The Agent Onboarding Profile should define the ceremony. ID-JAG should carry the identity assertion. CIMD, DCR, federation, or client binding should establish the client. The token endpoint should issue delegated access. SSF, CAEP, RFC 7009, and OPC should handle events, revocation, and lifecycle.

The next step should be a profile draft for one-click agent onboarding, with auth.md, MCP authorization, ID-JAG, client-establishment mechanisms, OpenID Federation, SSF/CAEP, and OPC treated as inputs. The work is concrete: define the metadata fields, state machine, trust model, client-binding rules, consent record, audit events, and conformance tests that make one-click agent setup interoperable instead of bespoke. It should also be honest about sequencing: some of the inputs are drafts, one trust-discovery dependency is still missing, and early deployments will need transition behavior.

Write the Agent Onboarding Profile. Keep auth.md as the document. Keep OAuth as the protocol. Use the bridge, but keep shortening it.

