MAPL: MACAW Agentic Policy Language · Open spec

Express and verify intent, formally.

A policy language and composition algebra for agentic actions. Every action is verified against policy before it runs, and provably scoped to what the policy allows.

163/164
τ²-bench tasks under written policy
0/949
AgentDojo attacks that took effect
Lean
proofs of the language’s laws
5 ms
per decision

Why MAPL.

Policy languages were built for a pre-agentic era: known callers making known requests. Agents act on behalf of people, delegate to other agents, chain calls across services owned by different teams, decide what to do at runtime, and occasionally lie.

  • Declarative and verifiable

    Four parts, no code. Policies are validated before they deploy, and every decision is deterministic and reproducible.

  • Bound at call time

    Policies name scopes, not people. Your IdP binds the caller when the call arrives, so a role change needs no policy change.

  • Many authors, one algebra

    Caller, service and data owners each write their own policy. They combine by intersection: authority only narrows, and a denial is final.

  • Dynamic state

    Decisions can depend on approvals, passkey logins and completed steps. A call can wait for an approver, and the agent can’t approve itself.

Every action is provably scoped to what its policies allow. The proofs are mechanized in Lean. The formal foundations, in the guide

A policy has four parts.

Every MAPL policy, at every level, has the same structure.

1

Resources

The allow list: tools, models and data, named scope:name, with wildcards.

"resources": [
  "tool:emp_records/read",
  "llm:openai/*"
]
Learn more

2

Denied resources

The deny list. A denial at any level is final.

"denied_resources": [
  "tool:emp_records/delete",
  "secrets:**"
]
Learn more

3

Parameter constraints

Limits on a call’s arguments, and patterns its arguments may not contain.

"tool:emp_records/read": {
  "limit": { "max": 100 }
}
Learn more

4

Approvals

Attestations a call needs: a manager’s approval, a passkey login, a completed step.

"attestations": [
  "manager_approval",
  "phishing_resistant"
]
Learn more

Minimal, and expressive. Allow and deny lists combine into any boolean rule over operations; constraints can test any decidable condition on arguments; approvals put steps in order. Your first policy

The intersection algebra.

Every party in a call has a policy: the person, the agent acting for them, and the service it calls. MAPL intersects them into one effective policy.

Alicethe person
Claude Desktopthe agent, acting for her
Databasethe MCP server
Effective policyall five, intersected
model
claude-sonnet
set by user:alice
tokens
≤ 1,000
set by app:claude-desktop
rows
≤ 1,000
set by mcp:database

Click any policy to see it in MAPL. Each value in the effective policy is the tightest any party set.

  • model claude-opusrefused: Alice’s policy allows only Sonnet
  • max_tokens 4000refused: Claude Desktop allows at most 1,000
  • query(rows=4000)refused: the database allows at most 1,000
  • claude-sonnet, 1,000 tokens, 1,000 rowsallowed

Resources ∩Denied ∪Constraints tightest winsApprovals ∪The intersection rules

A child can only narrow.

  1. company:macawthe rootmax_tokens ≤ 4,000
  2. bu:financeextends company:macawmax_tokens ≤ 1,000
  3. user:aliceextends bu:financemax_tokens ≤ 8,000

Alice’s policy asks for 8,000 tokens. Her effective limit is still 1,000. There are no overrides.

Inheritance in the guide

Human, agent and claims-based approvals.

Some decisions need more than the request: a person’s say-so, a step that already happened, a scope the caller holds right now. MAPL calls these attestations: facts a call can require, proved and signed by someone other than the agent.

One requirement, three kinds of proof

"tool:payments/send": { "attestations": [
    "payments_scope",from Alice’s token
    "kyc_checked",recorded by a tool
    "manager_approval::{params.amount > 25000}"a person, only over 25,000
] }

Human or agent approval

proved by a person or agent with authority

"approval_criteria": "role:manager"

The call waits. Only approvers who match the criteria can approve it; once approved it runs, and the approval is spent.

Short-lived scopes

proved by the requester’s token

"claim": { "scopes": "Banking.Write" }

Holds only while the token carries the scope. Nothing to approve or store: it ends when the token does.

System state

proved by a tool, after it runs

"internal": true

A tool records a fact: identity verified, data anonymized, a classifier’s verdict. Later calls can require it.

A person is present

proved by the login

"phishing_resistant"

Minted only from a passkey or hardware-key login. An agent holding a password can’t have it.

How an approval is routed

  1. Alice’s agentpayments.send(amount = 30,000)
  2. MAPL holds the callpending · for alice · approval_criteria: role:manager
  3. Who can see it
    BobIdP token roles: managersees it, approvesCarolIdP token roles: analystdoesn’t see itThe agentthe requestercan never approve
  4. The call runsapproval signed by Bob · spent

A requirement can depend on the call, like the amount above, and a condition that can’t be evaluated requires the proof. Approvals can be single-use or expire; a denial or a timeout fails the call; and when two policies name approvers, the approver must satisfy both. Attestations in the guide

Programmable verification pipeline, with hooks.

Every call passes eight stages. Three are hooks for your own verification logic, in Python.

Extractoryour code

Your extractor reads a value in the call, such as a SQL string or a JSON body, and returns facts policy can test. It decides nothing on its own.

extract(value, **config) -> dictLibrary: secrets. Or write your own.

Hooks in practice.

Hooks make domain-specific verification easy to add.

llm:openai/chat.completions“Summarize this config: AWS_KEY=AKIAIOSFODNN7EXAMPLE …”

  1. Resolve
  2. Extractoryour code
  3. Check
  4. Input verifieryour code
  5. Approve
  6. Execute
  7. Result processoryour code
  8. Sign
  1. Resolve

    Alice’s policies, the agent’s and the model service’s combine

  2. Input verifier

    secret_scanner reads the prompt and finds an AWS key

  3. Outcome

    RefusedThe prompt never reached the model.

Hooks in the guide →

How MAPL compares.

Keep OPA, Cedar and IAM for the access they already control. MAPL adds what agents need on top: authority that follows the person through every agent and service, approvals, and checks on what each call actually does.

CapabilityDetailMAPLCedarOPA/RegoAWS IAMOpenFGANeMo Guardrails
CompositionAuthority only narrows as policies compose, proved●One intersection over every policy: authors, org hierarchy, service hops. Lean-proved that no author can loosen another’s rule.◐Any author’s permit adds authority. Source◐Hand-coded per policy. Source◐Intersects account layers inside AWS only; no hops, no proof. Source○Grants are a union. Source○No composition algebra. Source
Explicit deny cannot be overridden●Any policy’s deny is the result’s deny.●Forbid overrides permit. Source◐Depends on how the rules are written. Source●An explicit deny overrides any allow. Source◐Exclusion only. Source◐In code, not a law of the language. Source
Caller and service policies both constrain access●The caller’s policies and the receiving service’s policy are evaluated separately, then intersected.◐One policy set per request; a service’s own rules must be written into it. Source◐Possible if each service writes and queries its own policy. Source◐Identity- and resource-based policies both apply, inside AWS. Source◐Relations on both sides can be modeled by hand. Source○Not supported. Source
Policies attached to data and objects●An object policy binds whoever consumes the data, whatever their role.●Resource scope and entity hierarchy. Source◐Custom. Source●Resource-based policies. Source●Object relations are its core. Source○Not supported. Source
Restrictions follow derived data through references●Derived objects carry their source’s policy through references.○No notion of derived data. Source◐Can be modeled with custom data. Source○Not supported. Source◐Can be modeled with relations between objects. Source○Not supported. Source
Identity and delegationIdentity bound from IdP claims at call time●Filled from validated claims; policies never name principals.◐Through AWS Verified Permissions. Source◐Hand-coded. Source◐AWS principals. Source◐Tuples written in advance. Source○Not supported. Source
Authority narrows at every agent hop●Person → agent → service → sub-agent, one layer per hop.○One request, one principal. Source◐Custom. Source◐Role chaining inside AWS. Source◐Usersets can model it; grants union. Source○Not supported. Source
Agent actionsNative model, tool and MCP resources●Tool calls, MCP, model calls and effects such as shell, files and network are first-class resources.◐Tool name and arguments through AgentCore; no effects, approvals or results. Source◐General purpose. Source○AWS APIs only. Source○Not supported. Source◐Centered on the dialog. Source
Model, parameter and token constraints●Allowed models, max_tokens and any parameter limit, at every policy level.◐Conditions on attributes the application passes in. Source◐Expressible in Rego over the request input. Source○AWS APIs only. Source○Models relationships, not call parameters. Source◐Model settings in configuration, not policy. Source
Approvals and evidenceNamed approvers, conditions, pending decisions, expiry●A human or agent approver named by policy, required on stated conditions, with timeouts and expiry.○Allow or deny only. Source◐Built by the application. Source○Allow or deny only. Source○True or false only. Source◐In-chat confirmation, with no approver identity. Source
Signed, single-use evidence the agent can’t forge●Approvals, claims and tool-recorded facts, signed by someone other than the agent; one-time evidence is spent by the call it allows.○Context comes unsigned from the application. Source○Can verify a JWT; nothing is single-use. Source○Fixed condition keys, such as MFA present; nothing is spent. Source○Contextual tuples are unsigned. Source○Not supported. Source
Extensibility and assuranceCustom logic that can only tighten a decision●Extractors, input verifiers and result processors. Theorem: a decision is at most what the policies allow.○No custom functions. Source◐Arbitrary, with no guarantee for combined rules. Source○Not supported. Source◐CEL conditions, with no guarantee. Source◐Python rails; any rail can override another. Source
Rich logic over structured request data●Conditions over parameters, and extractors that read SQL, JSON and other structured payloads.◐Fixed operators over typed attributes. Source●A general-purpose language over JSON input. Source○Fixed condition operators. Source◐CEL conditions over context. Source◐Arbitrary Python, outside any policy model. Source
Mechanized proofs (Lean)●The language’s laws and the pipeline theorem, mechanized in Lean.●Semantics and validator formalized in Lean. Source○Not supported. Source◐Automated reasoning over policies, not a mechanized language. Source○Not supported. Source○Not supported. Source
Validated before deployment; effective policy explained●Policies are validated before they deploy; the console shows and explains the effective policy.●Validator and SMT-based analysis. Source◐Type checking and tests. Source●Policy validation and Access Analyzer. Source◐Model validation and tests. Source○Not supported. Source

● built in · ◐ partial, or with custom code · ○ not supported. Hover or tap a mark for the reason and the source. From each project’s public documentation, November 2026.

Already on Cedar or OPA? Your policies port to MAPL.

The MAPL skill.

Install the MACAW plugin for Claude Code or Codex and use the /mapl skill. Say what your agents may do; it writes the policy.

You say

“Alice can read employee records, up to 100 at a time. Any update needs a manager’s approval. Deletes aren’t allowed.”

Install

/plugin marketplace add macawsecurity/macaw-plugin
/plugin install macaw-cc@macaw

Tested with Claude (Sonnet, Haiku, Opus), Codex (Terra, Luna, Sol) and Qwen3 8B.

Policy Assistant · in the console

Any policy, explained back.

Open a policy and ask. You get what it allows, what it blocks and its limits, in plain English.

The console

Written policy, stated in MAPL.

τ²-bench gives an airline agent and a retail agent their business rules in plain prose. We wrote them in MAPL and ran the benchmark’s calls through MACAW.

52 of 56
written rules about calls stated in MAPL. The other four are checks the benchmark’s own tools make.
163 of 164
correct calls allowed. The one refused breaks the airline’s own written rule.
36 of 36
rule-breaking calls refused. The benchmark’s own tools accept 19 of them.

The benchmarks

Read the spec. It’s open.

The full language: policies, inheritance, approvals, functions, and the formal foundations.