Skip to content

MCP Security and Authorization: OAuth, Permissions, and Approval

Secure an MCP integration by separating OAuth authorization, tool permissions, human approval, secret handling, and auditable execution outcomes.

Secure access boundary representing authorization for an MCP tool server

MCP security depends on several separate controls. A Model Context Protocol integration needs transport security, client authorization, tool permissions, user consent, payload validation, and a way to stop consequential operations before they run. OAuth can let a client reach an MCP server. It does not decide whether every tool call from that client is safe to execute.

The design is easier to reason about when it separates three decisions:

  1. Connection authorization: may this client access this MCP resource?
  2. Tool authorization: may this identity invoke this tool on this resource?
  3. Operation approval: should this exact high-impact call execute now?

MCP authorization and human approval solve different problems

Architecture Flow
Invalid Valid Denied Allowed low risk Consequential Approved current payload Rejected or expired MCP client OAuth and token validation Reject connection Tool permission Reject tool call Ask a human Execute tool Do not execute Record execution outcome

MCP authorization is defined at the transport boundary for HTTP-based servers and is based on OAuth. Human approval belongs closer to the side effect, where the system has the actual tool name, arguments, environment, and risk context.

Without that separation, an implementation can make either of these mistakes:

  • "The token is valid, so every tool call is approved."
  • "A human clicked approve, so the client may exceed its existing permissions."

Approval must never expand the caller's authorization. Execute with the same scoped machine identity after the decision.

Define each security layer

LayerControlFailure behavior
TransportHTTPS for remote MCP trafficReject insecure remote connections
AuthenticationValidate the presented access tokenReturn unauthorized without running a tool
Audience bindingAccept tokens intended for this MCP resourceReject tokens minted for another service
PermissionMap identity and scope to tools/resourcesDeny outside the allowed set
ValidationCheck tool name, schema, size, and argument boundsReject malformed or oversized calls
Human judgmentReview the exact consequential operationReject or expire without execution
ExecutionUse least-privilege downstream credentialsContain the side effect
EvidenceCorrelate decision with the real resultPreserve failure and rollback honestly

The MCP specification warns against token passthrough: an MCP server should not forward a token it received from a client to an unrelated downstream API. Obtain a separate downstream credential with the correct audience and privileges.

Use allow, ask, and deny at the tool boundary

A three-way policy makes the execution rule visible:

yaml
mcp_tools:
  inventory.read: ALLOW
  deployment.promote: ASK
  payment.refund: ASK
  customer.delete_all: DENY

defaults:
  unknown_tool: DENY
  approval_timeout: DENY
  changed_arguments: ASK_AGAIN

This is a conceptual policy, not an Actionbox server configuration. Enforce it in the client, gateway, or local wrapper that controls access to the downstream MCP server.

Actionbox's hosted MCP server exposes six Source-scoped tools: ask_human, get_action, list_actions, update_action, cancel_action, and resolve_action. The first creates a durable Action. The read tools retrieve only that Source's state, while the mutation tools update or terminate the Source's own Actions.

A resolve_action result is explicitly attributed to the machine and must never be treated as human approval. The Actionbox MCP surface is not a security proxy for every other MCP server. If a policy must be impossible to bypass, enforce allow, ask, and deny in the application or gateway that owns the downstream tool call.

For a concrete request and decision, see the MCP human-in-the-loop example. It shows the ask_human and get_action inputs and the check the publishing application must perform before acting.

Connect the public Actionbox MCP bridge

Install the public CLI, store a Source key in its protected local configuration, and verify the hosted API connection:

bash
python -m pip install actionbox
actionbox configure
actionbox doctor

Then configure an MCP host to launch the local stdio bridge:

json
{
  "mcpServers": {
    "actionbox": {
      "command": "actionbox",
      "args": ["mcp"]
    }
  }
}

The bridge connects to Actionbox's hosted MCP service. The Source key remains in the CLI's owner-only configuration instead of being copied into the JSON-RPC stream or a chat.

Test the boundary, not only the connection

Use a disposable Source and a harmless operation first:

  1. Ask the agent to call ask_human with a bounded question and two unambiguous choices.
  2. Confirm that the Action appears in the hosted inbox and remains open if the client disconnects.
  3. Resolve it in the dashboard, then have the agent call get_action for the returned Action ID.
  4. Confirm that rejection, expiry, a malformed response, or an unavailable API prevents the side effect.
  5. Rotate the disposable Source key and verify that the old bridge can no longer create Actions.

This exercise verifies the human-input path. Another MCP server may still be callable directly unless you enforce the policy at a tool boundary you control.

Protect credentials and capability URLs

  • Keep Source keys in the runner's protected secret store.
  • Do not paste keys into chat, project files, logs, screenshots, or command arguments.
  • Prefer a local bridge that reads owner-only configuration when the MCP host can launch a command.
  • For remote HTTP, inject the credential through the host's supported secret mechanism.
  • Do not include access tokens in URLs or query strings.
  • Redact credentials and customer secrets before tool arguments become review context.

A reviewer needs enough information to judge the operation, but not every byte available to the agent. Show the tool, affected resource, environment, impact, reversibility, and a safe summary of the arguments.

Bind approval to the exact tool call

If arguments can change after approval, the approval is not a meaningful control. Use a stable tool-call identity and bind the review to the current operation snapshot.

For an Actionbox-backed review:

  1. Build sanitized context from the exact tool call.
  2. Create one Action using a stable idempotency identity.
  3. Set a bounded server-side expiry.
  4. Treat rejection, expiration, API failure, and malformed response as denial.
  5. Re-read the authoritative Action when execution is delayed.
  6. Refuse a stale version or fingerprint.
  7. Execute with the caller's existing downstream permissions.
  8. Report the real success or failure afterward.

An Actionbox decision receipt can prove which Action snapshot was resolved. It does not prove the MCP tool succeeded, so keep the execution outcome separate.

MCP security review checklist

  • Remote traffic uses HTTPS.
  • Tokens are validated for the intended MCP resource.
  • Downstream APIs receive separate, correctly scoped credentials.
  • Unknown tools default to deny.
  • Tool arguments have strict schemas and size limits.
  • High-impact operations are classified before execution.
  • Review context excludes credentials and unrelated private data.
  • Approval is bound to stable tool-call identity and current arguments.
  • Rejection and timeout fail closed.
  • Retries do not create duplicate reviews or duplicate side effects.
  • Execution outcomes and rollback are recorded separately from approval.

Use the MCP host's built-in consent UI when the person using the host is also the authorized reviewer, the operation is immediate, and the host reliably displays the exact call. Add a durable external decision when approval must survive a disconnected client, route to another person, expire on the server, appear in workspace history, or correlate with a later execution outcome.

The two controls can work together. Harmless tool calls do not need to fill an external inbox. Use durable review when policy requires it or when someone outside the current MCP session is responsible for the decision.

Sources and further reading

Create a free Source · Connect Actionbox through MCP · Read the MCP server guide

About the author

Suson Sapkota

Suson founded ActionBox and works in software and data engineering. He writes about approval workflows, background jobs, and how to verify what happened after a human decision.

Turn the next risky operation into a reviewable decision.

Create a free Source, run the example from this guide, and keep the decision and execution outcome connected.