attenu

Cedar vs OPA vs Casbin vs attenu-guard: permissions for AI agents

Updated 2026-08-26. Cedar, Open Policy Agent and Casbin are mature, Apache-2.0 authorization libraries; this page is about the question an agent handoff raises that they were not built to answer, and how to run them next to attenu-guard.

An AI agent permissions library decides what an agent may do at the moment it calls a tool, and — when the agent delegates — what the sub-agent may do. Cedar, Open Policy Agent (OPA) and Casbin answer the first question against rules someone wrote. attenu-guard answers the second: at each handoff it computes the sub-agent's permissions so that they are never wider than the parent's, checks every tool call against them before the tool runs, and writes a hash-chained audit log that an auditor verifies offline, with the vendor absent.

Short answer. If your callers are known principals and your rules are stable, a request-time decision from Cedar, OPA or Casbin is the right tool. If your callers are sub-agents that did not exist a second ago and should hold less than their parent, you need the permission set computed at the handoff and carried down the chain — that is what attenu-guard does, and you can run it in the same process as any of the three.

from attenu_guard import Authority, Guard, RowLimit, EgressRank

orchestrator = Guard.issue("orchestrator", Authority(
    scopes={"crm.*", "mail.send"}, ceilings=[RowLimit(100_000), EgressRank("any")], ttl=3600))

# The child gets what the parent held ∩ what the task needs — never wider than the parent.
summarizer = orchestrator.delegate("summarizer", Authority(
    scopes={"crm.read"}, ceilings=[RowLimit(5_000), EgressRank("none")], ttl=900),
    task="summarize Q3 pipeline")

summarizer.check("crm.read", context={"rows": 4_200})        # Decision(allowed=True)
summarizer.enforce("crm.export", context={"egress": "any"})  # raises AuthorityDenied, logged
pip install attenu-guard          # zero runtime dependencies; adapters for 18 frameworks as extras

What do Cedar, OPA and Casbin decide?

Each evaluates a request — a principal, an action, a resource and some context — against policy an author wrote, and returns allow or deny. Cedar (AWS) does it with a typed, analysable policy language and hierarchical entities; AWS Bedrock AgentCore Policy applies Cedar to agent tool calls. OPA does it with Rego over arbitrary JSON input, as a library, sidecar or service, with decision logs and signed policy bundles. Casbin does it with a model file plus policy rules (ACL, RBAC with role inheritance and domains, ABAC) as an in-process library in many languages. All three are good at the job they were built for.

What happens when an agent delegates to a sub-agent?

A new caller appears whose permissions did not exist a second ago. A request-time decision can check what that caller asks for against a policy; it cannot know what the caller should hold unless something computed it at the handoff and carried it down. You can carry a delegation chain in OPA's input or model it as Cedar entities — the computation is then yours to write, test and keep correct at every hop, and at depth three the grandchild's list has no relation to the root's unless you built one. attenu-guard makes the relation the default: Guard.delegate() returns a child whose scopes are the intersection with the parent's, whose ceilings take the tighter bound, whose TTL is the shorter; chain ceilings on depth, fan-out and aggregate spend hold across every hop; revoke() on any node denies every descendant.

How do Cedar, OPA, Casbin and attenu-guard compare?

Cedar Open Policy Agent Casbin attenu-guard
What gets checked a request against policies (principal, action, resource, context) a query against Rego rules and input data a request against a model + policy file a tool call against the calling agent's computed permissions
Where the permission set comes from an author writes it an author writes it an author writes it computed at the handoff from the parent's set and the task's request; attenu-derive can compute the request from the app itself
Parent → sub-agent relation hierarchical entities; the narrowing is yours to compute any relation you encode in the input; the narrowing is yours to compute role inheritance and domains; no parent → child narrowing at a handoff built in: a child is never wider than its parent; ceilings on depth, fan-out and spend; cascade revocation
Where it runs your process (library) or a service library, sidecar or service your process (library) your process, at the framework's public tool-call hook
Agent-framework adapters AgentCore Policy (Strands, Bedrock) community integrations none published for agent frameworks (checked 2026-08-26) 18 frameworks, unmodified — LangGraph, LangChain, CrewAI, Google ADK, OpenAI Agents, Claude Agent SDK, Pydantic AI, AutoGen, smolagents, Strands, LlamaIndex, Semantic Kernel, Agno, Haystack, CAMEL-AI, Microsoft Agent Framework, AG2, A2A
Audit record decision logs you host decision logs you host; signed policy bundles logging hooks hash-chained, Ed25519-signed log; attenu-guard verify checks integrity and child ⊆ parent from the exported bundle alone, vendor absent
Measured on delegation (self-reported, CI-gated, bounds) 8,783 / 8,783 over-reach attempts denied · 43,128 injection variants, 0 widened · 0 benign blocks across 21 scenarios · enforced live across a real chain
Licence Apache-2.0 Apache-2.0 Apache-2.0 Apache-2.0

Cells for Cedar, OPA and Casbin describe their documented capabilities as of 2026-08-26; corrections are welcome through the contact page.

When is a request-time decision the right tool?

  • You have a stable set of human-written rules about who may do what to which resources, and every caller is a known principal. That is the shape all three optimise for, with mature tooling and, for Cedar, formal analysis of policies.
  • You need one decision reused across many services from one place.

When do you need attenu-guard as well?

  • The caller is a sub-agent whose permissions should be less than its parent's, and you would rather the relation held by construction than by convention.
  • There are three or more hops, or fan-out, or a spend budget that must hold across the whole chain.
  • Someone who is not you — an auditor, a customer's security team, a regulator — needs to check afterwards what was allowed and denied, without access to your policy server or your logs.

Can you use attenu-guard with Cedar or OPA?

Yes, in the same process. attenu-guard decides what the sub-agent holds and checks each tool call against it at the framework's hook; Cedar or OPA keeps deciding whether a human principal may touch a resource. The audit bundle records the agent-side decisions; your decision point keeps its own log.

What this page does not claim

Not that Cedar, OPA or Casbin are insecure, slow or wrong: they are not built for handoffs, which is a different job. Not that attenu-guard replaces resource-level authorization: it does not model resources at all. The numbers in the attenu-guard column are self-reported CI gates in a single-maintainer project; what is proven states each gate, its bound, and what is not met.


Install: pip install attenu-guard · Read the evidence and its bounds: what is proven · Embedding it in a platform: contact