MCP security and authorisation

How to secure an MCP server: OAuth 2.1, protected resource metadata, audience-bound tokens, least privilege, approvals, validation, limits, audit and prompt-injection handling.

Banner for the GeekMidst reference architecture “MCP security and authorisation”, covering Business context and MCP security and authorisation…

An MCP server turns business capabilities into tools an AI model can call. That makes it a new front door to your data, and it needs the same care as any API, plus controls for risks specific to AI clients, such as instructions hidden in data. This page sets out a security and tool-authorisation architecture based on the MCP authorisation specification and its security best practices.

This is a reference design. We validate identity providers, scopes, vendor permissions and data handling for each implementation, and GeekMidst can design and implement it through MCP server development. It is not legal or compliance advice; check obligations with your legal adviser.

Business context

The risks are concrete: a token accepted by the wrong server, a server forwarding a client's token downstream, a tool that runs any query it is given, a model persuaded by text in a record to call a write tool, or a runaway loop of calls. Each one has a control, and the controls work best when designed together.

MCP security and authorisation reference architecture

Reference architecture: a reusable pattern, not a live client integration

Client sideCLIENT SIDEAUTHORISATIONPOLICY AND SECRETSEXECUTIONPRODUCT APISUsersigns in and consentsAI host and MCP clientOAuth clientAuthorisation serverOAuth 2.1 with PKCEProtected resource metadataRFC 9728BMCP serverOAuth resource serverBTool policyread/write, limitsBSecrets storeserver-side onlyBHuman confirmationwrite toolsBDownstream API clientown credentialsBAudit logwho, what, outcomeBProduct APIsSalesforce, Braze, othersrequestsign-in and consentdiscover metadataauth code with PKCEBearer tokenpublishesvalidated requestwrite tool calldecisionpermitted calldownstream credentialdecision logscoped API call
  • AI and agents
  • Integration layer
  • Identity, policy and governance
  • External or custom system
  • People
  • Client side
  • BYour MCP server boundary
  • Dashed: asynchronous, optional or feedback
Diagram source (Mermaid)

Select a component to see what it is responsible for and how data moves to and from it.

Reference architecture. Authorisation servers, scopes, approval rules and downstream permissions are confirmed per implementation.
Components and data flows (text version)
ComponentTypeResponsibility
Usersigns in and consentsPeopleA named person who authorises the client and confirms sensitive actions.
AI host and MCP clientOAuth clientAI and agentsDiscovers the authorisation server, runs the OAuth flow with PKCE and sends the bearer token on every request.
Authorisation serverOAuth 2.1 with PKCEIdentity, policy and governanceIssues access tokens bound to the MCP server's URI as audience, with only the requested scopes.
Protected resource metadataRFC 9728Identity, policy and governanceA document the MCP server publishes that lists at least one authorisation server.
MCP serverOAuth resource serverIntegration layerValidates token audience, expiry and scope, the Origin header and tool inputs before any tool runs.
Tool policyread/write, limitsIdentity, policy and governanceAllowlists tools per role, keeps read and write tools separate, and applies rate limits, timeouts and idempotency.
Secrets storeserver-side onlyIdentity, policy and governanceHolds downstream credentials. Secrets never appear in tool results, prompts or logs.
Human confirmationwrite toolsPeopleShows a named person what will change and records their decision before a write runs.
Downstream API clientown credentialsIntegration layerCalls product APIs with narrow, parameterised requests using the server's own credentials, never the client's token.
Audit logwho, what, outcomeIdentity, policy and governanceRecords caller, tool, decision, outcome and timing, without storing secrets.
Product APIsSalesforce, Braze, othersExternal or custom systemBusiness systems behind the server, each with its own permissions and limits. Databases are never exposed directly.

Data flows

  1. User → AI host and MCP client: request. The user asks the host to do something.
  2. User → Authorisation server: sign-in and consent. The user signs in and approves the requested scopes.
  3. AI host and MCP client → Protected resource metadata: discover metadata. After a 401, the WWW-Authenticate header points to the metadata, which names the authorisation server.
  4. AI host and MCP client → Authorisation server: auth code with PKCE. The client sends the resource parameter (RFC 8707) so the token is bound to this server.
  5. AI host and MCP client → MCP server: Bearer token. Sent in the Authorization header on every request, never in the query string.
  6. MCP server → Protected resource metadata: publishes. The server serves its metadata at a well-known path.
  7. MCP server → Tool policy: validated request. Only requests with a valid, correctly scoped token, a valid Origin and schema-valid input reach the policy.
  8. Tool policy → Human confirmation: write tool call. Write and destructive tools wait for a person to confirm.
  9. Human confirmation → Tool policy: decision. Approval lets the call continue; rejection returns a tool error.
  10. Tool policy → Downstream API client: permitted call. Calls run with timeouts and an idempotency key so a retry does not repeat a change.
  11. Secrets store → Downstream API client: downstream credential. The API client fetches its own credential at call time; it is never passed to the model.
  12. Tool policy → Audit log: decision log. Every allow, deny and approval is logged.
  13. Downstream API client → Product APIs: scoped API call. Narrow, parameterised requests. Vendor errors and rate limits are returned as tool errors.

Controls and what they prevent

ControlWhat it preventsHow
OAuth 2.1 resource serverAnonymous or shared accessServers act as resource servers; clients use PKCE
Protected resource metadata (RFC 9728)Misconfigured clientsPublish metadata listing the authorisation server
Audience-bound tokensTokens reused at other serversValidate that the token was issued for this server (RFC 8707)
No token passthroughBypassed server controls and a lost audit trailNever accept or forward tokens not issued for this server
Least privilegeOver-broad accessMinimal scopes; separate read and write scopes
Read and write separationAccidental changesSeparate tools; writes off by default
Human confirmationUnreviewed changesPreview and approve each write
Input schema validationMalformed or injected argumentsJSON Schema with additionalProperties false
Rate limits, timeouts, idempotencyRunaway loops and duplicate writesPer-user limits; idempotency keys
Secrets server-sideCredential leaks to the modelSecrets store; never in results
No database credentials or unrestricted SQLBulk data extractionNarrow, parameterised tools only
Origin validationDNS rebinding403 on an invalid Origin; local servers bind to 127.0.0.1
Prompt-injection handlingInstructions hidden in dataTreat tool output as data; confirm writes
Audit loggingUnaccountable actionsLog caller, tool, outcome and timing

Data flow, step by step

  1. The client calls without a token and gets 401 with a WWW-Authenticate header pointing to the protected resource metadata.
  2. The client reads the metadata and finds the authorisation server.
  3. The user signs in and consents; the client completes the flow with PKCE and the resource parameter.
  4. The client sends the token as Authorization: Bearer on every request.
  5. The server validates audience, expiry and scope (401 for invalid or expired tokens, 403 with insufficient_scope), the Origin header and the tool input.
  6. The policy decides: is the tool allowed for this user, is it read or write, is the caller within limits?
  7. Writes wait for confirmation from a named person.
  8. The API client calls the product with its own credential and an idempotency key.
  9. Everything is logged.

Trust boundaries and authentication

The client side is untrusted from the server's point of view, including the model's choice of tools and arguments. The server boundary holds tokens, policy, secrets and audit. Product APIs sit beyond it, each enforcing its own permissions. Vendors show the same principles: Salesforce Hosted MCP Servers use per-user OAuth with PKCE through an External Client App with the mcp_api scope, enforce CRUD, field-level security and sharing, and have no anonymous service accounts. The Braze MCP server uses OAuth with the user's Braze login, needs a "Use MCP Server" permission that is off by default, and Braze advises against client "auto-mode".

The public MCP server on this website shows a different, deliberate choice: it is read-only and unauthenticated because it serves only published content, and it is rate limited per address with Origin validation for browser clients.

Failure scenarios and how to handle them

FailureEffectHow to handle it
Token for another server presentedPossible misuseReject unless the audience matches this server
Token expired401Client refreshes; server never falls back to a shared key
Scope too narrow403 insufficient_scopeClient requests a step-up scope with consent
Model calls a write tool unexpectedlyUnwanted changeApproval required; deny by default
Retry after timeoutDuplicate writeIdempotency key per change
Injected text in a recordModel misledOutput treated as data; writes confirmed by a person

Operational monitoring

Monitor authentication failures, denied calls, approval rates, write volume per user and latency. Alert on bursts of denials or writes. Review scopes, allowlists and approvers regularly, and rotate downstream credentials on a schedule.

Alternative approaches and trade-offs

OAuth per user gives accountability but needs an identity provider and consent design. Service credentials are simpler but hide who acted; keep them for read-only, low-risk tools. Local stdio servers take credentials from the environment and suit a single developer, not shared use. Central enforcement in a gateway keeps policy in one place; per-server enforcement keeps it close to the data. Many designs use both; see the MCP host, client and server pattern.

Implementation checklist

  1. 01

    Choose the authorisation server

    OAuth 2.1 with PKCE and Client ID Metadata Documents or pre-registration

  2. 02

    Publish protected resource metadata

    At the well-known path for your endpoint

  3. 03

    Validate every token

    Audience, expiry and scope on every request

  4. 04

    Separate read and write tools

    Read-only first; writes behind approval

  5. 05

    Define input schemas

    Strict schemas and clear tool errors

  6. 06

    Keep secrets server-side

    Secrets store and rotation

  7. 07

    Set limits

    Per-user rate limits, timeouts and idempotency keys

  8. 08

    Log and review

    Audit log, alerts and regular access reviews

Questions we hear

Is authorisation required by MCP?
The spec makes it optional. When an HTTP server supports it, it should follow the MCP authorisation spec, based on OAuth 2.1. Any server exposing private data should require it.
Can our MCP server forward the user's token to Salesforce?
No. The spec forbids accepting or passing through tokens not issued for the server. Use a separate credential for each downstream API.
Should we let the AI run SQL?
No. Expose narrow, parameterised tools. Never give an AI database credentials or unrestricted SQL.
Is this based on a client system?
No. It is a reference design based on the MCP specification, validated per implementation.

Sources

  • https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization
  • https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/authorization-server-discovery
  • https://modelcontextprotocol.io/specification/2026-07-28/basic/security_best_practices
  • https://developer.salesforce.com/blogs/2026/04/salesforce-hosted-mcp-servers-are-now-generally-available
  • https://www.braze.com/docs/developer_guide/mcp_server/setup/

Review your MCP security design

Tell us what your MCP server will expose and to whom. We can review the authorisation design, tool policy and approval steps.

Book a consultation →

Tell us what you are trying to fix.

Share your Salesforce setup, goals and constraints. A practitioner reads every message and replies with questions, first thoughts or an honest view of whether you need outside help at all.

Talk to a Salesforce Expert
Book a Consultation