Scoping access per user
Agent Handler has two kinds of credential, and the difference between them is usually the first thing a security review asks about.
Your production Access Key is organization-wide. It reaches every Tool Pack and every Registered User you own. That is the right credential for your backend to hold and the wrong one for an agent session to carry. A user-scoped Access Key is minted from it, names one Registered User, and cannot call tools as anyone else.
Reach for this page when your agent serves more than one person, when a downstream service needs its own credential, or when someone asks you to prove that one customer’s agent cannot read another customer’s data.
The exchange
Your backend authenticates once with the organization-wide key, then hands the agent a narrower one. Three steps.
1. Hold the production key in your backend. It lives in your secret store and never reaches the agent, the browser, or a log line. See Access Keys for storage and rotation.
2. Mint a user-scoped key when a session starts. Name the Registered User the session belongs to, the Tool Packs it should reach, and a short expiry:
key is returned once, on this response. After that only key_masked is readable, so pass it to the agent now or mint a new one.
3. Call MCP with the scoped key. The agent carries it in the Authorization header for the life of the session. Nothing else about the MCP call changes.
What the scoped key cannot do
Two independent boundaries, enforced server-side on every request.
registered_user_ids is checked on every tool call, against the key rather than against the URL. The MCP endpoint carries a Registered User ID in its path:
Editing that segment to a Registered User the key does not name fails the call with 404, carrying Resource not in API key scope. It does not return the other user’s data, and it does not fall back to the key’s own user. Whoever holds a user-scoped key holds access to exactly the users named on it, so the path segment is a selector within the key’s grant, never a way to widen it.
The status is 404 rather than 403 on purpose: an out-of-scope Registered User is reported the same way as one that does not exist, so a key cannot be used to enumerate what you own. Expect the same on a Tool Pack the key does not name, and on search_tools as well as tools/call.
Scopes are the reason to mint keys through the API rather than restrict them in the dashboard. The dashboard restricts Tool Packs and Registered Users but does not let you choose scopes, so a key restricted there still reaches the management endpoints. POST /api/v1/access-keys/ lets you pass ["runtime:all"] and leave management:all off, which is what makes a session key unable to read or change configuration at all.
Narrower only, never wider
A key minted through the API can only be narrower than the key that minted it. tool_pack_ids, registered_user_ids, scopes, and the expiry each have to be a subset of the calling key’s own grant. A key scoped to one Registered User cannot mint a key that reaches a second one, so a leaked session key cannot be escalated into a broader one.
Omitting a field is not the same as passing null. null means unrestricted on that dimension, and it is only accepted when the calling key is itself unrestricted there. Name the users and packs explicitly on any key an agent will hold.
Expiry
expires_in takes seconds and expires_at takes a timestamp. Omit both and the key expires in 90 days, which is far longer than a session needs. Match the expiry to the session: an hour is a reasonable default, and a short-lived key limits how long a leaked value is worth anything.
The expiry is also part of the subset rule, so a one-hour session key cannot rotate or revoke your never-expiring production key. See which keys a key can rotate or revoke.
Auditing it
Every tool call a scoped key makes is attributed to its Registered User in Tool Call Logs, searchable by origin_user_id. Key creation, regeneration, and revocation land in the Audit Trail, and a rotation entry names both the acting key and the target key, so you can read a chain without correlating requests by hand.
Next
Rotation, storage, and the dashboard workflow live on Access Keys.