CertSafari
    Anthropic Claude Certified Architect – Professional (CCAR-P)· Lessons

    Domain 3 · Lesson 13/38

    Finding MCP Authorization Gaps: Scopes, Per-User Credentials and Server Policy

    Analyze authentication and authorization requirements to identify security gaps

    12 min read
    2.38% of exam
    5 sources
    Published 4 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Tell a 401 from a 403 insufficient_scope challenge and re-authorize without dropping permissions the client already has
    • Find credential-handling gaps in per-user vaults, such as silent unauthenticated fallback and failed refreshes
    • Choose allowlist and denylist settings that actually limit which MCP servers and tools an agent can reach

    1.Scopes: 401 versus 403 and step-up authorization

    Authentication asks who the caller is. Authorization asks what that caller may do. MCP keeps the two failures apart with different status codes, and treating them as the same thing is a common design gap. A 401 means the client needs authorization or its token is invalid. A 403 means the token is valid but lacks the needed scopes or permissions.

    How an MCP server signals each authorization failure
    StatusMeaningClient response
    401 UnauthorizedAuthorization required or token invalidDiscover the authorization server via resource_metadata; request the scope from the WWW-Authenticate header, or scopes_supported if absent
    403 ForbiddenInvalid scopes or insufficient permissionsRead error="insufficient_scope" and the scope parameter, then re-authorize
    400 Bad RequestMalformed authorization requestFix the request

    Asking for scopes only when they are needed is how least privilege plays out at runtime. On the first request, the client asks for the scope named in the 401 challenge. Only if that is missing does it fall back to everything in scopes_supported. Later, when an operation needs more, the server returns 403 with error="insufficient_scope", the required scope, and the resource_metadata URL.

    The client then has to re-authorize carefully. The 2026-07-28 spec makes this the client's job: it requests the union of the scopes it asked for before and the scopes in the new challenge. The earlier 2025-11-25 spec put more weight on the server's challenge, advising servers to include any existing granted scopes that are still required alongside the newly required ones. Either way, a token requested with only the new scope could lose permissions the client already had, and the next operation would fail.

    The retry limit matters too. The client retries the original request with the new authorization no more than a few times, then treats the failure as permanent, so it does not loop forever on a scope it will never get.

    Checkpoint 1 of 8· Put it in order

    Put the client's response to a 403 insufficient_scope challenge in order

    1. 1.Determine required scopes as the union of previously requested and newly challenged scopes
    2. 2.Initiate re-authorization with that scope set
    3. 3.Parse error information from the WWW-Authenticate header
    4. 4.Retry the original request no more than a few times

    Checkpoint 2 of 8· Exam question

    A security architect is designing an Agent SDK deployment that will process untrusted third-party documents and must prevent credential exfiltration even if a prompt injection convinces the agent to try to send data to an attacker-controlled endpoint. Which combination of controls together address this threat, given that TLS-encrypted traffic through a plain forward proxy cannot be inspected or have credentials injected into it? (Select 3)(Select 3)

    Sources12

    2.Per-user credentials: who the agent acts as

    An agent that serves many users needs to act as each of them, not as one shared identity. Claude Managed Agents handles this with vaults. A vault holds one end user's credentials and is attached to a session. Credentials come in two kinds. MCP credentials (mcp_oauth or static_bearer) are keyed by mcp_server_url and injected automatically when the agent connects to that URL. Environment-variable credentials are kept in the sandbox as placeholders and swapped for the real secret only when a request leaves the sandbox, so the agent never sees the secret. Secret values are write-only and never come back in API responses. If you supply a refresh block, Anthropic refreshes the OAuth access token for you.

    Checkpoint 3 of 8· Fill the gap

    Which parameter attaches an end user's vault to a session?

    session = client.beta.sessions.create(
        agent=agent.id,
        environment_id=environment.id,
         ? =[vault.id],
        title="Alice's Slack digest",
    )

    Several runtime behaviours are easy to miss in a review:

    - Silent unauthenticated fallback. If no credential matches the server URL, the agent connects without credentials. That fails only if the server requires authentication. - No validation at creation. Credentials are stored as provided and not checked until the session runs. A bad token shows up later as a runtime error. - Precedence. When more than one vault has a matching credential, the first vault with a match wins. - Multiagent scope. Vault credentials apply to every thread in the session, so any agent that declares the matching MCP server authenticates with them. - Refresh failure. A failed refresh emits vault_credential.refresh_failed. Validation then returns invalid, meaning the grant is gone and the end user must re-authorize, or unknown, meaning a transient error (5xx, 429 or network failure) where you wait and retry.

    For audit trails, archive instead of deleting. Archiving purges the secrets but keeps the records, while a hard delete keeps nothing.

    Checkpoint 4 of 8· Check yourself

    A multiagent session gets a vault holding a user's Slack MCP credential. One subagent's definition declares the Slack MCP server. What happens?

    Checkpoint 5 of 8· Check yourself

    A compliance team needs to keep a record of which credentials existed for a departed user, without keeping the secrets. What should you do with the vault?

    Sources3

    3.Organisation policy: which servers and tools an agent can reach

    The last layer controls which MCP servers a client may connect to at all. In Claude Code, administrators can provide remote servers through managedMcpServers in managed settings. These entries must use an https:// URL; Claude Code refuses plain http://, even for localhost. They also take only literal values, with no ${VAR} expansion. That limit has a consequence for identity: any header you write here is the same for every user. The example below does exactly that with the records server.

    Servers provided through managed settings, one with a static headerjson
    {
      "managedMcpServers": {
        "search": {
          "type": "http",
          "url": "https://search.example.com/mcp"
        },
        "records": {
          "type": "http",
          "url": "https://records.example.com/mcp",
          "headers": {
            "X-Records-Key": "key-issued-for-all-claude-code-users"
          }
        }
      }
    }

    The gap is that the records server cannot tell users apart, because every user sends the same key. When you need per-user authorization, look at what managed-mcp.json offers instead: ${VAR} expansion, OAuth or per-user headers, or headersHelper.

    Allowlists and denylists decide which servers load. Read them in this order:

    - Denylist first. A server that matches any deniedMcpServers entry, by URL, command or name, is blocked, and nothing overrides a match. Prefer serverUrl entries, because they keep working if a server is renamed. - Then the allowlist. If allowedMcpServers is not set anywhere, every server that passed the denylist loads. If it is set, the server must match an entry. - Unset versus empty. An unset allowlist allows everything; an empty array allows none, apart from servers that skip the check. An empty denylist blocks nothing. - Soft allowlist. allowedMcpServers without allowManagedMcpServersOnly: true can be broadened by users in their own settings. - Servers that skip the allowlist. Every managedMcpServers entry, built-in servers, and managed-mcp.json entries that use no ${VAR} expansion. A managed-mcp.json server that uses ${VAR} is still checked.

    For example, if an admin sets an allowlist containing one serverUrl entry, a server a user adds that matches no entry is blocked, while the search and records servers above still load because provided servers need no allowlist entry. If the admin also denies the records URL, that server is blocked anyway.

    Permission modes sit alongside these lists. In bypassPermissions mode, permission prompts are skipped except for the actions no mode auto-approves, so a mode setting is not the control that limits which servers load. Use the allowlist and denylist for that.

    How empty and unset lists behave
    SettingUnset (default)Empty array []
    allowedMcpServersAll servers allowedNo servers allowed, apart from those that skip the allowlist check
    deniedMcpServersNo servers blockedNo servers blocked

    At the tool level, permission rules in a permissions object can match MCP tools by pattern, and which list a pattern sits in decides whether it blocks or pre-approves them.

    Checkpoint 6 of 8· Fill the gap

    Which pattern in the deny list blocks every MCP tool?

    {
      "permissions": {
        "deny": [
          " ? "
        ]
      }
    }

    Checkpoint 7 of 8· Check yourself

    An admin sets allowedMcpServers in managed settings but leaves allowManagedMcpServersOnly unset. What is the gap?

    Checkpoint 8 of 8· Exam question

    A CISO reviewing an Agent SDK rollout learns that permission_mode is set to bypassPermissions in a batch-processing pipeline and asks which authorization controls, if any, still constrain the agent under that mode. Based on how bypassPermissions is evaluated, which of the following statements are accurate? (Select 2)(Select 2)

    Sources45

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.After a 403 insufficient_scope, the client should request only the scope named in the challenge.Why is that wrong?

      Requesting only the new scope can drop permissions the client already had. The client requests the union of its earlier scopes and the challenged ones.

      Covered in Scopes: 401 versus 403 and step-up authorization

    2. 2.Setting allowedMcpServers to an empty array removes the restriction, just as an empty deniedMcpServers blocks nothing.Why is that wrong?

      The two lists treat an empty array differently. An empty allowlist allows no servers except those that skip the check, while an empty denylist blocks nothing.

      Covered in Organisation policy: which servers and tools an agent can reach

    3. 3.If a session has no credential for an MCP server, the connection is blocked before it is attempted.Why is that wrong?

      The connection is attempted without credentials and fails only if the server requires authentication.

      Covered in Per-user credentials: who the agent acts as

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “403 | Forbidden | Invalid scopes or insufficient permissions”
      ↩︎ Scopes: 401 versus 403 and step-up authorization
      “Use scope parameter from the initial WWW-Authenticate header in the 401 response, if provided”
      ↩︎ Scopes: 401 versus 403 and step-up authorization
      “Retry the original request with the new authorization no more than a few times and treat this as a permanent authorization failure”
      ↩︎ Scopes: 401 versus 403 and step-up authorization
      “Determine required scopes by computing the union of the client’s previously requested scope set and the scopes from the current challenge.”
      ↩︎ Exam trap 1
      “Determine required scopes by computing the union of the client’s previously requested scope set and the scopes from the current challenge.”
      ↩︎ Checkpoint
    2. 2.
      “Include any existing granted scopes as well, if they are required, to prevent clients from losing previously granted permissions.”
      ↩︎ Scopes: 401 versus 403 and step-up authorization
    3. 3.
      “MCP credentials (mcp_oauth, static_bearer): each credential is keyed by an mcp_server_url.”
      ↩︎ Per-user credentials: who the agent acts as
      “Credentials are stored as provided and are not validated until session runtime.”
      ↩︎ Per-user credentials: who the agent acts as
      “invalid: the grant is gone or the OAuth server rejected the refresh with a 4xx. Prompt the end user to re-authorize.”
      ↩︎ Per-user credentials: who the agent acts as
      “unknown: a transient error (5xx, 429, or network failure). Wait and retry.”
      ↩︎ Per-user credentials: who the agent acts as
      “Delete a vault or credential: Hard delete. The record is not retained. Use archive if you need an audit trail.”
      ↩︎ Per-user credentials: who the agent acts as
      “When no MCP credential matches by mcp_server_url, the connection is attempted unauthenticated and will error if the server requires authentication.”
      ↩︎ Exam trap 3
      “In multiagent sessions, vault credentials apply to every thread.”
      ↩︎ Checkpoint
    4. 4.
      “OAuth or per-user headers so each user authenticates as themselves.”
      ↩︎ Organisation policy: which servers and tools an agent can reach
      “Check the denylist. A server that matches any denylist entry, by URL, command, or name, is blocked. Nothing overrides a denylist match.”
      ↩︎ Organisation policy: which servers and tools an agent can reach
      “Soft allowlist | Enforce an allowlist that users can broaden in their own settings”
      ↩︎ Organisation policy: which servers and tools an agent can reach
      “Provided servers need no allowedMcpServers entry.”
      ↩︎ Organisation policy: which servers and tools an agent can reach
      “allowedMcpServers | All servers allowed | No servers allowed, apart from those that skip the allowlist check”
      ↩︎ Exam trap 2
      “When allowManagedMcpServersOnly is true, only the managed allowlist is kept; the denylist always merges from every scope.”
      ↩︎ Checkpoint
    5. 5.
      “bypassPermissions | Skips permission prompts, except for the actions no mode auto-approves”
      ↩︎ Organisation policy: which servers and tools an agent can reach

    Spotted a mistake, or was something unclear? Tell us.