Skip to main content

Agent Security Architecture

What is Agent Security?

Agent Security delivers permissions-as-a-service for any Model Context Protocol (MCP) server. It acts as a proxy/gateway between AI agents and the MCP server resources they interact with, providing:

  • Fine-grained ReBAC (relationship-based access control) powered by Permit.io (which uses OPA and OPAL under the hood)
  • Authentication & authorization that binds user, agent, MCP server, and downstream service identities
  • Comprehensive auditing covering every tool call, user, and agent
  • Flexible deployment options (hosted gateway available), all using the same policy rules

A single URL switch yields consistent enforcement, instant visibility, and human-in-the-loop (HITL) approvals — no code changes to agents or servers.

System Architecture Overview

Click to enlarge

Key components:

  • Platform (app.agent.security): Admin interface for managing hosts, MCP servers, and user access
  • Edge Router (NGINX): Routes requests by path to Gateway or Consent Service
  • Gateway (*.agent.security/mcp): MCP proxy that enforces authorization on every tool call
  • Consent Service (*.agent.security): Handles OAuth login, user consent, and upstream MCP OAuth
  • Permit.io PDP: Policy decision point for real-time authorization checks
  • Redis: Session and host configuration store (accessed only by Gateway)
  • PostgreSQL: User accounts, OAuth clients, and auth sessions
Architecture constraint

The Consent Service does not access Redis directly. All state persistence goes through the Gateway Admin API, centralizing Redis schema and logic in the Gateway.

Data Flow

The diagram below shows where data lives and how it flows between components:

Click to enlarge
FromToProtocolNotes
ALBNGINXHTTP/1.1TLS terminated at ALB
NGINXGatewayHTTP/1.1 (port 8001)Routes: /mcp, /oauth/*, /.well-known/*
NGINXConsent ServiceHTTP/1.1 (port 3000)Routes: /api/auth/*, /api/consent/*, /api/mcp/*, /login, /consent
Consent ServiceGateway Admin APIHTTP/1.1 + Bearer (port 8002)Sessions, OAuth states, pending tokens
GatewayRedisRESP (port 6379)Only Gateway has direct Redis access
Consent ServicePostgreSQLPostgreSQL (port 5432)Users, sessions, OAuth clients
GatewayConsent Service (JWKS)HTTP (port 3000)JWT signature verification
GatewayPermit.ioHTTPSAuthorization checks (Cloud PDP)
Consent ServicePermit.ioHTTPSPolicy sync during consent
GatewayUpstream MCPHTTPSStreamable HTTP with upstream OAuth tokens

Integration Patterns

Agent Security is available as a hosted gateway deployment:

PatternWhen to UseHow It Works
Hosted GatewayFastest rollout; SaaS workloadsPoint agents/MCP clients to https://<host>.agent.security/mcp

Policy Model

Trust-Level Access Control

Agent Security classifies each tool into a trust level based on its risk:

  1. Low trust — everything else (read-only by convention); this is the default for tools not matching medium or high patterns
  2. Medium trust — write operations (tools containing: create, write, update, set, modify, edit, put, post, insert, add, send, execute, run, invoke, submit, push, publish, deploy, apply, patch)
  3. High trust — destructive operations (tools containing: delete, remove, destroy, drop, purge, erase, truncate, terminate, kill, revoke)

Trust levels are hierarchical: higher levels inherit all permissions from lower levels.

Policy Architecture

Agent Security automatically generates Google-Zanzibar-inspired ReBAC (Relationship-based Access Control) policies based on:

  • Defined roles for users and agents
  • MCP server resource instances
  • Agent roles derived from the user's consent choices
  • A user_profile resource that links each user to the agents acting on their behalf, enabling relationship-based permission derivation through a 3-way chain: Agent --role on--> UserProfile --relation to--> MCP Server. The effective permission on a server is derived as min(agent_role_on_profile, profile_relation_to_server) — meaning a human's profile relation acts as a ceiling on the trust level any agent can actually exercise, regardless of what trust level was granted during consent.

Each MCP server maps to a Permit resource type whose key is the server key (e.g., linear). The server's tools become actions on that resource, using slugified tool names (e.g., create_issue). There are no separate resource instances per tool — the server itself is both the resource type and instance.

Simplified diagram

The diagram below shows the logical relationship between agents and server resources. The actual Permit model uses a 3-way derived chain through a user_profile intermediary: Agent --role on--> UserProfile --relation to--> MCP Server, with effective permission = min(agent_role, profile_relation). See the Authorization: Trust Ceiling section below for the full model.

Authentication & Authorization

How it Works

Admin setup (one-time via Platform UI):

  1. Admin signs in to the Platform UI at app.agent.security and creates a host linked to a Permit environment
  2. Admin imports upstream MCP servers through the Platform, which configures the Gateway and syncs policies to Permit
  3. Admin grants specific users permission to connect to specific MCP servers via the Platform's Humans page

User connection (first time):

  1. The MCP client discovers the gateway's OAuth endpoints
  2. The user authenticates and signs in
  3. The user selects an MCP server from the list of servers the admin has granted them access to
  4. If the upstream MCP server requires OAuth, the user authorizes with the upstream provider
  5. The user chooses the trust level they want to grant their agent, up to the maximum the admin configured
  6. The gateway issues a JWT access token to the MCP client

On subsequent tool calls:

  1. The gateway verifies the JWT and identifies the agent
  2. The gateway checks Permit: "Can this agent call this tool on this MCP server?"
  3. Allowed calls are proxied; denied calls return a permission denied error

Identity format: The gateway constructs a user key for the Permit check based on the caller type:

  • Human users: human|{subject} — where subject is the authenticated user's identity. This format is used by the consent service and platform for policy management (e.g., granting a user access to MCP servers).
  • Agents: agent|{client_id} — where client_id identifies the agent acting on behalf of the user. This format is used at runtime by the gateway for tool-call authorization checks.

Sequence: Admin Setup Flow

The admin creates a host through the Platform UI by selecting a Permit project and environment. The Platform resolves the environment's API key, provisions the host configuration in the Gateway, and stores it in Redis.

When a user connects for the first time, the MCP client discovers OAuth endpoints, the user authenticates and consents, and if the upstream MCP server requires OAuth, that flow is handled transparently.

Server allow-list

By default, users can only connect to MCP servers that the admin has pre-configured and granted them access to — the consent service validates that every upstream URL matches a server the user is authorized to use. However, if the admin enables Dynamic MCPs on the host, users can also enter arbitrary upstream MCP server URLs during the consent flow. See Dynamic MCPs below.

Sequence: Authorization Decision Flow

When a tool call arrives at the Gateway, it passes through a multi-step middleware chain before reaching the upstream MCP server.

Tool visibility vs. enforcement

The gateway returns all tools in list_tools responses regardless of the agent's trust level. Authorization enforcement happens exclusively at call_tool time — agents may see tools they cannot invoke.

Authorization: Trust Ceiling (min logic)

The effective permission on an MCP server is determined by the minimum of the agent's trust level and the human's profile relation to the server. This ensures a human's profile relation acts as a ceiling on what any agent can exercise.

How it works:

The system uses 9 derived role rules per MCP server to implement the min() logic through Permit's ReBAC:

Agent role on profileProfile relation to serverEffective server role
{server}-highhighhigh
{server}-highmediummedium (capped)
{server}-highlowlow (capped)
{server}-mediumhighmedium
{server}-mediummediummedium
{server}-mediumlowlow (capped)
{server}-lowhighlow
{server}-lowmediumlow
{server}-lowlowlow

The derived role then determines which tools are allowed:

  • Low trust tools: available to low, medium, and high roles
  • Medium trust tools: available to medium and high roles
  • High trust tools: available to high role only

Deployment

Agent Security is available as a hosted gateway at *.agent.security. Each host (tenant) gets a unique subdomain with isolated policies, users, and sessions.

Point your MCP clients to https://<host>.agent.security/mcp and the gateway handles the rest — authentication, authorization, and audit logging are all built in.

Key Advantages

  • Single control point for authorization and audit
  • Drop-in — no code changes, SDK optional
  • Fine-grained ReBAC — captures true user-agent-resource relationships
  • Policy-as-code — policies managed via UI and API, powered by OPA/Rego under the hood
  • Short-lived creds — minimize blast radius

Agent Configuration Examples

note

Agent roles are automatically derived from the trust level selected during the user consent flow. The table below shows how different agents might be configured in practice.

Below is an example of how different agents end up with permissions based on the consent flow:

Agent (MCP Client)UserMCP ServerTrust Level GrantedExample Allowed ToolsExample Denied Tools
Cursoralicelinear_mcpMediumget_issues, create_issuedelete_project
Claude Desktopalicegithub_mcpLowlist_repos, get_filecreate_issue, delete_repo
VS Code Copilotbobgithub_mcpHighget_file, create_issue, delete_repo(none — high includes all)
Claude Codecarolslack_mcpMediumsearch_messages, send_messageremove_member

Dynamic MCPs

Dynamic MCPs allow users to connect to any MCP server URL during consent, not just admin-provisioned servers. For setup instructions, see Platform: Dynamic MCPs.

How it works in Permit: The Consent Service creates per-user resource types for dynamic MCP servers, keyed as {serverKey}-{userId} with an mcp_server_type: "dynamic" attribute. The host-level toggle is enforced via a connect_dynamic_mcp action on the user_profile resource.

Glossary

TermMeaning
MCPModel Context Protocol (tool/agent interoperability)
OriginatorHuman delegating authority
AgentAutonomous MCP client acting on behalf of the user
HostA named gateway instance with its own subdomain, policies, and sessions
Trust LevelRisk classification (low/medium/high) that determines which tools an agent can call
PDPPolicy Decision Point — evaluates authorization requests in real time
HITLHuman-in-the-loop
ReBACRelationship-based access control
OPALOpen Policy Administration Layer
OPAOpen Policy Agent