- Docs
- Bureau Verify Guide
Bureau — Overview
Bureau Verify Guide
pluck bureau verify is the journalist's 60-second path. Hand it any Bureau bundle and the CLI auto-detects the kind from JSON top-level keys, calls the matching offline verifier, and exits non-zero if any check fails. No accounts, no API keys, no Rekor round-trip required for the offline check.
pluck bureau verify ./bundle.json
# Auto-detected: Dossier
# OK – 14 dots verified
# 0
What the auto-detector reads
Every Bureau bundle declares its shape through top-level keys. The verifier dispatches on a fail-closed match:
| Top-level keys present | Bundle kind | Predicate URI |
|---|---|---|
dossierHash + dots | Dossier | (composite – dots can carry any program's predicate) |
packHash + probes | ProbePack | https://pluck.run/Nuclei.PackEntry/v1 (when wrapped) |
voteHash + signers | QuorumVote | (composite – verifies threshold, dedup, revocation) |
predicateType = https://pluck.run/Oath.Commitment/v1 | Oath | Oath.Commitment/v1 |
predicateType = .../Rotate.KeyRevocation/v1 | Rotate revoke | Rotate.KeyRevocation/v1 |
predicateType = .../Rotate.KeyFreeze/v1 | Rotate freeze | Rotate.KeyFreeze/v1 |
predicateType = .../Rotate.ReWitnessReport/v1 | Rotate re-witness | Rotate.ReWitnessReport/v1 |
predicateType = .../SbomAi.Entry/v1 | SBOM-AI | SbomAi.Entry/v1 |
predicateType = .../Fingerprint.Model/v1 | Fingerprint baseline | Fingerprint.Model/v1 |
predicateType = .../Fingerprint.Delta/v1 | Fingerprint delta | Fingerprint.Delta/v1 |
predicateType = .../Mole.Canary/v1 | Mole canary | Mole.Canary/v1 |
predicateType = .../Mole.MemorizationVerdict/v1 | Mole verdict | Mole.MemorizationVerdict/v1 |
predicateType = .../Whistle.Submission/v1 | Whistle | Whistle.Submission/v1 |
predicateType = .../EvidencePacket/v1 | Bounty packet | EvidencePacket/v1 |
predicateType = .../Bounty.Submission/v1 | Bounty submission | Bounty.Submission/v1 |
predicateType = .../Custody.Bundle/v1 | Custody | Custody.Bundle/v1 |
A bundle that matches none of these falls through to a typed unknown-bundle-shape error and exits with code 2.
Per-kind invocations
Dossier
pluck bureau verify ./openai-gpt-4o.dossier.json
# Walks every TimelineDot signature, recomputes dossierHash,
# rejects on first mismatch. No flags required.
ProbePack
A signed ProbePack requires the author's public key. Pass it out-of-band – verifying against a key the registry served alongside the pack is TOFU and grants the registry total trust (see Operator Duties → Probe-pack supply-chain).
pluck bureau verify ./canon-honesty-v0.1.json --pubkey ./alice.pub.pem
QuorumVote
pluck bureau verify ./red-dot-vote.json \
--identities ./quorum-roster.json \
--revoked ./revoked-fingerprints.txt
The --identities JSON maps each fingerprint to a public key. --revoked is an optional newline-separated list of compromised fingerprints; signers in the revoked set are excluded from the threshold count.
Oath
pluck bureau oath verify ./oath.intoto.jsonl
# Validates Ed25519 signature against vendor-published SPKI fingerprint,
# checks expiresAt, refuses signed-but-stale claims.
Rotate – revocation, freeze, re-witness
# Verify a key revocation envelope
pluck bureau rotate verify-rotation <rekor-uuid>
# Re-witness reports surface daysSinceRevocation alongside ok
pluck bureau verify ./re-witness.intoto.jsonl
SBOM-AI entries
# By Rekor uuid (online – fetches the entry)
pluck bureau sbom-ai verify <rekor-uuid> --fingerprint <64-hex>
# By saved envelope (offline)
pluck bureau verify ./sbom-entry.intoto.jsonl
Fingerprint – baseline + delta
pluck bureau verify ./gpt-4o-baseline.intoto.jsonl
pluck bureau verify ./gpt-4o-delta.intoto.jsonl
# Delta classification: stable | minor | major | swap
Mole – canary + verdict
pluck bureau verify ./canary.intoto.jsonl
# Validates: sealedAt is BEFORE every probe's evaluatedAt,
# operator signed raw 32-byte digest of canonical(canary body).
pluck bureau verify ./memorization-verdict.intoto.jsonl
# Validates: deterministic n-gram + edit-distance score reproduces.
Whistle
Whistle submissions are signed as raw 32-byte digests by an ephemeral anon key – they are NOT wrapped in a DSSE/in-toto attestation envelope, so cosign's verify-attestation cannot consume them. Use the Pluck-specific verifier:
pluck bureau whistle verify-submission <rekor-uuid>
# Reads submission body from Rekor, recomputes canonical hash,
# checks anon-key signature.
DSSE wrapping (and cosign compatibility) is on the roadmap.
Bounty – observation packet + submission
pluck bureau verify ./evidence-packet.intoto.jsonl
pluck bureau verify ./bounty-submission.intoto.jsonl
EvidencePacket/v1 carries a markdown body suitable for direct platform submission. Verifiers walk the embedded Rekor uuid + cosign verify command independently – the bureau plays no role beyond hashing.
Custody
pluck bureau custody verify ./capture-bundle.json
# Exit 0 when FRE 902(13) compliant.
# Exit non-zero with result.reasons[] mapping each broken check to a
# legal-admissibility argument.
Custody bundles produced without WebAuthn binding emit fre902Compliant: false with a clear reason citing the Daubert reliability standard. WebAuthn binding is on the roadmap.
Exit codes
| Code | Meaning |
|---|---|
0 | Every signature verifies, every cross-reference resolves, every bound is honored. |
1 | At least one check failed. The verifier prints every broken check before exiting. |
2 | Usage error – missing flags, unreadable file, unknown bundle shape, unparseable JSON. |
The --json flag emits a machine-readable verification report suitable for CI / SIEM ingestion:
pluck bureau verify ./bundle.json --json
The JSON shape is stable: { ok: boolean, reason: string, checks: [...], summary: string }. Use it to gate releases, tag artifacts in pipelines, or wire alerts in your SIEM.
Sample outputs
Clean dossier
Auto-detected: Dossier
program dragnet
subject openai/gpt-4o
dots 14 (12 green, 2 red)
hash a1b2c3...
signed by b4d5e6... (verified)
OK
Tampered dossier
Auto-detected: Dossier
hash expected a1b2c3..., got x9y8z7...
reason dossier-hash-mismatch
FAIL
exit 1
Unsigned probe-pack
Auto-detected: ProbePack
reason pack-signature-missing
FAIL
exit 1
Quorum below threshold
Auto-detected: QuorumVote
threshold 3-of-5
signed 2 (after revocation dedup)
reason below-threshold
FAIL
exit 1
When to verify online
pluck bureau verify against a saved envelope is offline – it never touches the network. Three cases require an online round-trip:
- Rekor inclusion proof. A signed envelope alone proves the operator authored it; an inclusion proof proves Rekor accepted it.
pluck bureau dragnet verify --check-inclusion <uuid>runs the RFC 6962 walker against the live Rekor instance. - SBOM-AI registry lookup. Cross-checking a probe-pack's SBOM dependency requires fetching the SBOM entry.
pluck bureau sbom-ai verify <rekor-uuid>. - Vendor Oath fetch. Pulling the live
/.well-known/pluck-oath.jsonto confirm a current claim.pluck bureau oath fetch <vendor>.
For everything else – including reproducing a journalist's claim from a saved bundle – the offline path is the canonical one.
Verifying without Pluck
Every Bureau signature is Ed25519 PureEdDSA over the raw 32-byte digest of canonicalStringify(body). That matches the wire shape cosign / sigstore-go / sigstore-python expect. If a third party wants to confirm a Bureau claim without installing Pluck:
# Use cosign directly against a saved envelope
cosign verify-attestation \
--key alice.pub.pem \
--type "https://pluck.run/SbomAi.Entry/v1" \
./sbom-entry.intoto.jsonl
# Or pull the entry from Rekor by uuid
curl https://rekor.sigstore.dev/api/v1/log/entries/<uuid>
The bureau-specific bounds (probe-pack body ≤ 256 KiB, dossier ≤ 100k dots, etc.) are NOT enforced by cosign – those are caller-side gates the Pluck verifier adds. For maximum rigor, pair cosign verify-attestation with a follow-up pluck bureau verify on the same bundle.
What's next
- Bureau Foundations – the primitives every verifier walks.
- Operator Duties – the covenant operators accept by signing.
- Threat Model – Sybil defense, freeze window, kill-switch.
- Per-program verifier semantics: Dragnet, Nuclei, SBOM-AI, Rotate, Mole, Whistle, Bounty, Custody.