Quickstart
Issue and verify your first signed interaction record in under 5 minutes. By the end, you'll have a signed receipt and a working verification pipeline.
Node.js 22+ required. Check with node --version.
Step 1: Install
npm install @peac/protocol @peac/crypto
This installs the core protocol package with issuance, verification, key generation, and schema validation.
Step 2: Generate a signing key
import { generateKeypair } from '@peac/crypto';
const { privateKey, publicKey } = await generateKeypair();
// Store privateKey securely (env var, secret manager)
// Publish publicKey at /.well-known/peac-issuer.json
Never commit private keys to source control. Use environment variables or a secret manager.
Step 3: Issue a receipt
import { issue } from '@peac/protocol';
const { jws } = await issue({
iss: 'https://api.example.com',
kind: 'evidence',
type: 'org.peacprotocol/access-decision',
pillars: ['access'],
extensions: {
'org.peacprotocol/access': {
resource: 'https://api.example.com/data',
action: 'read',
decision: 'allow',
},
},
privateKey,
kid: 'key-2026-04',
});
// Deliver as HTTP header
res.setHeader('PEAC-Receipt', jws);
The receipt is a compact JWS string: a single line of base64url-encoded data with an Ed25519 signature.
Step 4: Verify a receipt
import { verifyLocal } from '@peac/protocol';
const result = await verifyLocal(jws, publicKey);
if (result.valid) {
console.log('Issuer:', result.claims.iss);
console.log('Kind:', result.claims.kind);
console.log('Type:', result.claims.type);
} else {
console.log('Verification failed:', result.code, result.message);
}
verifyLocal() works completely offline: no network calls to the issuer. It auto-detects the wire format.
Step 5: Publish your policy
Create /.well-known/peac.txt on your domain:
version: peac-policy/0.1
issuer: https://api.example.com
receipt_format: interaction-record+jwt
usage: conditional
purposes: [indexing, research, documentation]
attribution: required
contact: security@example.com
This is your machine-readable terms file. AI agents discover it automatically before making requests.
Step 6: Publish your keys
Create /.well-known/peac-issuer.json:
{
"issuer": "https://api.example.com",
"jwks_uri": "https://api.example.com/.well-known/jwks.json",
"receipt_versions": ["interaction-record+jwt"]
}
Verifiers fetch your JWKS to validate receipts offline.
What you've built
After completing these steps, you have:
- A signing pipeline: Your service issues signed records on every response
- A verification pipeline: Any client can verify your records offline
- Machine-readable policy: Agents discover your terms automatically
- Published keys: Verifiers can validate without contacting you