MAPL Policy Language
MAPL (MACAW Policy Language) defines authorization rules for AI agents. Policies inherit hierarchically from organization to caller level (user or app), with O(log M + N) evaluation that scales to millions of rules.
Why MAPL?
Existing policy languages (OPA Rego, XACML) weren't designed for agentic AI. They lack support for attestations, hierarchical inheritance, and AI-specific primitives.
Hierarchical
Policies inherit and compose. Set organization-wide rules, refine at team and user levels.
Attestation-aware
Condition policies on third-party verifications (DLP scans, compliance systems, approvals).
O(log M + N) Evaluation
Scales logarithmically. Handles millions of policies with sub-millisecond evaluation.
Policy Structure
A MAPL policy defines what resources an identity can access, what is explicitly denied, and constraints on how resources can be used.
- •
policy_idbinds the policy to an identity - •
extendsinherits from a parent policy - •
resourcesare allowed access patterns - •
denied_resourcesare explicit denials
{
"policy_id": "user:alice",
"extends": "team:engineering",
"scope": "user",
"resources": [
"llm:openai/chat.completions",
"tool:search_*",
"data:reports/**"
],
"denied_resources": [
"data:executive/*",
"*.secret",
"*.password"
],
"constraints": { ... },
"attestations": { ... }
}| Field | Description |
|---|---|
| policy_id | Unique identifier binding policy to identity (scope:identifier) |
| extends | Parent policy to inherit from. Effective policy is intersection. |
| resources | Resource patterns this policy allows access to |
| denied_resources | Resource patterns explicitly denied. Cannot be overridden by child policies. |
| constraints | Fine-grained controls: rate limits, parameter restrictions, time-based rules |
| attestations | Capabilities required from external systems. An entry with a namespace prefix instead loads another policy — see Object Policies. |
Resource Patterns
Resources use glob-style pattern matching. Patterns support single-segment wildcards (*) and recursive wildcards (**).
| Pattern | Matches |
|---|---|
| tool:search_* | tool:search_web, tool:search_docs (single segment) |
| data:reports/** | data:reports/q1/sales.csv, data:reports/2024/finance/summary.xlsx (recursive) |
| llm:openai/* | llm:openai/chat.completions, llm:openai/embeddings |
| *.secret | Any resource ending in .secret (commonly denied) |
| llm:*/chat.* | Any provider's chat endpoints: llm:openai/chat.completions, llm:anthropic/chat.messages |
Resource Types
llm:— LLM endpointstool:— Tool invocationsdata:— Data resourcesmcp:— MCP server resources
Pattern Precedence
More specific patterns take precedence. data:hr/salaries overridesdata:hr/*. Denials always win over allows.
Constraints
Constraints provide fine-grained control over how resources are accessed: rate limits, parameter restrictions, and time-based rules.
- 1Rate limits — Max invocations per minute
- 2Parameters — Restrict allowed values
- 3Time restrictions — Business hours only
"constraints": {
"rate_limit": 100,
"parameters": {
"llm:openai/chat.completions": {
"model": ["gpt-3.5-turbo", "gpt-4"],
"max_tokens": {"max": 4000},
"temperature": {"min": 0, "max": 1.0}
}
},
"denied_parameters": {
"api_key": {"pattern": ".*"},
"credentials": {"pattern": ".*"}
},
"time_restrictions": {
"allowed_hours": {"min": 9, "max": 17},
"allowed_days": ["mon", "tue", "wed", "thu", "fri"]
}
}| Format | Meaning |
|---|---|
| ["a", "b"] | Value must be in list (enumeration) |
| {"max": N} | Value must be ≤ max |
| {"min": N, "max": M} | Value must be in range [min, max] |
| {"pattern": regex} | String must match regex pattern |
Attestations
Attestations are boolean capabilities that integrate with external verification systems. Use them to gate access on DLP scans, compliance checks, or approval workflows.
- •Data export permissions
- •DLP scan requirements
- •Manager approval workflows
- •Compliance certifications
"attestations": {
"can_export_data": true,
"can_view_team_usage": true,
"requires_dlp_scan": true,
"pii_handling_certified": true
}Policy Inheritance
When multiple policies apply (global → company → business unit → team → user → app), they are merged using monotonic restriction. Permissions can only narrow, never expand.
Organization Policy Team Policy User Policy Effective Policy
───────────────────── ─────────────── ─────────────── ────────────────
resources: resources: resources: resources:
- llm:* - llm:openai/* - llm:openai/chat.* - llm:openai/chat.*
- tool:* - tool:search_* - tool:search_web - tool:search_web
max_tokens: 4000 max_tokens: 2000 max_tokens: 1000 max_tokens: 1000
denied_resources: denied_resources: denied_resources: denied_resources:
- *.secret - data:hr/* (none) - *.secret
- data:hr/*| Field | Merge Rule |
|---|---|
| resources | Intersection — all ancestor policies must allow the resource |
| denied_resources | Union — if any ancestor denies, it's denied |
| constraints | Most restrictive wins (min rate_limit, strictest parameters) |
| attestations | AND — all required attestations must be present |
When a policy does not exist, MAPL loads {namespace}:base instead. Ask for data:finance/transactions with no such policy, and data:base applies. One policy per namespace covers every object you have not written a policy for.
Object Policies
Policies normally attach to a caller — a company, team, user, or service. But some things are never invoked. A table, a file, a document, or a model gets used: a tool reads it, and nothing loads its policy. Object policies attach the rules to the thing itself, and MAPL enforces them whenever a tool consumes it.
Name the object in attestations. An entry with a namespace prefix is a policy reference, not a claim to verify. Build the ID from the invocation to cover every object with one line.
- •The object's
resourceslist which tools may touch it - •References follow to any depth, so a derived object inherits its sources' rules
- •Object policies merge by intersection — they restrict, never grant
- •A reference that resolves to nothing denies the call
// The object carries its own rules
{
"policy_id": "data:employee_comp",
"extends": "data:base",
"resources": ["tool:reporting/query"],
"denied_resources": ["tool:*/export"],
"attestations": ["pii_training_current"]
}
// The tool loads it, built from the call
{
"policy_id": "app:reporting",
"resources": ["tool:reporting/*"],
"attestations": ["data:{params.dataset}"]
}Because references chain, a query against a summary built on employee_comp inherits its PII requirement even though the caller never named it.
Best Practices
Use Hierarchical Policies
Set organization-wide defaults at the top level. Refine at team and user levels. This reduces duplication and ensures consistent baselines.
Explicit Denials for Sensitive Resources
Use denied_resources for resources that should never be accessible. Denials cannot be overridden by child policies.
Leverage Attestations
Integrate with DLP, compliance, and approval systems via attestations rather than duplicating logic in MAPL.
Be Specific with Patterns
Avoid overly broad wildcards. Use ** sparingly to prevent unintended access to nested resources.