OIDC endpoints

AgentKeychain conforms to OIDC discovery. If your auth library supports a discovery URL, this is the only thing you need to configure.

Discovery

GET https://agentkeychain.com/.well-known/openid-configuration

Example response:

{
  "issuer": "https://agentkeychain.com",
  "authorization_endpoint": "https://agentkeychain.com/authorize",
  "token_endpoint":         "https://api.agentkeychain.com/v1/token",
  "userinfo_endpoint":      "https://api.agentkeychain.com/v1/userinfo",
  "introspection_endpoint": "https://api.agentkeychain.com/v1/token/introspect",
  "jwks_uri":               "https://agentkeychain.com/.well-known/jwks.json",
  "registration_endpoint":  "https://api.agentkeychain.com/v1/clients/register",

  "scopes_supported":             ["openid", "profile", "agent_identity"],
  "response_types_supported":     ["code"],
  "grant_types_supported":        ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "subject_types_supported":      ["pairwise"],
  "id_token_signing_alg_values_supported": ["ES256"],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic", "client_secret_post"
  ]
}

Endpoints

EndpointPurpose
GET /authorizeAuthorization Code + PKCE entry point. The agent authenticates here; the browser is redirected back to your redirect_uri with a code.
POST /v1/tokenExchange an authorization code for an access token, refresh token, and signed ID token. Also handles refresh grants.
GET /v1/userinfoReturns the same claims as the ID token, in JSON form, for libraries that prefer userinfo to JWT parsing.
GET /.well-known/jwks.jsonES256 public keys for verifying ID token signatures. Cache for up to 24 hours.
POST /v1/token/introspectCheck whether a previously issued token is still active. Revoked tokens return active: false.

Authorization request

A standard OIDC authorization request. Your library builds this automatically — included here for reference.

GET https://agentkeychain.com/authorize?
  response_type=code&
  client_id=akc_client_wiki123&
  redirect_uri=https://yourapp.com/api/auth/callback/agentkeychain&
  scope=openid+profile&
  state=s-abc...&
  nonce=n-xyz...&
  code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
  code_challenge_method=S256

Token exchange

POST https://api.agentkeychain.com/v1/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=authorization_code&
code=<auth_code>&
redirect_uri=https://yourapp.com/api/auth/callback/agentkeychain&
code_verifier=<pkce_verifier>

Response:

{
  "access_token":  "at_...",
  "refresh_token": "rt_...",
  "id_token":      "<signed JWT>",
  "token_type":    "Bearer",
  "expires_in":    3600,
  "scope":         "openid profile"
}

The scope field echoes the scopes actually granted, which may be narrower than what you requested if the owner’s permission settings restrict them.

Branded button (optional)

If you’re letting your auth library drive the flow, you can still render the official “Sign in with AgentKeychain” button by importing it from @agentkeychain/web/react and passing an onClick handler that triggers your library’s sign-in. No client prop needed.

import { AgentKeychainButton } from "@agentkeychain/web/react";
import { signIn } from "next-auth/react";

export function LoginButton() {
  return (
    <AgentKeychainButton
      onClick={() => signIn("agentkeychain")}
    />
  );
}

The same works with Auth0, Clerk, WorkOS, or any library that exposes a sign-in function — wire it into onClick. The button handles branding; your library handles the protocol.

Verifying the ID token. AgentKeychain signs ID tokens with ES256. Any OIDC library will handle this for you via the JWKS endpoint. If you’re doing it by hand, fetch /.well-known/jwks.json, find the key matching the JWT’s kid, and verify the ES256 signature.
Next: ID token claims →