August 25, 2026
Securing Autonomous AI Agents: Building a Zero-Trust Control Plane with MCP, OPA/Rego, and…
What happens when you assume the AI agent itself may already be compromised?

By Saki George
9 min read
AI agents are rapidly moving beyond answering questions.
They can read repositories, invoke APIs, create issues, interact with cloud infrastructure, modify configuration, execute tools, and participate directly in engineering workflows.
That capability creates a security question I wanted to explore:
What happens when the AI model itself cannot be trusted to make the final authorization decision?
Prompt engineering alone does not solve this problem.
An agent can be prompt-injected. Its context can be manipulated. A model can misunderstand instructions. Tool descriptions can be abused. Credentials can be overprivileged. And an otherwise legitimate agent can begin behaving in ways that were never intended.
So I built an AI Agent Security Control Plane around a different assumption:
The model may be compromised. Security controls outside the model must remain authoritative.
The result is a working security engineering prototype combining MCP-style tool enforcement, OPA/Rego policy-as-code, signed agent identity, human authorization, four-eyes approval, behavioral risk scoring, detection, correlation, and automated quarantine.
The current release includes 85 automated security and adversarial tests and culminates in an end-to-end attack scenario where a compromised agent attempts privileged operations and is ultimately contained
The Security Problem
A conventional AI-agent architecture can look deceptively simple:
The dangerous assumption is that because the agent was instructed not to perform a certain operation, it won't.
That makes the model part of the security boundary.
I wanted the opposite architecture.
Designing the Control Plane
I separated the system into several independent security layers.
here are two especially important architectural boundaries.
OPA/Rego acts as the Policy Decision Point.
It answers questions such as:
- Is this role permitted to use this tool?
- How sensitive is this operation?
- Is this operation permitted in this environment?
The MCP security gateway acts as the Policy Enforcement Point.
It handles runtime controls such as:
- identity verification
- quarantine checks
- behavioral risk
- approval requirements
- tool registration
- execution
- telemetry
- containment
In simple terms:
1. The Agent Does Not Get to Declare Its Own Identity
The first boundary I implemented was agent identity.
Agent requests carry signed identity claims, including information such as the actor and role.
The control plane verifies those claims before evaluating authorization.
This allows the gateway to reject scenarios such as:
This matters because trusting a model-generated field such as:
would not constitute authorization.
The role has to be independently verified.
2. Tool Access Is Default-Deny
The gateway maintains an explicit registry of tools that agents may request.
If the model invents a tool name, attempts to access an unregistered capability, or reaches outside the approved interface, the request is denied.
Conceptually:
This reduces the possibility that model creativity accidentally becomes privilege expansion.
Unknown capability means no capability.
3. Moving Authorization into OPA/Rego
One of the most important stages of the project was externalizing authorization into Open Policy Agent and Rego.
Actions are classified as:
A simplified example of the model looks like:
For example, a legitimate development read produced:
Evidence: OPA READ_ONLY authorization
The important point isn't simply that OPA returns ALLOW.
It also returns the security classification, allowing the enforcement layer to determine what additional controls are necessary.
4. An ALLOW Decision Does Not Always Mean Execute
This became another important design principle.
Suppose OPA returns:
It means:
Policy permits this request to enter the sensitive-action authorization workflow.
The gateway interprets classifications approximately like this:
Evidence: OPA SENSITIVE classification
5. Human Approval Cannot Just Be approved=true
Adding a human approval button is easy.
Building an approval mechanism that cannot be trivially bypassed is harder.
I didn't want this:
approved = trueapproved = truebecause a generic approval flag creates several obvious problems.
Can it be replayed?
Can the action be modified after approval?
Can the requester approve their own request?
Can an unauthorized reviewer approve it?
Can an old approval be reused?
Can an approval for one operation authorize another?
So approvals in the prototype are bound to the exact requested action.
The approval context includes factors such as:
The action itself is cryptographically bound to its approval context using SHA-256.
If the requested action changes after approval:
Approvals also expire and are single-use.
That produced negative-path tests including:
6. Four-Eyes Authorization for Critical Actions
Critical operations require stronger controls.
For those actions, I implemented a four-eyes authorization model.
Two distinct authorized reviewers must approve the same operation.
The system explicitly tests attempts to bypass this requirement.
Evidence: Four-eyes attack testing
This is where the prototype began looking less like an AI demo and more like an enterprise authorization system.
7. Separation of Duties
The requesting actor cannot approve its own privileged operation.
Likewise, not every human identity qualifies as a security reviewer.
The control plane verifies reviewer authorization separately from agent authorization.
That means:
For critical operations:
oth must also be authorized.
This makes the approval workflow a security boundary rather than simply a user-interface step.
8. OPA Failure Must Fail Closed
Externalizing policy creates another security question:
What happens if the policy engine itself fails?
If OPA crashes and the gateway interprets that as permission, the architecture becomes weaker rather than stronger.
So I explicitly tested:
- OPA unavailable
- malformed policy response
- invalid decision
- policy execution errors
- unexpected classifications
The result is always:
Policy uncertainty
↓
DENYPolicy uncertainty
↓
DENYFail-closed behavior is one of the project's core security invariants.
9. Authorization Is Only the Beginning
Preventive controls alone aren't enough for autonomous systems.
I wanted the control plane to react to behavior over time.
So every security decision produces structured telemetry.
That telemetry feeds detection logic.
For example, attempts to perform prohibited production writes can generate detections such as:
AI-001
AI-002AI-001
AI-002Repeated denied activity can then generate a correlated higher-order event:
AI-003
Repeated denied actions by AI agentAI-003
Repeated denied actions by AI agentNow the system isn't simply answering:
Is this individual request allowed?
It is also asking:
What has this actor been doing recently?
That leads into adaptive risk.
10. Adaptive Behavioral Risk
The prototype maintains behavioral risk for the agent.
Repeated suspicious activity increases that risk.
For example:
This means an action that might ordinarily be permitted can become prohibited because the actor's security state has changed.
That is an important distinction from static RBAC.
11. Quarantine Must Override Normal Authorization
Once an actor is quarantined, I wanted to prove that it could not simply switch to a less sensitive operation and continue working.
So the final containment test intentionally attempts a normally permitted development read after quarantine.
The result:
The Final Test: Assume the Agent Is Already Compromised
The final adversarial scenario starts with a deliberately hostile assumption:
ASSUMPTION: agent is compromisedASSUMPTION: agent is compromisedThe objective isn't to see whether the prompt can convince the model to behave.
The objective is to determine whether external controls still work when the model doesn't.
The compromised agent attempts three prohibited production-sensitive operations.
Attack 1
GATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 30 / MEDIUMGATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 30 / MEDIUMAttack 2
GATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 60 / HIGHGATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 60 / HIGHAttack 3
GATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 90 / CRITICALGATEWAY: DENY
DETECTIONS: AI-001, AI-002
ADAPTIVE RISK: 90 / CRITICALThe detection layer then correlates the repeated behavior:
AI-003
Repeated denied actions by AI agentAI-003
Repeated denied actions by AI agentThe containment layer responds:
CONTAINMENT: QUARANTINEDCONTAINMENT: QUARANTINEDFinally, the compromised agent attempts a normally allowed READ_ONLY development operation.
And the integrated scenario concludes:
Evidence: Final integrated adversarial scenario
For me, this is the most important result in the entire project.
The system doesn't depend on the compromised agent voluntarily obeying the rules.
85 Automated Security Tests
The project wasn't built as one large implementation followed by testing at the end.
I built it incrementally.
Each security boundary was implemented, attacked, tested, and retained in the regression suite before moving to the next layer.
The progression eventually reached:
Ran 85 tests
OkRan 85 tests
Ok
The test suite covers areas including:
- identity tampering
- expired credentials
- role escalation
- unregistered tools
- policy classification
- Python and OPA policy parity
- OPA failure
- approval bypass
- approval mutation
- approval expiration
- approval replay
- reviewer authorization
- self-approval
- four-eyes bypass attempts
- adaptive risk
- detection
- correlation
- quarantine
- post-containment denial
Testing adversarial paths turned out to be just as important as testing successful authorization.
What I Learned
Several design principles became much clearer while building this project.
1. The LLM should not be the authorization boundary
Prompt instructions are useful behavioral controls.
They are not substitutes for deterministic authorization.
2. Model intent and execution authority should be separate
The model proposes:
"I want to execute X.""I want to execute X."The control plane determines:
"Are you actually permitted to execute X?""Are you actually permitted to execute X?"Those are different decisions.
3. Human-in-the-loop needs security engineering too
Adding a human approval step doesn't automatically make an AI system secure.
Approval needs identity, authorization, integrity binding, expiration, separation of duties, and replay protection.
4. Policy and enforcement should remain separate
OPA/Rego works well as a Policy Decision Point because policy can evolve independently of gateway execution logic.
The gateway remains responsible for enforcing the resulting decision.
5. Authorization should consider behavior
Static identity and RBAC answer:
Who are you and what you normally do?
Adaptive risk adds:
What have you been doing?
That becomes increasingly important as autonomous systems operate over longer periods.
6. Security systems need a containment state
Eventually, repeatedly evaluating the same malicious actor isn't enough.
There needs to be a point where the system says:
Stop.
This actor is no longer trusted to interact with protected tools.Stop.
This actor is no longer trusted to interact with protected tools.That is the role of quarantine.
7. Design for model compromise
Perhaps the biggest lesson was this:
The strongest AI security architecture isn't one that assumes the model will never fail. It is one that remains secure when the model does fail.
Prototype vs. Production
This project is intentionally a security engineering prototype.
A production deployment would preserve the trust boundaries while replacing several local components with enterprise services.
That could include:
I'd also want production capabilities around policy signing, versioning, rollout, rollback, distributed rate limiting, resilience, data classification, and centralized security analytics.
The prototype's purpose is to establish and test the security architecture and trust boundaries before introducing that infrastructure complexity.
Where This Leaves AI Agent Security
AI security discussions often focus on protecting the model:
- prompt injection defenses
- input filtering
- output filtering
- guardrails
- model alignment
Those controls matter.
But autonomous agents introduce another security layer:
Protecting the systems the model can act upon.
Once an AI agent can invoke tools, access repositories, call APIs, modify cloud resources, or initiate workflows, traditional security engineering concepts become relevant again:
identity, authorization, least privilege, separation of duties, policy enforcement, telemetry, detection, risk, and containment.
The difference is that the actor making requests is now partially autonomous.
That's why I believe AI-agent security will increasingly look like a convergence of:
The model can remain probabilistic.
The security boundary doesn't have to be.
Final Result
The final architecture follows one principle:
Model intent is advisory. External security controls are authoritative.
The compromised agent was allowed to request actions.
It was not allowed to grant itself permission.
After repeated malicious behavior, the control plane detected the activity, raised behavioral risk, correlated the events, quarantined the actor, and revoked further access.
85 automated security tests passed.
The final integrated compromised-agent scenario passed.
And most importantly:
Compromised model intent did not become privileged tool execution.
Project
The complete implementation, architecture, threat model, adversarial tests, OPA/Rego policies, and validation evidence are available in my public GitHub project: https://github.com/georgesaks/ai-agent-security-control-plane
AI Agent Security Control Plane
Use your GitHub repository link here.
Release: v1.0.0