# Multi-Layer Policy for Securing AI Agents

> Source: <https://www.tigera.io/blog/multi-layer-policy-for-securing-ai-agents/>
> Published: 2026-06-03 18:58:09+00:00

As part of our work at Tigera building products that create secure runtime environments for enterprise agents at scale in the real world, one small part of this puzzle I think about a lot is policy, and runtime enforcement of policy, and how to create a comprehensive secure runtime, configured from one place. The more companies we talk to trying to lock down and secure these platforms at runtime, the more I believe [AI Agent security](https://www.tigera.io/learn/guides/ai-agent-security/) needs policy in multiple places, not just one (e.g., not just at the gateway layer), and ideally expressed in the same policy language.

At the L7 gateway layer, every agent call is observable: who is calling, what they are calling, what attributes both sides carry, what the requested action is. This is where you decide whether an agent should be permitted to talk to a particular MCP server, invoke a particular tool, delegate to another agent, or call a particular LLM. The atoms of policy here are identity, action, resource, and context.

At the agent runtime layer, or kernel layer in a container, what the agent does inside its own runtime is observable: syscalls, file access, library loads, network connections that bypass the brokered channel. This is where you decide whether the agent can read a file, open a socket, spawn a subprocess, or load a library. The atoms of policy here are processes, paths, file descriptors, and system calls.

Both layers are necessary. The gateway alone cannot constrain what an agent does inside its runtime once it holds a token. The kernel alone cannot reason about identity, delegation, or multi-hop intent. Building policy at one and not the other leaves a category gap.

The architectural choice that makes this work in practice is using one policy language for both. We use Cedar at the gateway and interpret and translate Cedar to [eBPF](https://docs.tigera.io/calico/latest/about/kubernetes-training/about-ebpf) policy for the kernel: same policies, two enforcement points, one place to author and review.

## Policy at the gateway: enforcing agent intent

The gateway sees intent. It is the right place to enforce *who can talk to whom, under what conditions, with what level of human oversight.*

A Cedar policy that constrains which agents can invoke which tools:

```
permit (
  principal in Group::"finance-agents",
  action == Action::"invokeTool",
  resource in ToolSet::"finance-readonly"
) when {
  principal.risk_level == "low" &&
  context.delegation_depth <= 3
};
```

This policy expresses several things that are hard to model in RBAC or in a network policy. The principal is identified by group membership but constrained by attribute (`risk_level`

). The resource is a typed set of tools. The condition includes a check on delegation depth; agents three hops deep in a delegation chain are refused even if they pass every other check.

The gateway layer naturally enforces delegation rules, per-hop token issuance with scope reduction, agent-to-MCP tool authorization, agent-to-LLM constraints, human-in-the-loop hooks for high-stakes actions, and attribute-based decisions across all of these.

What the gateway cannot do is constrain what happens after it issues a token. Once the agent has the credential, the kernel is the only layer that sees what the process actually does with it.

## Policy at the kernel: constraining agent behaviour

The kernel sees behaviour. It is the right place to enforce *what an agent process is allowed to do at the operating system level*, regardless of what tokens it holds.

A baseline sandbox for an agent workload, expressed conceptually in the same Cedar policy model and compiled to BPF programs at runtime:

```
permit (
  principal in AgentClass::"data-analyst",
  action in [Action::"readFile", Action::"writeFile"],
  resource is FilePath
) when {
  resource.path like "/workspace/analyst-*" ||
  resource.path == "/var/run/secrets/analyst-key"
};
forbid (
  principal in AgentClass::"data-analyst",
  action == Action::"connectNetwork",
  resource is NetworkDestination
) unless {
  resource.host in DestinationSet::"approved-llm-endpoints" ||
  resource.host == "lynx-gateway.internal"
};
```

The compilation target is BPF LSM hooks, cgroup network hooks, and file access enforcement at the inode boundary. When the agent process steps outside what the policy permits, the kernel refuses the operation – `EPERM`

for the syscall, `ECONNREFUSED`

for the network connection, `ENOENT`

for the file access. The agent gets the same error it would get for any prohibited operation, regardless of what credentials it holds.

The kernel layer naturally enforces file access boundaries, network egress restrictions, syscall whitelisting, library load constraints, and process-spawn limits. The same observation pipeline that feeds enforcement also feeds threat detection.

What the kernel cannot do is reason about why an action is being attempted. It sees a `connect()`

system call. It does not know whether the call is part of a legitimate multi-hop delegation that the gateway already authorized. That context only exists at the L7 layer.

## The dual-layer architecture

The architectural integration matters as much as either layer in isolation. Cedar policies authored once, evaluated at the gateway, compiled to BPF for kernel enforcement. The compilation is not magical—only the substrate-relevant subset of Cedar policies compiles. The rest stay at the gateway. Either way, security teams write Cedar; the runtime decides which layer is the right one to enforce at.

This integration is what makes the dual-layer approach operationally sustainable. Without one policy language, you end up with two policy stores, two review processes, two engineering teams, and inevitable divergence between what the gateway permits and what the kernel allows. With Cedar at both layers, the policy you wrote is the policy that gets enforced everywhere.

## Why single-layer policy isn’t enough for AI agent security

Policy at the gateway alone defends against unauthorized callers and out-of-scope actions. It does not defend against a compromised agent that has a legitimate token and uses it to do things outside its intended behaviour, like read credential files, exfiltrate data through side channels, and escalate privilege inside its runtime.

Policy at the kernel alone defends against process-level misbehaviour. It does not understand identity or delegation, cannot reason about whether a network connection is part of a legitimate multi-hop chain, and has no way to enforce human-in-the-loop approval flows.

Combined, the two layers cover the threat model that either layer alone misses. A compromised agent with a legitimate token can still call out through the gateway, but its local actions are constrained by the kernel sandbox. A misconfigured Cedar policy at the gateway is mitigated by the substrate baseline. A shadow agent that never registered is observed and contained at the kernel.

For Kubernetes-native enterprises building agent infrastructure into regulated workloads, this is the architecture worth building toward. Gateway policy for what agents are allowed to ask for. Kernel policy for what they are allowed to do. Same language for both.

## Going deeper

Multi-layer policy is one piece of a larger problem: making AI agent infrastructure accountable end-to-end. Traceability, authorization provenance, identity and ownership, policy-based governance at scale, and human oversight and intervention—they all have to work together.
