
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
@ar.io/proof
Advanced tools
TypeScript kernel of the ar.io verification stack: RFC 8785 (JCS) canonicalization, SHA-256, and Ed25519 verification for Verifiable Event Envelopes. Full-family verifier (inline + external commitment); accepts ario.agent/v1, ario.mlflow/v1, ario.events/v
Verify ar.io verification-stack provenance records — with no ar.io code or service in the trust path.
This is the TypeScript verification kernel for the Verifiable Event Envelope family: the signed JSON records that tools like the ariod verification agent and the MLflow plugin anchor permanently to Arweave. Given an envelope (fetched from any Arweave gateway), this package answers: is it authentic, and does it commit to the bytes I'm holding?
@noble/ed25519)npm install @ar.io/proof
Fetch the raw transaction from any Arweave gateway and verify it client-side:
import { verifyEnvelope } from "@ar.io/proof";
const env = await (await fetch("https://arweave.net/raw/<tx_id>")).json();
const result = await verifyEnvelope(env);
result.ok; // spec_version + payload_hash + Ed25519 all passed
result.signatureOk; // Ed25519 over the signed scope, against env.public_key
result.payloadHashOk; // SHA-256(JCS(payload)) === env.payload_hash
result.errors; // [] when ok — machine-readable reasons otherwise
verifyEnvelope never throws on hostile input — a malformed envelope (or a lying gateway) yields ok: false with reasons, not an exception.
The check that defeats a lying gateway: Arweave tags are unsigned search hints, so after finding a candidate envelope, confirm it actually commits to your artifact's hash:
import { sha256Hex, verifyEnvelope, contentHashes } from "@ar.io/proof";
const myHash = await sha256Hex(fileBytes); // 64-char lowercase hex
const result = await verifyEnvelope(env, myHash);
result.contentHashOk; // true ⇔ the envelope commits to exactly these bytes
result.contentRole; // how it commits: e.g. the registered baseline,
// an observed (tampered) hash, …
contentHashes(env); // all content hashes an envelope commits to, by event type
The @ar.io/anchor SDK hands a producer a set of InclusionReceipts and can serialize them into one portable, self-verifying ario.evidence/v1 bundle (body_type: ario.anchor.trace/v1). Verify the entire bundle — every event's signature + payload binding + Merkle inclusion, all offline — with the bundled CLI:
npx @ar.io/proof verify trace-bundle.json
# also re-fetch each checkpoint on-chain to confirm it's anchored:
npx @ar.io/proof verify trace-bundle.json https://arweave.net,https://permagate.io
It prints a per-event + rollup verdict and exits on a pinned code — 0 verified · 1 a real failure (bad signature / tamper / broken inclusion) · 2 malformed bundle · 3 gateway-unavailable when an on-chain re-fetch was requested. The producer's asserted verdict is shown but never trusted — the displayed verdict is always recomputed from the body. The same CLI also verifies the agent's ario.agent.proof/v1 inclusion bundle (it sniffs spec_version), so one command covers anchor + agent.
The
verifyCLI (bin: proof) is implemented onmainand ships with the next published version. Until then, run it from a checkout (node ts/dist/cli.js verify …afternpm run build) or useverifyEvidenceBundleprogrammatically.
Programmatically:
import { verifyEvidenceBundle } from "@ar.io/proof";
const bundle = JSON.parse(await fs.readFile("trace-bundle.json", "utf8"));
const result = await verifyEvidenceBundle(bundle, { gateways: ["https://arweave.net"] });
result.status; // "verified" | "partial" | "failed" | "malformed" (recomputed)
result.signatureOk; // wrapper Ed25519 signature
result.bodyHashOk; // body_hash === SHA-256(JCS(body))
result.checkpoints; // per-checkpoint envelope / merkle-root / on-chain results
result.events; // per-event signature / payload-binding / inclusion results
A withheld record_bytes (external commitment, record not disclosed) leaves that event's payload binding undetermined — surfaced, never failed (the bundle stays cryptographically sound).
Agents close daily checkpoints over per-cycle leaves (RFC 9162, §2.1 domain separation — not the Bitcoin duplicate-leaf variant). Verify a leaf's inclusion against an anchored root:
import { leafHash, verifyInclusion, hexToBytes } from "@ar.io/proof";
const ok = await verifyInclusion(
await leafHash(leafBytes), // Uint8Array leaf hash
leafIndex, // 0-based position
totalLeaves,
auditPath.map(hexToBytes), // sibling hashes, leaf → root
hexToBytes(expectedRootHex),
);
| Export | What it does |
|---|---|
verifyEnvelope(env, optionsOrContentHash?) | The three load-bearing checks (spec-version registry, payload-hash recompute, Ed25519 over the signed scope) + optional content bind. Pass { payloadBytes } for external-commitment envelopes. Returns VerificationResult. |
verifyEvidenceBundle(bundle, { gateways?, fetchImpl? }) | Verify a signed ario.evidence/v1 / ario.anchor.trace/v1 bundle: wrapper signature + body_hash + every checkpoint + every event's inclusion, offline (optional on-chain re-fetch). Returns EvidenceBundleResult. Powers the npx @ar.io/proof verify CLI. |
verifyAgentProofBundle(bundle, { gateways?, fetchImpl? }) / isAgentProofSpec(v) | Verify the agent's ario.agent.proof/v1 inclusion bundle (artifact.md §10). |
contentHashes(env) | The content hash(es) an envelope commits to, by event type — the reverse-provenance join keys. |
specVersionSupported(v) | Fail-closed accept-check: ario.agent/v1 and additive minors (ario.agent/v1.<n>). Unknown majors/profiles are rejected. |
jcs(value) | RFC 8785 canonical JSON bytes. |
sha256Hex(bytes) / sha256Bytes(bytes) | SHA-256 via WebCrypto. |
ed25519Verify(sig, msg, pubKey) | Raw Ed25519 verification. |
leafHash / nodeHash / merkleRoot / auditPath / verifyInclusion / EMPTY_TREE_ROOT_HEX | RFC 9162 binary Merkle tree primitives. |
utf8 / bytesToHex / hexToBytes | Encoding helpers. |
Envelope / VerificationResult / ContentRole / Subject | Types. |
The primary signature covers JCS(envelope minus signature minus co_signatures) (envelope-spec §2/§7.1). The reserved co_signatures carve-out lets countersignatures be added later without invalidating the primary signature.
Three independent implementations of this kernel exist — this package, the Python ar-io-proof (PyPI), and the Go reference (ar-io-agent/pkg/proof, MIT-carved) — and every one is conformance-gated byte-for-byte in CI against the shared, frozen test-vectors-v1.2 corpus (per-file SHA-256 pins). The proof-checker web app additionally runs this kernel and a WASM build of the Go reference against each other live, asserting identical verdicts across the corpus plus adversarial negatives.
That mutual gate is the point: anyone can verify ar.io provenance records with no ar.io code in the trust path — write your own verifier against the public specs and the corpus will tell you if it's conformant.
previous_hash), checkpoint reconciliation, and gateway/transport logic are consumer-layer concerns composed above the kernel.env.public_key; binding that key to a real-world identity is yours to establish.ESM-only. Needs WebCrypto (globalThis.crypto.subtle): any modern browser, Node.js ≥ 20 (≥ 19 works), Deno, Bun, workers.
MIT — verification must be open.
FAQs
TypeScript kernel of the ar.io verification stack: RFC 8785 (JCS) canonicalization, SHA-256, and Ed25519 verification for Verifiable Event Envelopes. Full-family verifier (inline + external commitment); accepts ario.agent/v1, ario.mlflow/v1, ario.events/v
The npm package @ar.io/proof receives a total of 0 weekly downloads. As such, @ar.io/proof popularity was classified as not popular.
We found that @ar.io/proof demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.