Architecture Overview
ShieldAgent enforces security at the boundary between AI agents and the tools they use. Where exactly that boundary sits in your stack is flexible — deploy the proxy inline between agent and upstream, or use the SDK's Verdict API to scan requests from within your own server code before executing them.
Where to Position ShieldAgent
ShieldAgent can be inserted at several points in the agent-to-tool call chain. The right position depends on what you own in your stack and the level of visibility you need. All positions use the same security pipeline; only the integration method differs. Positions 2 and 3 use the SDK's Verdict API — your code sends request payloads to ShieldAgent for scanning and enforces the returned verdict.
Position 1 — Proxy between Agent and MCP
The agent points its MCP client at the ShieldAgent proxy instead of the upstream server directly. No code changes to the agent or the MCP server. The proxy intercepts every tool call, runs the full security pipeline, and forwards approved requests. This is the primary deployment model and the one that gives you complete visibility into all tool calls.
Best when: you do not own the agent or MCP server, or you want zero-touch deployment. Network segmentation should enforce that agents cannot bypass the proxy.
Position 2 — Verdict API in your own API
If your agents call a REST API that you own and operate, use the ShieldAgent SDK to scan each incoming request before executing it. Your server calls client.scan() with the request payload. ShieldAgent runs the full security pipeline and returns a verdict (allow / block / human_review). Your code enforces the verdict — execute if allowed, reject if blocked. The security pipeline runs on the ShieldAgent proxy, not in-process.
Best when: you own the API layer your agents call and want to add security scanning without changing your traffic flow. Your code stays in control — ShieldAgent scans and returns a verdict, you enforce it.
TypeScript
import { ShieldAgentClient } from '@shieldagent/sdk';
const client = new ShieldAgentClient({
baseUrl: 'https://proxy.shieldagent.io',
apiKey: '{your-api-key}',
});
// Call client.scan() before executing each agent request:
async function handleAgentRequest(agentId: string, method: string, path: string, body: unknown) {
const verdict = await client.scan({
tenantId: '{your-tenant-id}',
agentId, // optional — omit if you cannot identify the caller
toolName: `api:${method}:${path}`,
params: { method, path, body },
context: { transport: 'rest' },
});
if (verdict.action === 'block') {
// YOU must enforce this — ShieldAgent cannot block on your behalf
throw new Error(`Request blocked by ShieldAgent: ${verdict.reason}`);
}
if (verdict.action === 'human_review') {
return { status: 'pending_review', reviewId: verdict.reviewId };
}
// verdict.action === 'allow' — safe to execute
return executeRequest(method, path, body);
}Python
from shieldagent import ShieldAgentClient
client = ShieldAgentClient(
base_url="https://proxy.shieldagent.io",
api_key="{your-api-key}",
)
# Call client.scan() before executing each agent request:
async def handle_agent_request(agent_id: str, method: str, path: str, body: dict):
verdict = await client.scan(
tenant_id="{your-tenant-id}",
agent_id=agent_id, # optional — omit if you cannot identify the caller
tool_name=f"api:{method}:{path}",
params={"method": method, "path": path, "body": body},
context={"transport": "rest"},
)
if verdict.action == "block":
# YOU must enforce this — ShieldAgent cannot block on your behalf
raise HTTPException(status_code=403, detail=verdict.reason)
if verdict.action == "human_review":
return {"status": "pending_review", "review_id": verdict.review_id}
# Execute the request
return execute_request(method, path, body)Position 3 — Verdict API in your own MCP server
If you operate an MCP server that agents connect to, add a client.scan() call before each tool handler. When an agent requests a tool, your server sends the tool name and arguments to ShieldAgent for scanning. ShieldAgent returns a verdict — your code executes the tool only if allowed. This gives you deep visibility and policy enforcement at the point where tools are defined, while keeping ShieldAgent centralized.
Best when: you build and maintain the MCP server and want security enforcement at the tool definition layer. Your server stays in control — ShieldAgent scans, you enforce. Richer context for policy evaluation than external proxy positioning.
TypeScript
import { ShieldAgentClient } from '@shieldagent/sdk';
const client = new ShieldAgentClient({
baseUrl: 'https://proxy.shieldagent.io',
apiKey: '{your-api-key}',
});
// Call client.scan() before every tool handler:
async function handleToolCall(toolName: string, params: unknown, clientName?: string) {
const verdict = await client.scan({
tenantId: '{your-tenant-id}',
// agentId is optional — MCP protocol does not expose agent identity
clientHint: clientName, // pass MCP clientInfo.name for best-effort agent matching
toolName,
params,
context: { transport: 'mcp' },
});
if (verdict.action === 'block') {
// YOU must enforce this — ShieldAgent cannot block on your behalf
throw new Error(`Tool blocked by ShieldAgent: ${verdict.reason}`);
}
if (verdict.action === 'human_review') {
return { status: 'pending_review', reviewId: verdict.reviewId };
}
// verdict.action === 'allow' — safe to execute the handler
return executeToolHandler(toolName, params);
}Python
from shieldagent import ShieldAgentClient
client = ShieldAgentClient(
base_url="https://proxy.shieldagent.io",
api_key="{your-api-key}",
)
# Call client.scan() before every tool handler:
async def handle_tool_call(
tool_name: str, params: dict, client_name: str | None = None
):
verdict = await client.scan(
tenant_id="{your-tenant-id}",
# agent_id is optional — MCP protocol does not expose agent identity
client_hint=client_name, # pass MCP clientInfo.name for best-effort matching
tool_name=tool_name,
params=params,
context={"transport": "mcp"},
)
if verdict.action == "block":
# YOU must enforce this — ShieldAgent cannot block on your behalf
raise MCPError(f"Tool blocked by ShieldAgent: {verdict.reason}")
if verdict.action == "human_review":
return {"status": "pending_review", "review_id": verdict.review_id}
# Execute the tool handler
return execute_tool(tool_name, params)Position 5 — Sidecar Proxy
ShieldAgent runs as a sidecar container alongside each agent (or alongside your MCP/API server). The agent sends requests to the sidecar on localhost instead of the upstream URL directly. No extra network hop — traffic stays on localhost. Same security pipeline as Position 1, but co-located for lower latency and per-agent isolation.
Best when: Kubernetes environments, per-agent isolation requirements, or microservice architectures. Also works as a sidecar of your server — co-locate ShieldAgent alongside your MCP/API server instead of the agent for infrastructure-enforced blocking without a network hop.
Position 6 — Post-Gateway
ShieldAgent sits behind your existing API gateway (Kong, Envoy, AWS API Gateway). The gateway handles authentication and routing, then forwards agent traffic to ShieldAgent for security scanning before it reaches the upstream. No agent code changes — the gateway routes transparently.
Best when: enterprises with existing API gateways that cannot change agent routing. Limitation: traffic bypassing the gateway is invisible to ShieldAgent.
Position 7 — Observer (Audit-Only)
Traffic flows directly from the agent to upstream without interception. A copy of each request/response is sent to ShieldAgent asynchronously for audit and detection. ShieldAgent cannot block threats in this mode — it provides detection, risk scoring, and compliance evidence without enforcement.
Best when: initial evaluation, compliance auditing, or brownfield environments where inline insertion is not yet possible. Zero latency impact.
Which position should I use?
| Position | What you need to own | Agent code changes | Sees outbound tool calls | Latency impact | Enforcement |
|---|---|---|---|---|---|
| 1 — Inline Proxy | Nothing | Point at proxy URL | Yes | +5-15ms | Infrastructure |
| 2 — Verdict API (REST) | Your API server | Add SDK scan() | Yes | +5-15ms | Customer code |
| 3 — Verdict API (MCP) | Your MCP server | Add SDK scan() | Yes | +5-15ms | Customer code |
| 5 — Sidecar Proxy | Agent compute (pod/VM) | Point at localhost | Yes | +2-5ms | Infrastructure |
| 6 — Post-Gateway | Gateway config | None | Yes (via gateway) | +5-15ms | Infrastructure |
| 7 — Observer (Audit) | Mirror mechanism | None | Yes (async) | 0ms | None (detection only) |
Positions can be combined for defense in depth — for example, deploying an inline proxy for outbound tool calls alongside a sidecar for per-agent isolation.
Passthrough vs. Verdict API
Two SDK integration patterns exist for customers who own their server. Choose based on whether ShieldAgent needs to forward traffic to a separate upstream.
| Scenario | Pattern | How it works |
|---|---|---|
| Your server is a gateway to a different upstream | Passthrough (apiProxy / mcpProxy) | SDK sends request to ShieldAgent proxy. Proxy scans, then forwards to the real upstream and returns the response. |
| Your server IS the tool provider (no separate upstream) | Verdict API (scan) | SDK sends the payload to ShieldAgent. ShieldAgent returns a verdict (allow/block/human_review). Your server executes or rejects locally. |
Enforcement Model
All deployment positions run the same security pipeline — detection, policy evaluation, risk scoring, and audit are always handled by ShieldAgent. What differs is who enforces the verdict. Position 1 provides infrastructure-enforced blocking: ShieldAgent sits inline and stops the request before it ever reaches upstream. Positions 2 and 3 use the Verdict API: ShieldAgent detects threats and returns a verdict; your server code enforces it. This shared responsibility model is standard in the security industry — analogous to AWS WAF Count vs. Block mode or CrowdStrike Detect vs. Prevent mode.
Enforcement Comparison
| Position | Enforced by | Block mechanism | Guarantee |
|---|---|---|---|
| 1 — Inline Proxy | ShieldAgent | Proxy drops / rejects the request | Infrastructure — cannot be bypassed |
| 2 — Verdict API (REST) | Your server code | Your handler throws or returns error | Code-level — depends on implementation |
| 3 — Verdict API (MCP) | Your server code | Your tool handler rejects | Code-level — depends on implementation |
| 5 — Sidecar Proxy | ShieldAgent | Sidecar drops / rejects the request | Infrastructure — per-agent isolation |
| 6 — Post-Gateway | ShieldAgent | Proxy drops / rejects after gateway | Infrastructure — for gateway-routed traffic |
| 7 — Observer | None | No blocking — detection only | No enforcement guarantee |
Responsibility Matrix
| Responsibility | Positions 1 / 5 / 6 (Proxy) | Positions 2 & 3 (Verdict API) | Position 7 (Observer) |
|---|---|---|---|
| Threat detection | ShieldAgent | ShieldAgent | ShieldAgent |
| Policy evaluation | ShieldAgent | ShieldAgent | ShieldAgent |
| Risk scoring | ShieldAgent | ShieldAgent | ShieldAgent |
| Audit trail | ShieldAgent | ShieldAgent | ShieldAgent |
| Compliance documentation (Annex IV) | ShieldAgent | ShieldAgent | ShieldAgent |
| Blocking threats | ShieldAgent — infrastructure-guaranteed | Customer — code-level, verified via confirmExecution() | Not available — detection only |
| Enforcement verification | Automatic (proxy blocks before forwarding) | Optional — call confirmExecution() to close the audit loop | N/A |
Compliance Framework Impact
| Framework | Positions 1 / 5 / 6 (Proxy) | Positions 2 & 3 (Verdict API) | Position 7 (Observer) |
|---|---|---|---|
| SOC 2 CC6.1 (Logical access controls) | ShieldAgent is the complete logical access control. | ShieldAgent provides detection + audit. Your enforcement code is part of the combined control evaluated by auditors. | Detection and audit only. Does not satisfy logical access control requirements alone. |
| ISO 42001 A.6.2.6 (AI system monitoring) | Fully compliant. | Fully compliant — monitoring is provided regardless of enforcement topology. | Fully compliant — monitoring and audit are provided. |
| EU AI Act Art. 9 (Risk management) | ShieldAgent identifies, analyzes, evaluates, and mitigates threats. | ShieldAgent identifies, analyzes, and evaluates. You mitigate by enforcing verdicts. Both parties must be documented in Annex IV. | Identifies and analyzes only. Does not mitigate — does not satisfy blocking requirements for high-risk systems. |
| EU AI Act Art. 14 (Human oversight) | Human review via ShieldAgent dashboard. | Human review via dashboard + your explicit enforcement decision after receiving a human_review verdict. | Human review via dashboard (advisory only — no enforcement mechanism). |
| EU AI Act Annex IV (Technical documentation) | Auto-generated with infrastructure-enforced blocking proof. | Auto-generated — must include your enforcement mechanism and confirmExecution() rates as supporting evidence. | Auto-generated — must document that enforcement is not provided and describe compensating controls. |
Infrastructure Topologies
Independent of which position you use, you also choose how the ShieldAgent infrastructure itself is deployed. These topologies apply to the proxy and management API — choose based on compliance requirements and operational budget.
Shared Multi-Tenant
All tenants share one proxy deployment. Isolation is logical — enforced by JWT claims, row-level security in PostgreSQL, and per-tenant rate limits. Lowest infrastructure cost.
Enterprise plans include dedicated isolation options. Contact your account team for details.
Component Overview
ShieldAgent is a monorepo with separate apps and shared packages. You only deploy the components you need — at minimum, the proxy, API, and a PostgreSQL database.
| Component | Role |
|---|---|
| Proxy | The security chokepoint. Intercepts every MCP message and REST API call. Runs the security pipeline before forwarding to upstream. |
| Management API | REST API for managing tenants, agents, policies, audit, risk, and incidents. Real-time events via WebSocket. |
| Dashboard | Security dashboard. Real-time monitoring, policy management, audit log exploration, agent registry. |
| MCP Scanner | CLI tool that inspects MCP servers for supply-chain risks, tool manifest drift, and dependency vulnerabilities. |
| ML Classifier | Optional sidecar for ML-based prompt injection detection. Falls back gracefully when unavailable. |
| Audit Trail | Tamper-evident event log with export adapters. |
| Risk Engine | Risk scoring, behavioral analysis, trend monitoring, and alerting. |
| Policy Engine | Compiles and evaluates policy rules. Runs in-process inside the proxy. |
Supported Transports
The proxy supports both network and process-based MCP transports. Choose based on how your agent framework communicates with MCP servers.
| Transport | Protocol | Use case |
|---|---|---|
| HTTP/SSE | MCP over HTTP with Server-Sent Events | Network agents, multi-replica deployments |
| stdio | MCP over stdin/stdout | Agent spawns proxy as child process (local dev, desktop apps) |
| REST API proxy | HTTP methods forwarded to upstream | Pass-through for non-MCP REST APIs with policy enforcement |
Scaling Considerations
Horizontal proxy scaling
The proxy is stateless on the request path. Add replicas behind a load balancer. Redis is shared across replicas for rate limiting, session tracking (SSE affinity), and the upstream routing cache. A Kubernetes HPA targeting CPU is the recommended scaling strategy.
SSE connection affinity
Server-Sent Event connections are long-lived. The proxy uses Redis-backed session tracking to route reconnects to the same replica. Configure your load balancer with sticky sessions (sessionAffinity: ClientIP in Kubernetes) as a fallback.
Database
PostgreSQL is the source of truth for all configuration and audit data. Use a managed database (RDS, Cloud SQL, Neon) with a read replica for audit log queries. The audit writer is designed to degrade gracefully under database pressure.
ML classifier
The ML classifier is optional. When unavailable, the proxy continues to detect threats using built-in detection methods. Scale the classifier independently of the proxy — it is CPU/GPU-bound and benefits from dedicated nodes.
Minimum Required Services
Not all components are required for every deployment. Start with the essentials and add services as needed.
Proxy · Management API · PostgreSQL
Dashboard · Redis (rate limiting + session affinity)
ML Classifier (enhanced injection detection) · MCP Scanner (supply-chain auditing) · Grafana + Prometheus (observability)