Agent policy for sites
For site operators: which agents may do what, per-agent quotas and prices, handling of unverified claims, and declared tools.
A site's agent policy decides what each verified agent may do. It is a typed, validated JSON object stored with the site; unknown fields are rejected.
Important
The policy engine is complete and tested, but there is no console screen, admin API field or CLI command to edit a site's policy yet. The admin API returns it (agentPolicy on the site), and an operator sets it directly in the site's stored configuration. A management screen is on the roadmap. Sites without a policy keep the default behaviour below.
Example
{
"agents": {
"chatgpt": {"actions": ["agent_submit"], "perMinute": 30},
"perplexity": {"actions": ["*"], "price": {"amount": "0.01", "currency": "USD", "unit": "request"}}
},
"default": {"actions": []},
"unverified": "challenge",
"crawlerPrice": {"amount": "0.005", "currency": "USD"},
"tools": []
}| Field | Meaning |
|---|---|
agents | keyed by the verified agent name (from agents.json or its directory entry); each grant has actions (site actions, "*" for all), an optional perMinute quota and an optional price |
default | the grant for verified agents without an entry |
unverified | what happens when a User-Agent claims an AI assistant, AI crawler or search engine and no signature proves it: challenge (default), block, charge (402 with the crawler price) or count |
crawlerPrice | the price for verified agents with no entry on a site with no default, and for unverified: "charge" |
tools | declared tools published in the manifest |
Quotas are per site and per agent, on top of the agent's own quota in agents.json. The maximum policy size is 16 KiB.
Registering agents
Agents are known to AgentGate through agents.json (or AGENTS_FILE):
agents: local keys, as printed byagentgate keygen NAME({"name", "public_key", "per_minute"});directories: allow-listedSignature-Agentorigins whose key directory AgentGate fetches, each with anameandper_minute. The repository'sagents.example.jsonlists ChatGPT agent, Google-Agent, Cloudflare Browser Run and Browserbase, checked on 2026-09-24;registries: optional lists of directory URLs and signature agent cards, imported at startup.
Labels and default rules
The policy adds labels; default rules act on them, before the browser checks:
| Label | Default rule |
|---|---|
agentgate:agent:policy:allowed | allow (skips browser challenges, not content blocks) |
agentgate:agent:policy:denied | block 403 |
agentgate:agent:policy:quota_exceeded | block 429, Retry-After: 60 |
agentgate:agent:policy:unverified:challenge / block / charge / count | challenge / 403 / 402 / none |
agentgate:agent:payment:required, exact_mismatch, max_too_low | 402 |
agentgate:agent:payment:invalid_value, conflicting, unsigned | 400 |
agentgate:agent:payment:accepted, agentgate:agent:policy:unlisted | none |
Rule sets loaded from your own rules.json do not get these default rules automatically.
Limits
- On the form, a Web Bot Auth signature earns
policy:allowedonly when it binds@methodand@pathand carries a nonce, which is consumed. - The price-offer check requires some
web-bot-authsignature to cover the offer header; it does not tie that to the signature that verified, which only differs when a request carries several. - No third-party agent has yet exercised pay per crawl, handoff or receipts against an AgentGate gateway.