MCP security / Insight

MCP security: why authorization is not a tool contract

A valid token can let an agent reach a Model Context Protocol (MCP) server without making its next action appropriate. Secure MCP architecture needs both protocol-level authorization and an explicit contract for what each tool may do, for whom, to which resources, and with what evidence.

Article

For: Architects, platform engineers and security teams connecting AI agents to enterprise tools through MCP.

Three questions that a successful connection does not answer#

Imagine an agent that can create CRM tasks. A connectivity test passes, authentication succeeds, and a well-formed request produces a task. That proves the integration works on one path. It does not prove that the task belongs to a customer the user may access, that its assignee is permitted, or that retrying after a timeout will not create it twice.

  • Protocol access: may this client make this request to this MCP server?
  • Business authority: may this subject, through this workload, perform this action on this resource now?
  • Execution contract: what exactly happens, and how will we identify success, denial or an uncertain outcome?

These questions are related, but none can stand in for the others. A scope such as tasks:write may be useful without expressing every customer, tenant, approval and workflow constraint. The architectural mistake is treating a successful OAuth exchange as the end of the authorization design rather than the beginning of the protected request path.

What MCP authorization actually covers#

The MCP authorization specification defines an authorization flow for HTTP-based transports. Authorization is optional in MCP overall; where this mechanism is used, the protected MCP server is an OAuth resource server. Clients identify the intended resource, and the server validates that incoming access tokens are intended for it. This is not a universal authorization mechanism for local stdio integrations.

A downstream CRM is a different resource. The MCP server needs an appropriate, separately validated authority path to that API; receiving a token for the MCP server does not automatically authorize a CRM operation. The MCP security guidance explicitly rejects token passthrough that accepts a token intended for another resource and forwards it downstream. Its proxy guidance also addresses consent for the specific MCP client, not merely a previous consent to the proxy.

This builds on a wider OAuth principle: restrict access tokens to their intended resource servers and validate that restriction at the receiver. RFC 9700, the OAuth security best current practice explains audience restriction and its role in limiting token misuse. Audience validation is necessary, but it is not a substitute for checking the requested customer record or business action.

For a local stdio server, ask a different operational question: which executable receives which environment credentials and filesystem or network access? Local execution changes the credential path; it does not make the process intrinsically trusted. Keep credentials outside model context and review the actual runtime privileges.

Draw an authority map, not just an integration diagram#

For one representative action, name the human or service initiating the work, the application executing it, and the exact business resource affected. Do this at each hop. The word agent is too imprecise: a model proposes parameters, a workload holds credentials, and a business principal owns permissions. Collapsing those roles makes it difficult to explain whose authority was exercised.

On a narrow screen, scroll the table sideways to see every column.

Authority map for a hypothetical CRM task integration
BoundaryTrusted evidenceDecision to enforce
User → host applicationAuthenticated user and tenant; approved missionMay this person start this workflow for this customer?
MCP client → MCP serverValidated token for this server; client and scopesMay this caller invoke this capability?
MCP server → CRM APIDownstream credential plus verified subject/resource contextMay this operation affect this customer's record now?
Tool result → orchestrationValidated response, provider reference and sourceIs the outcome confirmed, denied or still unknown?

Delegated user access is not always available in a legacy API. A narrowly scoped service credential can be a deliberate integration choice, but then the adapter must enforce user-specific constraints from verified state. A subject identifier supplied by the model is not verified state. If you cannot enforce the required boundary, reduce the capability or keep the action in the existing human workflow.

A confused deputy can exist behind perfectly valid tokens#

Consider a hypothetical support assistant. Maya may work on customer Alpha. The MCP server uses a service account that can write tasks for every customer. A retrieved note proposes a follow-up for customer Beta. The request is valid JSON, Maya's MCP token is genuine, and the server's CRM credential is genuine. The server nevertheless creates Beta's task because it checks the tool name but not Maya's authority over Beta.

The server has acted as a confused deputy: it used its broader power on behalf of a caller who lacked the relevant permission. This business-authorization example is distinct from the OAuth proxy consent attack documented in MCP's security guidance. Both illustrate why the authority of an intermediary cannot be treated as the authority of everyone who can reach it.

A safer path for the same proposed task
  1. Propose

    The model proposes customer, assignee and task text. These are untrusted candidate parameters.

  2. Resolve and authorize

    The application resolves identifiers and checks the current subject, tenant, resource and permitted action.

  3. Execute or deny

    The adapter executes only the checked action. A denial does not trigger a fallback to a more powerful identity.

Removing suspicious language from the note would not repair the missing permission check. Nor would hiding the tool from the model: discovery filtering is helpful, but direct invocation still needs enforcement. Test the boundary with a normal-looking unauthorized resource identifier, not only an obvious prompt-injection string.

A schema describes shape; a contract describes consequences#

MCP tool definitions include an input schema and can include an output schema and behavioural annotations. The MCP tools specification warns that annotations are untrusted unless they come from trusted servers. A read-only hint is therefore not independent proof that a deployed implementation cannot write, export data or call another service.

Consider a search tool that returns signed download URLs. Its JSON schema may be stable while its security consequences change: a URL might grant access to another person, last longer than the session, or reveal more fields than expected. A useful enterprise contract records those consequences, who owns them, and which implementation change requires review.

  • Meaning: one bounded purpose, allowed resources and explicitly prohibited uses.
  • Authority: trusted identity source, current entitlement checks and downstream credential strategy.
  • Data: input limits, permitted output fields, classification, provenance and allowed destinations.
  • Effects: read or write semantics, approval conditions, duplicate prevention and reconciliation.
  • Operations: timeouts, budgets, owner, observed implementation version and disablement route.

Review semantic changes as well as code changes. A description that encourages a different workflow, a broader default search scope, or a new destination may materially change behaviour without changing the input schema. Pinning a version helps identify change; it does not prove that the version deserves trust.

Copy this tool-contract worksheet into your design review#

Complete this for one tool before generalising it into a platform. The example is intentionally ordinary: an internal CRM task. Do not copy its permission choices into another business process. Store the contract alongside your implementation and tests; it is an application design artifact, not an MCP wire-format object.

Keep tokens, secrets and unnecessary personal data out of the evidence record. Logs should connect a request to its decision and outcome without becoming a second uncontrolled copy of the CRM. A contract is useful only when you can point to the code or downstream service that enforces each material rule.

Make the denial paths part of the demonstration#

Ask the team to demonstrate three requests: an allowed action, the same action against an unauthorized resource, and an action whose outcome becomes uncertain. The first establishes utility. The second establishes the permission boundary. The third establishes whether the system can stop safely when the integration does not behave like a demo.

  • Wrong audience: a token issued for a different resource is rejected before business processing.
  • Changed access: permission revoked after planning prevents the later effect.
  • Description drift: an unreviewed tool change does not silently expand allowed behaviour.
  • Lost response: a timeout is not treated as proof of failure and followed by an unbounded write retry.
  • Misleading output: a tool's prose cannot grant permission to a different tool or overwrite verified workflow state.

These checks develop the broader argument in bounded autonomy for AI agents. In the Agentic AI Architecture & Security course, the secure-tool and identity exercises turn a similar authority map into a design that participants can defend. The useful review question is not ‘Does MCP work?’ It is ‘Can we explain and enforce every business effect this connection makes possible?’

Sources and further reading

Primary sources checked on . Worked examples and worksheets are Ardevant teaching material; sources do not imply endorsement.

  1. MCP specification — Authorization

    HTTP authorization scope, protected resources and token audience validation. Versioned source checked 30 September 2026.

  2. MCP — Security Best Practices

    Token passthrough and the protocol's OAuth proxy confused-deputy scenario; distinguish these from the hypothetical business-policy example here.

  3. MCP specification — Tools

    Tool definitions, schemas and the trust limitations of behavioural annotations.

  4. RFC 9700 — Best Current Practice for OAuth 2.0 Security

    Audience restriction and resource-server validation, especially sections 2.3 and 4.10.2.

Continue / Apply the method

Know what your agent connections can actually do.

Bring one tool integration or proposed MCP architecture. Work with Anton to map identity, resource access and effects, and identify the decisions needed before release.

Author

Anton Selin

Software architect and your consulting partner.

Anton works on enterprise AI, cloud strategy, and agentic systems. Through Ardevant, he offers architecture consulting and practical training focused on the decisions your team needs to make.

About Anton and Ardevant