Security & verification
Raven's trust model is "don't trust us — check". Everything needed to verify a receipt independently is public.
ed25519 signatures, domain-separated
Every issued receipt-v1 is signed with an ed25519 key whose only job is attestation. The signature covers canonicalJson({domain:"raven-receipt", version:"v1", payloadHash}) — domain separation means a Raven receipt signature can never be confused with any other protocol's, nor with Raven's own legacy v2 attestation envelope.
The published key — cross-check, never the trust root
GET https://raven-hosted-verifier.onrender.com/pubkey
{"keys":[{"keyId":"rvk_c2997e90215279c2",
"publicKeyBase64":"MCowBQYDK2VwAyEASGJt4Ilx2Z6g0BVC1VQIfaUcV0nr8WB1J45/8vfje6w=",
"alg":"ed25519"}],
"domain":"raven-official-attestation","version":"v2"}
The domain/version fields name the legacy v2 attestation envelope this registry was published under; the same keyId also signs receipt-v1. Either way, /pubkey is discovery and cross-check only. Signer trust comes from a key you pin deliberately — your own explicit, local pin is the trust decision. Cross-check that pin against this site's footer and the public reference repository; every channel must agree, and no channel Raven operates is the root on its own.
Verify a receipt-v1: the recipe
The signed payloadHash commits to the full claim: the subject (chain, mint, token program), the scope (checks performed and checks not performed), findings, coverage gaps, rules and taxonomy versions, the observed slot, and the timestamp with its own maxAgeSeconds. Five steps:
- Recompute payloadHash = "sha256:" + sha256(canonicalJson(receipt minus {signature, signerPublicKey, payloadHash, receiptId})) — must match the receipt's value.
- Check subject binding of the payload: receiptId === "raven-receipt-v1:" + payloadHash.
- Verify the ed25519 signature over canonicalJson({domain:"raven-receipt", version:"v1", payloadHash}) using signerPublicKey.
- Signer trust: confirm signerPublicKey equals the Raven key you pinned. This is the trust decision — separate from signature validity, which step 3 established on its own.
- Report freshness (timestamp + maxAgeSeconds) and coverageGaps alongside the result — never collapsed into it.
Worked example with a real production-signed receipt: /receipt-v1-test-vector.json. Unit-test your verifier against it before trusting your integration.
The canonical verifier
The canonical supported receipt-v1 verifier is the open, zero-dependency package raven-receipt-verifier — the name is ratified and the package is not yet published; this page will carry the install command when it is. Until then, a minimal public reference implementation you can clone and run today: raven-receipt-verify — an interim reference only; it is not the hardened canonical kernel and does not claim equivalence with it.
Related packages (public truth)
- raven-receipt-verifier - ratified name; unpublished (npm 404). No public registry command yet.
- plugin-raven-verify@0.3.1 - installable ElizaOS adapter only. Consequential use requires independently supplied trusted keys; current fallback trusts same-host /pubkey when RAVEN_TRUSTED_KEYS is absent - do not rely on that discovery path as a trust root.
- raven-verify-js@0.1.0 - DEPRECATED, unsuitable for trust decisions.
- raven-verify-mcp - unsigned local/developer preview; not a signed receipt-v1 deliverable.
Fail-closed behavior
- Current POST /receipt/v1 returns an explicit unsigned refusal and issues no receipt when required evidence or signing cannot be established — never an unsigned "trust me".
- Unfetchable accounts, undecodable layouts, and unknown Token-2022 extensions produce explicit findings/gaps or a no-receipt refusal, never silently clean evidence.
- Informational evidence cannot erase triggered findings or unevaluated surfaces.
- Holder exclusions happen ONLY with decoded venue evidence (pump.fun curve, PumpSwap pool registration) — no address lists, no heuristics.
Coverage gaps
Every response carries coverageGaps — what was NOT checked. New engine versions are tracked explicitly: when coverage expands, history is segmented as coverage expansion, never silently rewritten as a verdict change.
Quality Ledger
Every hosted verification — success or failure — appends one sanitized entry to an append-only ledger (timestamp, mint, verdict, latency, error code; never keys, never signatures' private material). It's our own audit trail for verdict-to-outcome tracking across baselined launches and revisits.
Cryptographic posture
Current receipt-v1 objects are signed with Ed25519 and carry signerPublicKey, rulesVersion, payloadHash, and receiptId. Match signerPublicKey to the independently authenticated key pin; /pubkey is discovery/cross-check only. Legacy v2 receipts instead identify the signing key with keyId. Rotation never silently rewrites historical receipts, and each version must continue to verify under its own frozen contract. Raven does not claim quantum resistance today; any future signing scheme requires a separately documented versioned contract (/key-policy.json).
Cryptographic agility (checklist for verifying agents)
- For receipt-v1, match signerPublicKey to your independently pinned, authenticated key; /pubkey is discovery/cross-check only — don't assume.
- Verify using the frozen receipt-v1 domain/version and Ed25519 recipe. keyId/signatureAlg belong to legacy v2 compatibility.
- payloadHash recomputed and checked; receiptId binding checked.
- Signer key pinned explicitly by you. /pubkey, this site, and Raven's public repositories are cross-checks that must match your pin — never its source.
- Old receipts remain tied to their signing key; rotation never silently rewrites them.
- Operationally: no private keys in logs, no API keys in browser code, no secret-bearing fields in static files (enforced by the test suite and change-review gate).
Unit-test your verifier against a real receipt: /receipt-v1-test-vector.json (receipt-v1). Full policy, key states, and rotation rules: /key-policy.json and RAVEN_CRYPTO_AGILITY.md. No post-quantum guarantee is claimed; algorithm agility is a design principle.
Legacy v2 attestation (POST /verify)
Integrations built on the legacy POST /verify endpoint receive a v2 attestation: the signature covers "raven-official-attestation" || officialAttestationHash, and the replay check recomputes replayHash from the response fields (worked example: legacy v2 vector receipt-test-vector.json). Legacy compatibility only — new integrations use the receipt-v1 recipe above.
Report a vulnerability
Report security issues privately to security@ravenattest.com — the same contact is published in machine-readable form at /.well-known/security.txt (RFC 9116). Reports are reviewed privately; do not open public issues for unpublished vulnerabilities. Never include private keys, seed phrases, API keys, or customer data in an initial report — we will never ask for them. Other contact routes (developer access, partnerships, general): contact.
What Raven is not
Raven verifies launch state from on-chain evidence. It does not predict price, does not guarantee safety, and is not financial advice. A pass means "no risk findings on the surfaces we checked, gaps listed" — your agent's policy decides what to do with that.