Secure MCP/Agent for Enterprise Access Control


Problem Statement

In personal MCP deployments (e.g., integrating with Claude Applications), MCP invocations are typically configured using the user’s personal credentials. In this model, the MCP server or target system enforces access control directly based on the user’s identity.

In enterprise environments, however, this approach is insufficient. Organizations often require fine-grained access control, and direct personal access to target systems may not be feasible. For example, when using an MCP tool to query Snowflake, certain sensitive columns may need to be masked depending on the requester’s role or entitlements.

To address these challenges, Clear Entitlement (CE) provides an authorization server, MCP proxy, and SDK that enable enterprise-grade control and security for MCP access.


Secure Enterprise Agent/MCP Deployment with ClearEntitlement




Agent/MCP Proxy or Gateway

Out-of-the-box access control in Agent/MCP servers is often insufficient for fine-grained authorization. An additional enforcement layer is required, particularly when MCP integrations rely on API keys.

While SDK integration on either the MCP client or server can perform entitlement checks, a more integration-friendly approach is to provide an MCP server proxy that:

- Performs entitlement checks.
- Handles policy-driven request/response transformations.
- Optionally manages token exchange (if supported).

From the client’s perspective, the proxy behaves like the original MCP server, but is accessed through a different endpoint.


Token Scope / Claim–Based Access Control

When the MCP server or target system natively supports fine-grained authorization via scopes and claims, tokens can be minted with only the least privileges required for a specific tool or resource invocation.

CE’s proxy or SDK can mint such tokens dynamically, based on policies defined for the MCP server.

⚠️ Note: When using a proxy as the Policy Enforcement Point (PEP), direct access to the MCP server should be blocked or denied.


Entitlement Provisioning

Roles, groups, application access, and other security attributes are typically requested through an identity workflow system such as SailPoint. Privileged Access Management (PAM) solutions like CyberArk can also temporarily elevate (and later revoke) privileges for ordinary user accounts.

Depending on the deployment, entitlements may be provisioned (via SCIM or API calls) into:
- CE’s Policy Information Point (PIP), per XACML
- The MCP server or target system (if supported)
- The Identity Provider (IdP)

When entitlements are provisioned into the IdP, access tokens can be minted with groups or other attributes as claims. At runtime, CE’s Policy Decision Point (PDP) can also retrieve and cache entitlement data from external sources, such as an IdP or database, to support dynamic policy evaluation.

Finally, CE’s Policy Administration Point (PAP) is responsible for policy management and can also support manual provisioning of entitlement data.


Federation, SSO, Token Exchange & API Key

In a single-IdP scenario, a user logs in once and does not require further interactive authentication to access the MCP server.

- SSO: For example, Okta supports silent login (prompt=none) through a front-channel flow, which can be executed in a hidden iframe for a seamless experience.
- Token Exchange: A back-channel flow that improves the user experience and enables scope downgrades for guardrailed access. For example, an access token can be minted with only the minimum required scopes and claims for a given invocation. Okta’s inline hooks can also be used to dynamically generate customized claims based on URL parameters.

MCP servers may also integrate with third-party services (e.g., Snowflake, GitHub), which often use their own IdPs. In multi-IdP scenarios, SSO can still be achieved if federation is configured, and token exchange may also be supported to unify access.

In some deployments, API key integration with the MCP server is used instead. In this model, the user authenticates only to the chatbot (MCP client), while access to the MCP server is performed with a common service identity (API key). In such cases, the chatbot enforces access controls on behalf of the user.



Use Cases & Solutions

RBAC / ABAC

Examples:
- Controlling access to a Slack channel.
- Enforcing a maximum payment amount for a transaction.

How it works:
- The proxy intercepts the request and calls the authorization service to determine access.
- The tool name is modeled as the resource, and the request payload along with the access token is passed as the context.
- The Policy Decision Point (PDP) retrieves relevant attributes (e.g., roles, groups) from the Policy Information Point (PIP) or directly from the access token.
- Conditional expressions can be used to implement ABAC policies, such as restricting payment amounts or other resource-specific conditions.

Sample Policy:
resource = "mcp/tool/[tool_name]"
subject = [role, group, or user]
condition = "payload.payment.amount < 500", or
condition = "payload.payment.amount < role.maxAmount"

The screen below shows a demo where a user can only make payments up to $500. The denial is driven by a policy obligation, which can either return a general deny message or provide a specific reason.



Data Redaction (Row Filtering) and Masking (Column Filtering)

Request Filtering / Redaction

- Modify Request Filter: To redact data, the proxy can modify or add filters to the request based on obligations returned from the authorization check.
- Response Row Filtering: The proxy can filter rows in the response according to access check results.

⚠️ Caution: This approach is inefficient and should only be applied to small datasets.

Column Masking

- The proxy can mask specific columns based on obligations returned from the authorization check.
- If proxy-based approaches are impractical, server-side SDK integration can be used.

Handling SQL Queries (e.g., Snowflake, BigQuery)

⚠️ This is a specialized use case requiring careful verification of column access in both SELECT and WHERE/JOIN clauses. Simply masking columns in the response is unsafe, as it can be exploited in blind SQL attacks.
Example vulnerability:
SELECT first_name, last_name FROM employees WHERE salary > 100000;
If the user is not authorized to view the salary column, they could still infer its value by adjusting the threshold in the WHERE clause.

- Row Filtering: The proxy modifies the SQL WHERE clause based on obligations from the authorization check.

- Column Masking:
   • Check access for each column in the query, including those in WHERE and JOIN clauses.
   • Replace unauthorized columns in the SELECT list with masked values (e.g., ******).

Sample Obligation:
- allowed_columns=first_name,last_name,gender,hire_date,birth_date
- filter=employees.username='$username$'

The screen below shows a demo where user "Test Two" can view all columns of their own record.


The screen below shows a demo where user "Test Two" is a department head and can view all records for their department, but cannot see the DoB column.



Disaster Prevention

Certain tool methods pose significant risks, such as deleting records. If an LLM misinterprets a user’s intent, this can result in serious consequences.

Confirm with User Obligation
- When a user requests a potentially dangerous action (e.g., deleting records), CE can require an additional confirmation step before the action is executed.
- If the user is authorized to perform the action but no confirmation flag is present in the context, CE returns a “confirm with user” obligation.
- The chatbot then presents the action details to the user and requests confirmation. This may be handled through a back-channel such as CIBA (Client-Initiated Back-channel Authentication), for example, by sending a mobile push notification with a confirmation button.
- Once the context includes a confirmation flag set to “confirmed,” CE permits the action to proceed.

Note: This usually requires SDK integration, as the proxy may not have the full context to perform the obligation effectively.


Mint Token with Least-Privileged Scopes/Claims

In certain MCP or agent-to-agent (A2A) invocations, it is recommended to use an access token with the least-privileged scopes and claims, especially when the target system enforces access control based on these attributes.

How it works:

- The CE SDK (or Proxy) invokes the PDP with the full MCP or A2A payload.
- The PDP extracts relevant parameters by translating human text into JSON using an LLM.
- The PDP determines the minimum required scopes and claims based on policies.
- The PDP returns a “mint token” obligation containing the required scopes and claims.
- The CE SDK (or Proxy) calls the token exchange API of the IdP to obtain a new access token, if no valid unexpired token with the required scopes and claims is already cached.
- The least-privilege token is then passed to the MCP server or agent for the invocation.

Using a least-privilege token reduces security risks by limiting the token’s authority to only what is required for the specific operation. This approach can also improve overall system resilience.


Demo

Demo Setup:
- ChatBot: Out-of-the-box LibreChat Docker image, configured only to integrate with the proxy.
- Proxy: CE’s MCP Proxy
- MCP Server: Several local MCP tools simulating payment, SQL, and other tools.
- IdP: Okta
- Provisioning: Setup role/group membership in CE’s admin console
- Entitlement Server: CE