Discovery and registration
Protected Resource Metadata, OAuth discovery, Dynamic Client Registration and the authorization endpoint.
Checked against the Evaluation environment, Console 0.10.1 / 0.14.1, on October 19, 2026. Release status
An agent needs nothing but the MCP or UCP service URL to start. It calls the service, gets a 401 that points to Protected Resource Metadata, reads the AIGW authorization server from it, discovers the endpoints, registers itself, and sends the user to authorize. This page documents each of those calls. Read endpoints from discovery instead of hard-coding them.
Endpoints at a glance
| Method | URL | Purpose |
|---|---|---|
| GET | <your service>/.well-known/oauth-protected-resource | Protected Resource Metadata (RFC 9728), served by the MCP or UCP service |
| GET | https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/.well-known/openid-configuration | OIDC discovery |
| GET | https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/.well-known/oauth-authorization-server | OAuth AS metadata (RFC 8414) |
| GET | https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/.well-known/jwks.json | Resource signing keys (merchant-facing) |
| POST | https://api.aigw.eval.loginid.ai/api/register | Dynamic Client Registration (RFC 7591) |
| GET | https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/oauth2/auth | Authorization endpoint, per Resource |
| POST | https://core.api.aigw.eval.loginid.ai/oauth2/token | Token endpoint, core. See Token endpoint. |
Protected Resource Metadata
Supported Protected Resource Metadata (RFC 9728) tells an agent which authorization server protects your MCP or UCP endpoint. Your service publishes it, not AIGW.
The 401 challenge
When a request arrives without a valid token, your service responds with a pointer to the metadata:
HTTP/1.1 401 UnauthorizedWWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"Metadata document
curl -s "https://mcp.example.com/.well-known/oauth-protected-resource"{ "resource": "https://mcp.example.com", "authorization_servers": [ "https://api.aigw.eval.loginid.ai/<RESOURCE_ID>" ]}Fields
resourcestringRequired- Your MCP or UCP service identifier.
authorization_serversstring[]Required- The AIGW per-resource issuer,
https://api.aigw.eval.loginid.ai/<RESOURCE_ID>. Agents use it to find AIGW discovery.
The Token exchange Resource's Reference step in the Console has a Download oauth-protected-resource.json button for this file. Keep the document public and free of secrets.
Authorization server metadata
Supported Each Resource publishes discovery at both the OIDC path and the RFC 8414 path on the same per-resource base.
curl -s "https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/.well-known/openid-configuration"{ "issuer": "https://core.api.aigw.eval.loginid.ai/", "authorization_endpoint": "https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/oauth2/auth", "token_endpoint": "https://core.api.aigw.eval.loginid.ai/oauth2/token", "jwks_uri": "https://core.api.aigw.eval.loginid.ai/.well-known/jwks.json", "registration_endpoint": "<AIGW registration endpoint>", "scopes_supported": ["openid", "search:read"], "code_challenge_methods_supported": ["S256", "plain"]}Fields to read
| Field | What it contains |
|---|---|
issuer | The core AIGW issuer, not the per-resource URL. |
authorization_endpoint | The per-resource /oauth2/auth URL. |
token_endpoint | The core /oauth2/token URL. |
jwks_uri | The core JWKS for agent-facing AIGW tokens. |
registration_endpoint | The AIGW DCR endpoint. |
scopes_supported | Standard scopes plus the Resource's own scopes, such as search:read. |
code_challenge_methods_supported | Includes S256 and plain. Always use S256. |
token_endpoint_auth_methods_supported | Lists client_secret_post, client_secret_basic, private_key_jwt and none. Send client_secret_post; client_secret_basic is Unsupported in this release. |
grant_types_supported | authorization_code, implicit, client_credentials, refresh_token and device code. |
| Other core endpoints | revocation_endpoint, userinfo_endpoint, end_session_endpoint and device_authorization_endpoint point to the core host. |
Two hosts, on purpose
Authorization is per Resource on https://api.aigw.eval.loginid.ai; token issuance is on the core host https://core.api.aigw.eval.loginid.ai. Don't derive one from the other. Read both from discovery.
JWKS
AIGW has two key sets. Use the one that matches the token you are verifying.
| Key set | URL | Signs |
|---|---|---|
| Core | https://core.api.aigw.eval.loginid.ai/.well-known/jwks.json | Agent-facing AIGW access tokens. This is the discovery jwks_uri. RS256 was observed. |
| Per-resource | https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/.well-known/jwks.json | ES256 user and client assertions AIGW sends to the merchant authorization server. |
The per-resource JWKS can hold older keys alongside the active one during rotation. Select by kid and refetch when you see an unknown kid.
Dynamic Client Registration
Supported RFC 7591 registration gives an agent its own OAuth client at runtime. Registration is global: an agent registers once and can then reach any AIGW-protected merchant, with each Project's Agent policy applied on first contact.
curl -s -X POST "https://api.aigw.eval.loginid.ai/api/register" \ -H "Content-Type: application/json" \ -d '{ "client_name": "My agent", "redirect_uris": ["https://agent.example.com/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "client_secret_post" }'Request body
client_namestring- A name for your agent, such as
My agent. redirect_urisstring[]Required- Absolute HTTPS callback URLs. Non-HTTPS URIs are rejected.
grant_typesstring[]["authorization_code", "refresh_token"]. Refresh is Unverified.response_typesstring[]["code"]token_endpoint_auth_methodstringclient_secret_post.client_secret_basicis Unsupported.scopestring- Do not send. A single scope AIGW can't register makes it reject the whole request. Request scopes at the authorization endpoint instead.
Which of these fields AIGW strictly requires is not documented for this release, apart from HTTPS redirect URIs. Send all five as shown; the Playground uses exactly this body.
Response
{ "client_id": "<client_id>", "client_secret": "<client_secret>", "client_secret_expires_at": 0, "verification_method": "none"}A successful registration returns 201 with:
client_idandclient_secret;client_secret_expires_at: 0, so treat the secret as long-lived;- a default granted scope string;
- redirect domain information;
verification_method,"none"for a plain registration;- the core AIGW issuer and endpoints.
The exact field names for the scope, domain and endpoint values are not documented for this release, so the example shows only confirmed fields.
Ignore the authorization endpoint in the DCR response
The DCR response returns a core authorization endpoint, but the Resource flow uses the per-resource /oauth2/auth. Use the authorization server you discovered from Protected Resource Metadata.
Errors
| Cause | Result |
|---|---|
| A redirect URI is not absolute HTTPS | Registration is rejected. |
The body includes a scope AIGW can't register | The whole registration is rejected. |
The HTTP status and error body for these failures are not documented for this release. The standard RFC 7591 error format, a JSON body with error and error_description, may apply but is Unverified.
Authorization endpoint
Supported Authorization Code with PKCE (S256) against the per-resource endpoint. Open this URL in the user's browser:
GET https://api.aigw.eval.loginid.ai/<RESOURCE_ID>/oauth2/auth ?response_type=code &client_id=<AGENT_CLIENT_ID> &redirect_uri=https://agent.example.com/callback &scope=openid%20search:read &state=<STATE> &code_challenge=<CODE_CHALLENGE> &code_challenge_method=S256Query parameters
response_typestringRequiredcodeclient_idstringRequired- The client ID from registration.
redirect_uristringRequired- One of the HTTPS URIs you registered.
scopestringRequired- Space-delimited, URL-encoded.
openidplus the Resource scopes you need, such asopenid%20search:read. Request the minimum. statestringRequired- A random value tied to this transaction. Check it on the callback.
code_challengestringRequiredBASE64URL(SHA256(code_verifier)). Keep the verifier for the token exchange.code_challenge_methodstringRequiredS256. Don't useplain, even though discovery lists it.
The user signs in with an identity provider enabled on the Resource, sees the consent screen with the Resource's scope descriptions, and approves or denies.
Successful redirect
On approval, AIGW redirects to your registered callback with a code and your state:
https://agent.example.com/callback?code=<AUTHORIZATION_CODE>&state=<STATE>Reject the response if state doesn't match, then exchange the code at the token endpoint.
Error redirect
Authorization can fail even with a well-formed request. These controls can stop it:
- the agent is Pending, Rejected or Revoked under the Project's Agent policy;
- a requested scope is not configured on the Resource;
- the identity providers enabled on the Resource;
- the user fails to authenticate or denies consent.
AIGW's error response for these cases is not documented for this release. RFC 6749 defines an error redirect to your callback with error, error_description and state, which may apply but is Unverified:
https://agent.example.com/callback?error=<error>&error_description=<text>&state=<STATE>If authorization fails right after a successful registration, check the agent's status in the Console under Agents before you debug PKCE or sign-in.
Release status
| Capability | Status |
|---|---|
| Protected Resource Metadata and discovery | Supported |
| Dynamic Client Registration | Supported |
| Authorization Code with PKCE | Supported |
| Refresh tokens | Unverified |
| Web Bot Auth agent proof | Unverified |
client_secret_basic | Unsupported |
| DCR and authorization error bodies | Unverified |

