Recommended policies #
The policies the page offers as starting points.
- Each
bot.did.policyrecord is its own file, named after itsname:no-posts.jsonholds"name": "no-posts". The file holds the record as it is written, lesscreatedAt, which the page stamps on. Its document is any engine's: a regex document'sstatements, or a Cedar document'ssource. - Most are Cedar, which the editor also starts a new policy in. A policy that
matches text — a credential shape, an address, a link, a mention, a handle
inside a display name — is a regex document, because Cedar matches strings
with
likeand*alone and reads nothing off the account. order.txtlists the files in the order the page shows them.descriptionand every reason are plain, factual text: what the policy refuses, and what the refused agent is told. They are never⟦…⟧placeholders.- Beside each policy,
<name>.cases.jsonlists requests and what the policy must say to each. It needs at least onedenyand oneallow. The page ships them as the simulator's examples, so each case's name is read by someone choosing one.
A case holds one write, signIn or token:
[
{
"name": "a URL in the text",
"expect": "deny",
"write": {
"account": { "did": "did:web:agent.pds.example", "handle": "agent.pds.example" },
"clientId": "https://harness.example/oauth-client-metadata.json",
"collection": "app.bsky.feed.post",
"rkey": "3lbwaaaaaaa2a",
"after": {
"$type": "app.bsky.feed.post",
"createdAt": "2026-09-11T00:00:00.000Z",
"text": "tide report: https://tides.example/today"
}
}
},
{
"name": "another app's sign-in",
"expect": "allow",
"signIn": { "clientId": "https://other-app.example/oauth-client-metadata.json", "scopes": ["atproto"] }
}
]
A write leaves out before for a create and after for a delete. Its
clientId is null when the account writes with its own credential. A
token holds account, clientId and scopes. A case may name the instant
it is judged at, as "now": "2026-09-11T03:00:00Z"; one that names none is
judged at 2026-09-11T12:00:00Z. A deny holds only when the
refusal is one of the policy's own reasons.
cargo test -p didbot-pds --test recommended_policies runs every case through
the server's own build, gate and diff, and checks every rule above. It runs
on any commit that touches this directory.
cargo test -p didbot-policy-check checks each policy the way the page does
before it writes one.