RAVEN. / security

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:

  1. Recompute payloadHash = "sha256:" + sha256(canonicalJson(receipt minus {signature, signerPublicKey, payloadHash, receiptId})) — must match the receipt's value.
  2. Check subject binding of the payload: receiptId === "raven-receipt-v1:" + payloadHash.
  3. Verify the ed25519 signature over canonicalJson({domain:"raven-receipt", version:"v1", payloadHash}) using signerPublicKey.
  4. 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.
  5. 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)

Fail-closed behavior

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)

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.