PARP 0.1 · released · v0.1.0 spec · v1.0.1 integrations

Your site can tell an agent what it may do. Signed, and checkable.

robots.txt was written for crawlers that fetch pages. It says nothing about retrieval, training, attribution or commercial use, and anyone can forge a copy of it. The Piruz Agent Receipt Protocol adds the missing half: a cryptographically signed statement of rights, bound to the exact bytes you served, plus an optional receipt an agent can issue to record what it did.

LLMBOO runs it in production today. Every manifest below is signed with our Ed25519 publisher key, and you can verify one yourself in about ten seconds.

See our live manifests Read the spec

What it is, and what it is not

What PARP does

  • Lets a publisher sign a rights manifest: licence, retrieval, training, commercial use, attribution, expiry.
  • Binds that manifest to a SHA-256 digest of the bytes actually served, so a changed page invalidates the claim.
  • Lets an agent record a receipt referencing the exact manifest it read, with no personal data in it.
  • Rides on plain HTTPS and an RFC 8288 Link header. No new scheme, no new port, no crawler to install.

What PARP is not

  • Not DRM. It does not block, encrypt or restrict anything.
  • Not proof that an agent obeyed your policy. A receipt proves only that its issuer made a record.
  • Not legal advice or a licence agreement. Rights are policy signals until a contract says otherwise.
  • Not an IANA registration. The media type is a vendor type, private to this release.
  • Not authentication. It identifies a publisher's statement, not a user or a session.
Release status. PARP 0.1 was initiated by Piruz Afruz MB, Lithuania, and is published as an open protocol. The specification is released as v0.1.0 and the publisher adapters as parp-integrations v1.0.1 (Node, PHP, .NET and Shopify starters). Every manifest carries its protocol version, so verifiers can tell versions apart as the protocol evolves. A neutral media type and short link relation will be proposed to IANA once at least two independent deployments publish interoperability evidence. Nothing on this page is a claim of standardisation, endorsement, or compliance by any AI provider.

Verify ours, do not trust it

That is the whole point of signing. Fetch our key, fetch a manifest, check the signature and check the digest against the bytes we actually serve. If any step fails, the claim is worthless, which is exactly the property robots.txt lacks.

# Node 20+, no dependencies
const key   = await (await fetch("https://llmboo.com/.well-known/piruz-agent-key.json")).json();
const token = await (await fetch("https://llmboo.com/agent-rights/llms.txt.parp")).text();
const [body, sig] = token.split(".");

const k  = await crypto.subtle.importKey("jwk", key.keys[0], {name:"Ed25519"}, true, ["verify"]);
const ok = await crypto.subtle.verify("Ed25519", k,
             Buffer.from(sig,"base64url"), Buffer.from(body,"base64url"));

const manifest = JSON.parse(Buffer.from(body,"base64url").toString());
// ok === true, and manifest.contentSha256 === sha256 of https://llmboo.com/llms.txt
Publisher keyhttps://llmboo.com/.well-known/piruz-agent-key.json
Rights indexhttps://llmboo.com/agent-rights
Signed manifesthttps://llmboo.com/agent-rights/llms.txt.parp
Receipt intakePOST https://llmboo.com/api/agent-receipt
Advertised onLink: <…llms.txt.parp>; rel="…SPEC.md#transport"; type="application/vnd.piruz.agent-rights"

How we implemented it, security first

Ed25519, canonical bytes

Signatures cover canonical JSON with sorted keys and no insignificant whitespace, so two implementations sign identical bytes and a re-serialised manifest cannot silently change meaning.

Bound to what we served

Each manifest carries the SHA-256 of the resource itself and an expiry. Edit the file and the digest stops matching, which is a feature, not a bug.

Keys out of band

The public key is published separately from the manifests, as JWK. An agent that takes the key from the same response it is verifying has verified nothing.

Receipts carry no people

We store exactly six fields: id, manifest digest, agent URL, purpose, issue time, arrival time. Anything else in the request body is discarded on the way in.

Opt-in and time-limited

Sending a receipt is voluntary, the endpoint is public, and receipts are deleted after 90 days. The retention period is stated in the response, not buried in a policy.

Conservative rights

Our own manifests allow retrieval and require attribution. Training and commercial use are left unspecified on purpose: that is a licensing conversation, not a header.

Adopt it on your site

The protocol is open and the reference implementation is about a hundred lines. If you publish anything an AI assistant reads, you can state your terms in a way that cannot be forged or misattributed.

  1. 1Generate an Ed25519 keypair and publish the public half as JWK at a stable URL on your domain.
  2. 2Sign a manifest per resource: subject URL, publisher, licence, the four use permissions, the content digest and an expiry.
  3. 3Serve it as application/vnd.piruz.agent-rights and advertise it with a Link header on the resource.
  4. 4Accept receipts if you want them, opt-in, with no personal data and a stated retention period.

Or skip the steps: the free LLMBOO plugins for WordPress and OpenCart publish PARP out of the box, following the parp-integrations v1.0.1 conventions. Each store signs with its own key, generated on its own server and never sent to us. Starters for Node, PHP, .NET and Shopify are in the same repository.

We are looking for the second independent implementer. Two deployments with published interoperability evidence is the bar before a neutral media type and a short link relation can be proposed through the IANA procedures. If you run a publisher, a store platform or an agent, we will help you wire it and we will publish the evidence jointly.