new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Better Auth · Plugins · all subjects

agent-auth/capabilities

10 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Capability definition structure

Each capability has: name (string, required), description (string, required), input (optional JSON Schema), location (optional absolute URL for agents to call this capability directly instead of default execute URL).

Default execute vs custom 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 (REST handler, another service, etc.). onExecute does not run for that call. Resolve agentSession in handler using helpers, then enforce grants and business logic.

getAgentSession - resolving agent session outside onExecute

For custom location routes, agents send Authorization: Bearer header with agent JWT. Use auth.api.getAgentSession({ headers }) to run verification in-process and get AgentSession or null. Verification includes signature, aud, replay (jti), expiry, and request-binding claims.

verifyAgentRequest helper function

Alternative to getAgentSession: verifyAgentRequest(request, auth) does same verification by forwarding Request headers to GET /agent/session via auth.handler. Use whichever fits your code shape.

Checking grants in agent session

After getting agentSession, inspect agentSession.agent.capabilityGrants. These are active DB grants intersected with JWT capabilities claim. For the capability, ensure matching grant exists: const allowed = agentSession.agent.capabilityGrants.some((g) => g.capability === CAP && g.status === 'active')

Agent session grant constraints validation

If a grant has constraints, validate request body or query in custom location handler the same way /capability/execute would. Plugin does not re-run execute constraint helpers on arbitrary routes; logic stays in handler or call shared code extracted from onExecute path.

AgentSession object contents

agentSession contains: user (resolved user for agent, delegated host user or resolveAutonomousUser); agent (id, name, mode, capabilityGrants, host id, metadata); host (host record when agent is linked to host). Types exported from @better-auth/agent-auth.

JWT audience (aud) validation rules

JWT aud must match server expectation for URL being called. No per-capability location: use default_location or endpoints.execute or issuer/base URL values plugin allows. With location: aud should be that absolute URL. GET /capability/list includes location when set. Single capability in JWT: aud may equal that capability location. Multiple capabilities in JWT: per-capability location values not accepted as aud; use issuer, base path, or default execute instead. Behind reverse proxy: set trustProxy if Host/X-Forwarded-Proto need to line up with aud validation.

resolveCapabilities for filtered capability sets

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. Receives: capability (string), arguments (args object), agentSession (with user, agent, host info). Return value is sent to agent.

Give your agent this brain