Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.runlayer.com/llms.txt

Use this file to discover all available pages before exploring further.

Beta Feature - Agent Accounts is currently in beta and requires access approval.
Agent Accounts in Runlayer represent AI applications or services that interact with MCP servers on behalf of users or autonomously. They are the primary way to programmatically connect your AI applications to the Runlayer platform.

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
Each agent account receives a unique Client ID and Client Secret upon creation, which are used to authenticate API requests.

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

Authentication

Agent accounts authenticate using the OAuth 2.0 Client Credentials flow. The token endpoint returns a JWT that you include in the Authorization header of all API requests.

Getting an M2M Token

# Get M2M token (agent-only, no user context)

TOKEN_RESPONSE=$(curl -s -X POST 'https://your-runlayer-instance.com/api/v1/oauth/token' \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=your-client-id" \
  --data-urlencode "client_secret=your-client-secret")

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

echo "M2M Token: ${ACCESS_TOKEN:0:50}..."
# Token valid for 1 hour

Getting an OBO Token

To get an OBO token, you need one of:
  1. A user UUID from an active delegation (simplified flow)
  2. A user email from an active delegation (simplified flow)
  3. A WorkOS user access token (RFC 8693 compliant)
# Get OBO token (agent acting on behalf of a user)

# Option 1: Simplified with user UUID (recommended if you have delegation)
USER_ID="user-uuid-from-delegation"

TOKEN_RESPONSE=$(curl -s -X POST 'https://your-runlayer-instance.com/api/v1/oauth/token' \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=your-client-id" \
  --data-urlencode "client_secret=your-client-secret" \
  --data-urlencode "actor_token=$USER_ID" \
  --data-urlencode "actor_token_type=urn:runlayer:token-type:user-id")

# Option 2: Simplified with user email (use if UUID isn't readily available)
# USER_EMAIL="user@example.com"
# TOKEN_RESPONSE=$(curl -s -X POST 'https://your-runlayer-instance.com/api/v1/oauth/token' \
#   -H "Content-Type: application/x-www-form-urlencoded" \
#   --data-urlencode "grant_type=client_credentials" \
#   --data-urlencode "client_id=your-client-id" \
#   --data-urlencode "client_secret=your-client-secret" \
#   --data-urlencode "actor_token=$USER_EMAIL" \
#   --data-urlencode "actor_token_type=urn:runlayer:token-type:user-email")

# Option 3: With WorkOS user access token (RFC 8693 compliant)
# USER_ACCESS_TOKEN="user-workos-access-token"
# TOKEN_RESPONSE=$(curl -s -X POST 'https://your-runlayer-instance.com/api/v1/oauth/token' \
#   -H "Content-Type: application/x-www-form-urlencoded" \
#   --data-urlencode "grant_type=client_credentials" \
#   --data-urlencode "client_id=your-client-id" \
#   --data-urlencode "client_secret=your-client-secret" \
#   --data-urlencode "actor_token=$USER_ACCESS_TOKEN" \
#   --data-urlencode "actor_token_type=urn:ietf:params:oauth:token-type:access_token")

OBO_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

echo "OBO Token: ${OBO_TOKEN:0:50}..."
# Agent now acts with intersection of agent + user policies

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.
# Call MCP tool through the Runlayer proxy
# Use $ACCESS_TOKEN (M2M) or $OBO_TOKEN

curl -X POST "https://your-runlayer-instance.com/api/v1/proxy/your-server-id/mcp" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_context",
      "arguments": {
        "query": "project structure"
      }
    },
    "id": 1
  }'
The proxy endpoint uses the MCP Streamable HTTP transport. You can also use any MCP SDK client (such as the Vercel AI SDK, OpenAI Agents SDK, or Google ADK) pointed at the https://your-runlayer-instance.com/api/v1/proxy/{server_id}/mcp URL.

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

  1. User navigates to the agent account in the Runlayer UI
  2. User creates a delegation to the agent account
  3. Agent account requests an OBO token using the user’s ID
  4. Agent account calls MCP tools with the user’s permissions applied
Delegations control who the agent account can act as. For OAuth-protected servers, the agent account also needs a session grant to determine whose credentials to use (see below).

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), the 401 response carries an X-Runlayer-Connect-URL header pointing at the agent account’s recovery page:
X-Runlayer-Connect-URL: https://your-runlayer-instance.com/agent-accounts/<agent-account-id>
Recommended flow:
  1. The agent forwards the URL from the header to the end-user it is acting on behalf of.
  2. The user opens the URL and signs in to Runlayer.
  3. 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.
  4. The agent retries the OBO token exchange — it now succeeds.
The header is only set when the failure is recoverable by the end-user. Agent-side failures (disabled agent account, missing/invalid client credentials, bad agent JWT) deliberately omit the header so callers cannot probe for the existence of agent accounts they do not control.
The body of the 401 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

TypeWho can use itLimit
PersonalOnly the grantor’s own OBO calls use these credentialsOne per (grantor, agent account, server)
SharedAny user’s OBO calls on this agent account can fall back to these credentialsOne per (agent account, server)

Credential Resolution

When an agent account makes an OBO call to an OAuth-protected server, Runlayer resolves credentials in this order:
  1. Caller’s personal grant — if the OBO caller has their own session grant for this server, their OAuth credentials are used.
  2. Shared grant fallback — if no personal grant exists, a shared session grant (from any grantor) is used.
  3. Error — if neither exists, the call fails with a 401 error.

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
Revoking a delegation through the Admin panel does not revoke session grants, and revoking a session grant does not revoke delegations. However, disconnecting from an agent (removing your connection) revokes both your delegation and your session grants for that agent. Additionally, when an admin deactivates a user, the user can no longer obtain new OBO tokens, effectively rendering their session grants unusable — though the grants themselves are not explicitly deleted from the system.
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.
  1. Alice connects to the agent and authorizes Slack. This creates a personal session grant for Alice.
  2. An admin promotes Alice’s grant to shared, so it can serve as a fallback for other users.
  3. Bob connects to the agent but does not authorize Slack — he has no personal grant.
  4. When Support Bot makes an OBO call to Slack as Alice, Runlayer uses Alice’s personal grant (her own OAuth credentials).
  5. 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).
  6. 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
This ensures that an agent account acting on behalf of a user can never exceed either party’s permissions.

Best Practices

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.
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.
Access tokens are valid for 1 hour. Implement token refresh logic in your application to request new tokens before expiration.
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:
  1. Navigate to Agent Accounts in the sidebar
  2. Create new agent accounts with the Add Agent Account button (admin-only)
  3. Configure agent account settings, policies, and delegations
  4. 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

  1. Navigate to Admin → Agent Accounts
  2. Select the agent account to rotate
  3. Click Rotate Credentials
  4. Confirm the rotation
  5. Save the new client secret immediately (shown only once)
  6. Update your application with the new credentials

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
After rotating credentials, existing access tokens remain valid for up to 1 hour. If you need to fully block access immediately, consider disabling the agent account temporarily in addition to rotating credentials. Update your application with the new client secret promptly, as no new tokens can be obtained with the old secret.

Error Handling

When authenticating or making API calls, you may encounter these common errors:

Authentication Errors

Error CodeErrorCauseRemediation
400unsupported_grant_typeWrong grant type usedUse client_credentials for agent account tokens
401invalid_clientInvalid client ID or secretVerify credentials are correct and not rotated
401invalid_grantInvalid or expired tokenRe-authenticate to get a new token
401invalid_grantUser deactivated, not found, or no delegationVerify the user exists, is active, and has delegated to the agent

OBO Token Exchange Errors

Error CodeErrorCauseRemediation
400invalid_requestInvalid actor_token formatUse valid user UUID, user email, or WorkOS token
401invalid_grantUser not found, inactive, or no delegationSend the user to the X-Runlayer-Connect-URL recovery page (see Recovering from a denied OBO call)
401invalid_grantAgent account disabledContact admin to re-enable agent account

Proxy Call Errors

Error CodeErrorCauseRemediation
401No credentials available for this server. A session grant is required.No session grant exists for this agent account and serverCreate a session grant by granting access on the connector
401OAuth session not foundGrantor’s OAuth session missingGrantor needs to re-authorize the MCP server
401OAuth session expiredGrantor’s OAuth session expiredGrantor needs to re-authorize the MCP server
403Policy deniedPBAC policy blocked the requestReview agent account and user policies

Example Error Responses

Agent account authentication and token exchange errors return a JSON object with a detail field:
{
  "detail": "invalid_grant: actor token exchange denied"
}
When the denial can be recovered by the end-user (missing delegation, user not found / inactive, malformed actor token), the same response also carries an X-Runlayer-Connect-URL header:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
X-Runlayer-Connect-URL: https://your-runlayer-instance.com/agent-accounts/<agent-account-id>

{"detail":"invalid_grant: actor token exchange denied"}
Check the detail field for specific guidance on how to resolve the error. When X-Runlayer-Connect-URL is present, forward that URL to the end-user — clicking through and signing in lets them grant the missing delegation in one step. See Recovering from a denied OBO call.