Agent Auth plugin purpose and capabilities
The Agent Auth plugin lets your Better Auth server act as an Agent Auth provider, implementing the Agent Auth Protocol. It gives AI agents a standard way to discover your service, register themselves, request approval, and execute scoped capabilities using short-lived signed JWTs. It comes with adapters for OpenAPI and MCP.
Agent Auth features
The plugin provides: OpenAPI adapter to derive capabilities and schemas from OpenAPI 3.x specs; MCP adapter to expose agent auth as MCP tools; discovery document at /.well-known/agent-configuration; capability listing, description, and execution with optional per-capability location URLs; delegated and autonomous agent modes; device authorization and CIBA approval flows; short-lived signed JWTs with replay protection; audit/event hooks for approvals, grants, and execution.
Agent Auth plugin installation
Install @better-auth/agent-auth. Optional client and CLI packages: npm install @auth/agent @auth/agent-cli.
Agent Auth plugin basic configuration
Add agentAuth() to the plugins array in betterAuth config. Define capabilities with name, description, and optional input schema. Provide an onExecute handler that switches on capability name and returns the result. Set providerName and providerDescription. Set modes to array of 'delegated' and/or 'autonomous'.
Agent Auth discovery document exposure
Expose the discovery document from your app root at /.well-known/agent-configuration using auth.api.getAgentConfiguration(). The discovery route should live at /.well-known/agent-configuration even if your Better Auth base path is /api/auth.
Agent Auth database migration
Run npx auth migrate or npx auth generate to add the agent, host, grant, and approval tables required by Agent Auth.
Agent Auth client plugin setup
Add agentAuthClient() from @better-auth/agent-auth/client to the createAuthClient plugins array to get type-safe access to the plugin endpoints from a Better Auth client.
Agent Auth discovery flow
Agent Auth flow: (1) Agent discovers provider from /.well-known/agent-configuration; (2) Agent lists capabilities and decides what it needs; (3) Agent registers with server and requests capability grants; (4) User approves request through device authorization or CIBA; (5) Agent signs short-lived JWTs with aud matching the URL and invokes granted capabilities at default_location or at custom location if set.
Discovery document key fields
Discovery document includes: issuer (provider's base URL matching Better Auth baseURL); endpoints (absolute URLs for each route, e.g., execute points at POST /capability/execute); default_location (full URL of default execute endpoint, always matches endpoints.execute, agents use as JWT aud when capability doesn't define custom URL).
OpenAPI adapter createFromOpenAPI function
createFromOpenAPI reads an OpenAPI spec and produces: capabilities (one per operationId), input/output JSON Schemas, a proxy onExecute handler, and optionally providerName and providerDescription from info. Every operation with an operationId becomes a capability. Path, query, and header parameters plus JSON request body merge into single input schema. 200/201 response body becomes output.
OpenAPI adapter resolveHeaders for upstream authentication
Use resolveHeaders in createFromOpenAPI options to inject credentials each upstream API request needs. The function receives agentSession and should return headers object (e.g., containing Authorization header with Bearer token for internal service or user-scoped access token).
OpenAPI adapter defaultHostCapabilities option
defaultHostCapabilities controls which capabilities are auto-granted to new hosts. Can pass true (all), a single HTTP method string, an array of methods, or a callback that receives full runtime context.
OpenAPI adapter approvalStrength per HTTP method
Map HTTP methods to approvalStrength so mutating operations require stronger user verification. For example: GET: 'session', POST: 'webauthn', PUT: 'webauthn', DELETE: 'webauthn'.
OpenAPI adapter per-capability location option
When location is set in createFromOpenAPI, every derived capability gets that URL. Agents call it directly with agent JWT instead of going through default execute endpoint. Useful when you want agent to hit real API URL and handle session in own middleware.
OpenAPI adapter lower-level helpers
The adapter exports: fromOpenAPI(spec) returns Capability[] only (no handler, no host caps); createOpenAPIHandler(spec, opts) returns only onExecute proxy handler to pair with hand-written capabilities or filtered spec.
Capability definition structure
Each capability has: name (string, becomes operationId for OpenAPI), description (string), optional input (JSON Schema), optional location (absolute URL agents call instead of default_location). By default agents call default_location and plugin runs onExecute. If location set, agents call that URL and onExecute is not used.
Default execute vs custom capability location behavior
No location: Agents POST to default_location (endpoints.execute) with { capability, arguments }. Plugin validates JWT and grant, then runs onExecute. With location: Agents call that URL. onExecute does not run. Resolve agentSession in handler using helpers, enforce grants and business logic yourself.
Getting agent session outside onExecute
For custom location routes, use auth.api.getAgentSession({ headers }) which runs JWT verification in-process and returns AgentSession or null. Alternatively use verifyAgentRequest(request, auth) which forwards Request headers to GET /agent/session via auth.handler. Both validate signature, aud, replay (jti), expiry, and request-binding claims.
Checking grants for custom location handlers
After getting agentSession, inspect agentSession.agent.capabilityGrants which are active DB grants intersected with JWT capabilities claim. Ensure matching active grant exists: agentSession.agent.capabilityGrants.some(g => g.capability === CAPABILITY_NAME && g.status === 'active'). If grant has constraints, validate request body same way execute would.
Agent session object structure
AgentSession contains: agentSession.user (resolved user for agent - delegated host user or resolveAutonomousUser result); agentSession.agent (id, name, mode, capabilityGrants, host id, metadata); agentSession.host (host record when agent linked to host). Types exported from @better-auth/agent-auth.
JWT audience (aud) validation rules
JWT aud must match server expectations: No per-capability location: Use default_location, endpoints.execute, issuer/base URL. With location: aud should be that absolute URL. GET /capability/list includes location when set. Single capability in JWT: aud may equal that capability's location when set. Multiple capabilities in JWT: per-capability locations not accepted as aud, use issuer, base path, or default execute endpoint. Invalid location values fail at startup. Behind reverse proxy, set trustProxy if Host/X-Forwarded-Proto needed for aud validation.
resolveCapabilities function
Use resolveCapabilities to show different capability sets to different callers, such as plan-gated, user-specific, or organization-specific capabilities.
onExecute handler behavior
onExecute runs for capabilities using default execute URL (no per-capability location). Plugin verifies JWT including aud, attaches agentSession, checks grant, then calls onExecute. Capabilities with custom location never hit this path - you handle them in own route using session helpers. Function receives { capability, arguments: args, agentSession } parameters.
Agent Auth approval flows
Plugin supports two approval methods: device_authorization for browser-based approval with user code; ciba for backchannel approval flows. Both enabled by default. Can restrict with approvalMethods and customize with resolveApprovalMethod callback.
Device authorization page configuration
Set deviceAuthorizationPage to path or absolute URL for user-facing device approval page. Plugin does not render device approval UI - your app must provide the page referenced by this option.
onEvent hook for auditing
Use onEvent callback to capture important lifecycle events: agent creation and revocation, host creation and enrollment, capability requests and approvals, capability execution. Good place to write audit logs or feed analytics pipelines.
Agent Auth configuration options
Configuration options: providerName (string, human-readable name in discovery metadata); providerDescription (string, returned in discovery document); modes (array of 'delegated' and/or 'autonomous', defaults to both); capabilities (array of capability definitions); onExecute (handler function for default execute URL); requireAuthForCapabilities (boolean, require host or agent JWT to list/describe capabilities); approvalMethods (array of 'ciba' and/or 'device_authorization', defaults to both); resolveApprovalMethod (function to choose approval method); deviceAuthorizationPage (path or absolute URL for approval page); defaultHostCapabilities (string array or function for auto-granted host capabilities); allowDynamicHostRegistration (boolean or function to allow unknown host registration); onEvent (callback for audit events); trustProxy (boolean, trust X-Forwarded-Proto for aud validation, defaults to false).