A robots.txt for agent actions.
A minimal, open standard that lets any organization declare — in one machine-readable file — which actions autonomous AI agents may take against its systems, under what conditions, and with what audit trail.
Status: Draft 0.1 · License: CC-BY-4.0 (spec), Apache-2.0 (reference code)
Discussion: GitHub Issues · Author: Uljan Sinani — permissioning.ai
Autonomous agents now read, write, purchase, deploy, and delete. Today, the only controls are (a) the credentials an agent happens to hold, and (b) prompt-level pleading. Neither is a policy. OAuth scopes govern API access, not agent behavior: an agent with a valid token to a CRM can mass-delete contacts at 3 a.m., and nothing in the stack distinguishes that from a human clicking once.
There is no standard way for a system owner to say: “Agents may read invoices, may draft but not send emails, may never touch records older than 90 days, and every write must carry an attributable agent identity.”
This protocol defines that declaration.
robots.txt, a published policy has value even before enforcement exists — it establishes intent, liability boundaries, and a target for tooling.A site or service publishes a single file at a well-known path:
https://example.com/.well-known/agent-permissions.json
{
"permissioning_version": "0.1",
"owner": "example.com",
"updated": "2026-06-11",
"default": { "read": "allow", "write": "deny", "execute": "deny" },
"rules": [
{
"id": "crm-read",
"resource": "api.example.com/crm/*",
"actions": ["read"],
"effect": "allow"
},
{
"id": "email-draft-only",
"resource": "api.example.com/mail/*",
"actions": ["create:draft"],
"effect": "allow",
"conditions": { "deny_actions": ["send", "delete"] }
},
{
"id": "payments-human-gate",
"resource": "api.example.com/payments/*",
"actions": ["write", "execute"],
"effect": "require_approval",
"approval": { "type": "human", "timeout_s": 3600 }
}
],
"audit": {
"required": true,
"fields": ["agent_id", "principal", "action", "resource", "timestamp", "task_context"],
"sink": "https://example.com/agent-audit"
},
"contact": "security@example.com"
}
default — fallback effects per action class (read / write / execute / delete).
Effects: allow, deny, require_approval, rate_limit.
rules[] — ordered, first-match-wins. Each rule has:
| Field | Description |
|---|---|
resource |
Glob over hostnames/paths, or an MCP tool name (mcp:server-name/tool-name). |
actions |
Verbs, optionally namespaced (create:draft, update:status). |
effect |
allow | deny | require_approval | rate_limit |
conditions (optional) |
Time windows (hours_utc), record-age limits (max_record_age_days), value caps (max_amount, currency), volume caps (max_per_hour), identity constraints (require_agent_id, allowed_issuers). |
approval (optional) |
human | secondary_agent | mfa, with timeout. |
audit — fields every governed action must log, and where.
task_context is the agent’s stated task — the field that makes 3 a.m. incident review possible.
escalation (optional, top-level) — what enforcement layers should do on violation: block, block_and_alert, revoke_session.
Implementation status (v0.1):
conditions(time windows, record-age limits, value/volume caps, identity constraints) are part of the v0.1 manifest schema but are not yet enforced by the reference implementation in/reference. The reference middleware and filesystem guard resolve a rule’seffect(allow/deny/require_approval/rate_limit) only; a conditional rule currently behaves as its baseeffectregardless of itsconditions. Treat publishedconditionsas declared intent, not as something the reference code checks. Enforcing them is planned for a later revision.
Agent-Action headerA rule’s actions field matches against the semantic action an agent intends, not merely the HTTP method of the request. HTTP methods are too coarse: a single POST /mail could be create:draft (benign) or send (consequential), and the manifest must be able to distinguish them.
To carry this intent, an agent SHOULD send an Agent-Action request header naming the semantic action it is performing, optionally namespaced:
Agent-Action: create:draft
Enforcement points resolve a request’s action as follows:
Agent-Action header is present, its value is the action used for rule matching.GET/HEAD → read, POST/PUT/PATCH → write, DELETE → delete.Because the fallback maps an unlabeled write to the broad write class, an agent that does not declare a fine-grained action receives only whatever authority the manifest grants to write — which, under the recommended deny-by-default posture (§3.1), is none. This makes action declaration incentive-compatible: an agent that wants the narrower create:draft permission must explicitly claim it, and in claiming it becomes accountable for it in the audit log (§3.1, action field).
Security note. The Agent-Action header is self-asserted and unsigned in v0.1, exactly as HTTP methods are. It narrows authority but never widens it: an agent cannot escalate by lying, because a false Agent-Action either matches a more restrictive rule or fails to match and falls through to the default. Binding Agent-Action to a signed agent identity is reserved for a future version (§3.3, agent capability statements).
Implementation status (v0.1): The reference middleware in
/referenceimplements this header. This section documents existing behavior; it is normative for v0.1.
Agents MAY publish a capability statement (agent-card.json: identity issuer, action vocabulary, audit-sink support) so enforcement points can negotiate. Out of scope for v0.1 beyond reservation of the name.
The manifest is enforcement-neutral. Known viable enforcement points, in ascending order of strength:
| Layer | Mechanism | Strength |
|---|---|---|
| Agent runtime | Framework reads manifest before tool calls | Honor system (still useful: liability + logging) |
| MCP server | Server filters/wraps its own tools per manifest | Strong for MCP traffic |
| API gateway / proxy | Policy-enforcement middleware keyed on agent identity headers | Strong, agent-framework-agnostic |
| IdP / token issuer | Scopes minted to match manifest rules | Strongest, slowest to adopt |
A reference implementation (v0.1 target): a small reference middleware (Python/FastAPI, ~250 lines including comments and docstrings) that fetches a manifest, classifies inbound requests by agent identity header, and enforces allow/deny/require_approval. Enough to demo, small enough to audit. It enforces rule effects; it does not yet evaluate conditions (see §3.2).
→ See reference/middleware.py
require_approval define a callback wire format in v0.2, or stay implementation-defined?User-Agent-style header (Agent-Id, Agent-Issuer) acceptable bootstrap, or does v0.1 need signed attestation?Every enforcement vendor will fight over the control plane. The declaration format underneath should be neutral, boring, and shared — the same reason robots.txt isn’t owned by a crawler company. If you run agents against enterprise systems, or enterprise systems agents touch, break this draft: open an issue.
v0.1 — June 2026. Substantive criticism > stars.