What is an Agent Account?
An Agent Account is a registered client application that can:- Authenticate programmatically using OAuth 2.0 client credentials
- Call MCP tools through the Runlayer proxy
- Act on behalf of users when delegated permissions
- Operate autonomously with its own policies
Token Types
Agent accounts can obtain two types of access tokens depending on their use case:M2M Token (Machine-to-Machine)
Use M2M tokens when your agent account operates autonomously without a specific user context.- Agent account operates independently
- Only agent account-level policies are enforced
- Ideal for background jobs, scheduled tasks, or autonomous AI agents
OBO Token (On-Behalf-Of)
Use OBO tokens when your agent account acts on behalf of a specific user.- Agent account operates in the context of a delegating user
- Intersection of agent account and user policies are enforced
- Requires an active delegation from the user to the agent account
- Ideal for user-facing AI assistants or copilots
How OBO Works
The complete On-Behalf-Of flow, end to end: a one-time delegation from the user, a two-step token flow (mint an agent token, then exchange it for an OBO token per RFC 8693), and a proxied MCP call that enforces both parties’ policies and resolves OAuth credentials through session grants. Each concept in the diagram is covered below: authentication, delegations, session grants, and policies. For copy-paste code, see the Agent Account Authentication Recipes.Authentication
Agent accounts authenticate using OAuth 2.0: the Client Credentials grant for M2M tokens, plus an RFC 8693 token exchange for OBO tokens. The token endpoint returns a JWT that you include in theAuthorization header of all API requests.
Getting an M2M Token
Getting an OBO Token
To get an OBO token, you need one of:- A user UUID from an active delegation
- A user email from an active delegation
- A WorkOS user access token (RFC 8693 compliant)
client_credentials (the same call as the M2M example above), then exchange it for an OBO token via RFC 8693 token exchange. The agent token is cacheable and can be reused across many user exchanges, and the client_secret never travels on the per-user exchange call.
subject_token form that matches what your system stores:
Scoping a token to specific servers (optional)
Pass one or more RFC 8707resource parameters (the MCP server URL) on the
client_credentials or token-exchange call to scope the minted token to those
servers. The server records the targets in the token’s aud claim:
The
aud claim is narrowed to the servers the principal can access.
Whether the proxy enforces it is controlled per agent account by the
Enforce token resource scoping setting — see
Resource Scoping Enforcement. Omitting
resource mints a token with no aud, accepted everywhere the principal’s
policies allow (unchanged behavior).Calling MCP Tools
Once authenticated, you can call MCP tools through the Runlayer proxy using your access token. The proxy exposes a standard MCP Streamable HTTP transport endpoint at/api/v1/proxy/{server_id}/mcp.
Resource Scoping Enforcement
Scoping a token records the target servers in the token’saud claim. Whether the proxy enforces that scope is a per–agent-account setting, Enforce token resource scoping, in Settings → Agent Accounts → (account) → Settings.
When enforcement is on, the proxy rejects an aud-bearing token used against a server outside its aud with 403 invalid_target. This confines a leaked or over-shared token to exactly the servers it was scoped to, below the account’s usual policy ceiling.
- Off by default — opt in per account. Enforcement is disabled until an admin turns it on for a specific agent account, so no account is forced to scope its tokens by an upgrade.
- When on,
resourceis required. The token endpoint rejects a token request that doesn’t name at least one server (invalid_target), so every token this account issues is scoped. (Per RFC 8707 §2, an authorization server may require resource indicators.) - Scope a token to every server it will call. A token scoped to server A cannot call server B, even if the account’s policies allow B.
- Aggregate endpoints reject scoped tokens. The agent-account aggregate MCP, plugin, and skill endpoints fan out beyond a single named server, so a scoped (
aud-bearing) token is rejected there.
3f6a2b1e-… (see the scoping example above):
403 response
resource fails at the token endpoint instead:
400 response
Delegations
Delegations allow users to grant agent accounts permission to act on their behalf. When a user creates a delegation to an agent account, the agent account can request OBO tokens for that user.Key Concepts
- Delegator: The user granting permission
- Delegatee: The agent account receiving permission
- Expiration: Delegations can have optional expiration times
- Revocation: Users can revoke delegations at any time
Delegation Flow
- User navigates to the agent account in the Runlayer UI
- User creates a delegation to the agent account
- Agent account exchanges its agent token for an OBO token scoped to the user
- Agent account calls MCP tools with the user’s permissions applied
Recovering from a denied OBO call
When an agent’s OBO token exchange is denied because the end-user has no active delegation (or any of the related recoverable failure reasons), the400 invalid_grant response carries an X-Runlayer-Connect-URL header pointing at the agent account’s recovery page:
- The agent forwards the URL from the header to the end-user it is acting on behalf of.
- The user opens the URL and signs in to Runlayer.
- The user clicks Connect on the agent account page. This creates the delegation and any required session grants for OAuth-protected servers in a single click.
- The agent retries the OBO token exchange — it now succeeds.
The body of the 400 response is unchanged across all denial reasons — the recovery hint is delivered exclusively through the response header. Agents that don’t yet inspect the header continue to work; they just fall back to surfacing the raw
detail message to the user.Session Grants
Session grants control how an agent account authenticates to OAuth-protected MCP servers. A session grant shares a user’s OAuth credentials for a specific server with an agent account, independent of delegations.Personal vs Shared
Credential Resolution
When an agent account makes an OBO call to an OAuth-protected server, Runlayer resolves credentials in this order:- Caller’s personal grant — if the OBO caller has their own session grant for this server, their OAuth credentials are used.
- Shared grant fallback — if no personal grant exists, a shared session grant (from any grantor) is used.
- Error — if neither exists, the call fails with a
401error.
Lifecycle
Session grants are created when:- A user connects to an OAuth connector attached to an agent
- An admin creates one through the Agent Accounts API
If the grantor’s OAuth session expires, calls relying on that session grant will fail until the grantor re-authorizes the server.
Example: Slack Agent with Multiple Users
Suppose you have an agent account called “Support Bot” that needs to call a Slack MCP server on behalf of users.- Alice connects to the agent and authorizes Slack. This creates a personal session grant for Alice.
- An admin promotes Alice’s grant to shared, so it can serve as a fallback for other users.
- Bob connects to the agent but does not authorize Slack — he has no personal grant.
- When Support Bot makes an OBO call to Slack as Alice, Runlayer uses Alice’s personal grant (her own OAuth credentials).
- When Support Bot makes an OBO call to Slack as Bob, Runlayer falls back to Alice’s shared grant (since Bob has no personal grant).
- If Alice later authorizes a second user Carol, and Carol creates her own personal grant, Carol’s OBO calls use her own credentials — Alice’s shared grant is not used.
Policies
Both agent accounts and users can have policies that control what actions they can perform. When an agent account uses an OBO token, the effective permissions are the intersection of:- The agent account’s policies
- The user’s policies
- Any server-level policies
Best Practices
Secure your client secret
Secure your client secret
Store your agent account’s client secret securely (e.g., environment variables, secrets manager). Never commit it to version control or expose it in client-side code.
Use OBO tokens when appropriate
Use OBO tokens when appropriate
If your agent account is acting on behalf of a specific user, always use OBO tokens rather than M2M tokens. This ensures proper audit trails and policy enforcement.
Handle token expiration
Handle token expiration
Access tokens are valid for 1 hour. Implement token refresh logic in your application to request new tokens before expiration.
Apply least privilege
Apply least privilege
Configure your agent account’s policies to only allow the minimum permissions required for its function. Avoid granting broad access.
Managing Agent Accounts
Agent accounts are managed through the Runlayer UI:- Navigate to Settings → Agent Accounts
- Create new agent accounts with the Add Agent Account button (admin-only)
- Configure agent account settings — including Enforce token resource scoping — policies, and delegations
- View agent account activity in the audit logs
All workspace members can view agent accounts, create delegations, and create session grants. Only administrators can create, edit, or delete agent accounts and rotate credentials.
Credential Rotation
Agent account credentials should be rotated periodically or after security events to maintain security.When to Rotate
- Scheduled rotation: Rotate credentials every 90 days as a best practice
- Security incident: Immediately rotate if credentials may have been exposed
- Personnel changes: Rotate when team members with access leave the organization
- Suspicious activity: Rotate if you detect unusual API usage patterns
How to Rotate
- Navigate to Settings → Agent Accounts
- Select the agent account to rotate
- Click Rotate Credentials
- Confirm the rotation
- Save the new client secret immediately (shown only once)
- Update your application with the new credentials
Agent accounts linked to an Agent cannot be rotated from the Agent Accounts page. The UI will direct you to the agent’s page instead, where you can rotate the credentials for the linked account.
Impact of Rotation
When you rotate credentials:- Old client secret is immediately invalidated - The agent account cannot authenticate with the old secret to obtain new tokens
- Existing tokens remain valid until expiry - Previously issued JWTs (both M2M and OBO) continue to work for up to 1 hour since they are stateless tokens
- Delegations remain intact - No need to recreate delegations
- Policies are unchanged - Access rules continue to apply
Error Handling
When authenticating or making API calls, you may encounter these common errors:Authentication Errors
OBO Token Exchange Errors
Proxy Call Errors
Example Error Responses
Agent account authentication and token exchange errors follow RFC 6749 §5.2: a JSON object witherror and error_description fields (a legacy detail field is also emitted for backward compatibility):
X-Runlayer-Connect-URL header: