Embedded identity

Bind MCP authorization to a customer-verified end user without trusting agent-supplied identity.

An Embedded project keeps your application's users separate from Arc0 dashboard accounts. Your backend establishes the mapping after authenticating the person in your own product. An email match, agent argument, or account picker is not proof of that identity.

Server-side connection management

Keep management API keys on your server. Create a connection link with POST /v1/connect, connect permission, and the Arc0 endUserId resolved from your authenticated session. The returned ten-minute capability opens Arc0 Connect. The provider credential belongs to that user. This link is a connection setup capability, not a general management session or permission to browse other users' connections.

The linking contract connects a signed MCP OAuth request, an authenticated Arc0 browser session and your independently authenticated end user:

  1. In the Arc0 consent browser, POST /v1/mcp/link-requests on the core/auth base URL with the session cookie and { organizationId, projectId, oauth_query }. The unchanged oauth_query comes from the signed OAuth request. The result is { requestId, expiresIn: 300 }.
  2. Your backend authenticates the person in your application and resolves their Arc0 user ID. It calls POST /v1/mcp/authorization-tickets on the API base URL with a server-side management key carrying mcp:link, and { requestId, endUserId }. The result is { ticket, requestId, expiresIn: 300 }. Do not accept the end-user ID directly from the browser.
  3. After explicit confirmation in the same Arc0 browser session, call POST /v1/mcp/link-confirm on the core/auth base URL with { oauth_query, ticket, confirm: true }. The ticket is consumed once and returns the linked { organizationId, projectId, endUserId, bindingId }.
  4. The consent flow selects that linked context through POST /v1/mcp/authorize and completes the OAuth authorization. The resulting MCP token is bound to that subject; tool calls cannot replace it with an endUserId argument.

Browser requests require the session and trusted Origin. Preserve the signed OAuth query verbatim; do not reconstruct its client, redirect URI or PKCE parameters. Tickets expire with their request and are bound to the original browser session and OAuth request. Treat them as secrets, send them over HTTPS, and keep them out of logs.

The issuing key must remain enabled and owned by an authorized administrator. Arc0 rechecks that authority and the linked subject on subsequent access. Relinking a conflicting identity requires an explicit new authorization instead of silently changing an existing grant.

This is the implemented integration contract. A general hosted Embedded connection-management portal is separate work; these tickets do not grant such a session. Direct accounts use their own Arc0 identity and do not use Embedded linking tickets.

Runtime keys when OAuth is unavailable

Your backend can mint a short-lived, user-bound key with POST /v1/users/:endUserId/keys on the API base URL. Authenticate with a server-side Embedded management key carrying mcp:keys and every permission requested for the child. Resolve the end-user ID from your application's authenticated session.

{
  "name": "Headless agent",
  "permissions": ["execute"],
  "expiresIn": 3600
}

The response is { id, key, endUserId, expiresIn }; store the returned secret securely. Only execute and connect may be delegated. The lifetime is 60–86,400 seconds; the default is one hour. If permissions are omitted, both execute and connect are requested, so the parent must hold both. A child key cannot mint more keys or act as a management key.

Use the child key as x-api-key for MCP, or as a Bearer API key for REST. MCP tool use requires execute; hosted connection creation additionally requires connect. The subject is fixed, and the child stops working if the parent expires, is revoked, loses required permissions, or its owner loses administrative authority. Arc0 rechecks these conditions for subsequent requests and approval resumption. Keep the broad parent key on your server; give only the user-bound child key to the agent.

On this page