AI Infrastructure Security
- agent/run identity
- guarded tool execution
- LLM choice separated from authorization
- explicit SDK trust boundary
AI Infrastructure Security
Least-privilege identity and authorization for AI agent tool execution, implemented as an SDK-first guard for cooperative tool, MCP, and LangChain paths.
Stack
What This Demonstrates
Problem And Constraints
LLM-driven applications may choose tools dynamically, but the host application must not treat a model-selected tool as an authorized action. AgentTrust explores the boundary between "the model requested this" and "the application authorizes this" with scoped per-run identity and guarded tool execution.
System Architecture
AgentTrust SDK boundary diagram: LLM or agent enters the host application, host routes guarded calls through AgentTrust identity and policy, authorization either denies and audits or allows a guarded adapter to invoke a tool or MCP client. Raw client or tool references are outside the SDK boundary.
requests action
enforced path
AgentTrust SDK
Deny
Allow
allow only
Outside SDK boundary
Code retaining a raw MCP session, raw client, or direct tool reference can bypass SDK-level enforcement.
Components
The host application starts an AgentTrust run, receives a scoped in-process run identity, routes tool or MCP calls through guarded adapters, and gets an allow-or-deny decision before execution. Audit records capture the decision and outcome for calls inside that path.
Component Responsibilities
Owns
Exposes
Depends on
Persistence
No application database; local audit sink is configured by path
Owns
Exposes
Depends on
Persistence
Adapter decisions are recorded through the shared audit sink
Request Flow
The host starts a run for a known agent, AgentTrust establishes scoped run identity from policy, and each guarded tool call is authorized before the underlying tool or MCP client is invoked.
Guarded Tool Execution flow: Host starts run to Policy grants scopes to Per-run identity established to Tool requires scope to Authorize required scope, then branches to deny path: Audit deny to ToolDenied to No execution, or allow path: Execute guarded tool to Audit outcome.
Deny
Allow
Where controls apply
Engineering Decisions
Authorization Failure Behavior
Implemented behavior
A run cannot be started when no policy exists for the agent.
Implemented behavior
The guarded call writes a deny audit event and raises ToolDenied before execution.
Implemented behavior
AgentRun checks expiry before guarded execution and denies expired identities.
Implemented behavior
The JWT verification helper fails closed for covered invalid token cases.
Implemented behavior
The guarded MCP wrapper can fail closed when default-to-tool-name fallback is disabled.
Implemented behavior
Allowed guarded calls audit an error status when the underlying callable raises.
Security Boundaries
then
then
then
Auditability
Threat Model
The threat model is intentionally scoped to SDK-level cooperative enforcement. It is strongest against unauthorized tool selection inside guarded paths and intentionally does not claim protection from raw-client bypass or compromised hosts.
Guarded calls authorize the required scope before execution.
Only applies when the host routes the call through AgentTrust.
Unknown agents and missing scopes fail closed in the guarded path.
Policy authors can still grant overly broad scopes.
Automated tests verify fail-closed expiry and JWT validation behavior.
No revocation or key rotation exists in the current MVP.
Scope grants are explicit and inspectable.
AgentTrust cannot infer business intent or prevent unsafe wildcard grants.
The docs and architecture mark this as outside the SDK boundary.
Code with direct references can call tools without AgentTrust.
None within the SDK-first boundary.
A compromised process can bypass wrappers, read secrets, or alter audit files.
Events are appended under a process lock for cooperative execution.
Filesystem access can modify, truncate, or delete local JSONL audit records.
Verified Runtime Evidence
The primary evidence scenario is a public-safe MCP-style demo proving authorization-before-execution for guarded calls. Credential validation is documented as automated-test evidence, not runtime-demo evidence.
Runtime demo evidence
An ops-reader run is granted only service.read. The allowed read invokes the fake MCP client once; the denied service.restart call raises ToolDenied and leaves the underlying invocation count at zero.
Agent: ops-reader
ALLOW service.read underlying_invoked=True invocation_count=1
DENY service.restart tool_denied=True underlying_invoked=False invocation_count=0
AUDIT ALLOW service.read
AUDIT DENY service.restartAutomated test evidence
Tests cover expired run identities, expired serialized JWTs, tampered tokens, wrong signing secrets, and malformed scope claims.
PYTHONDONTWRITEBYTECODE=1 python3 -m pytest -p no:cacheprovider
48 passed, 3 skipped
Skipped: real MCP SDK integration tests when mcp is not installedRuntime demo evidence
The same demo emits one ALLOW and one DENY audit line with the same synthetic agent/run context, tool, required scope, decision, and execution status.
ALLOW agent=ops-reader run=<synthetic> tool=service.read scope=service.read status=ok
DENY agent=ops-reader run=<synthetic> tool=service.restart scope=service.restart status=not_executedVerified locally with synthetic data for calls routed through AgentTrust guarded execution APIs. This does not demonstrate process isolation or protection against raw-client bypass.
View Full Runtime Evidence →Verified Behavior
The MCP-style evidence demo allows service.read for ops-reader and invokes the fake client once.
The same run denies service.restart with ToolDenied because only service.read is granted.
The denied MCP-style call leaves the fake underlying service.restart invocation count at zero.
The demo prints ALLOW service.read and DENY service.restart audit records for the same run.
Expired, tampered, wrong-secret, and malformed-scope credential cases fail closed in tests.
Starting a run for an agent missing from policy raises PolicyError.
Direct, async, decorator, MCP wrapper, and LangChain guarded paths are covered by local tests.
The latest local run reported 48 passed and 3 skipped; skipped tests were real MCP SDK integration tests because the dependency was not installed.
Trade-offs And Limitations
Future Extensions