@omegaengine/verify
v0.6.0
Published
Offline, zero-dependency verifier for OmegaEngine Agent Security Attestations — checks the Ed25519 signature against the published JWKS and the content hash, with no trust in OmegaEngine.
Maintainers
Readme
@omegaengine/verify
Offline, zero-dependency verifier for OmegaEngine Agent Security Attestations.
It confirms two things, entirely on your machine, with no trust in (and no call to) OmegaEngine:
- Authenticity — the attestation's
signatureV2is a standard EdDSA JWS (RFC 8037) signed by the key published at OmegaEngine's JWKS (/.well-known/jwks.json, RFC 7517). - Integrity — the
attestationIdequals the SHA-256 of the canonical attestation body, so nothing was altered.
Built only on Node's built-in crypto — no third-party dependencies to trust.
CLI
npx @omegaengine/verify attestation.json
# ✓ VERIFIED — issued by https://omegaengine.ai (key 9f3a…)Zero-key live sample:
npx -y @omegaengine/verify@latest sample --api=https://omegaengine.ai
# ✓ VERIFIED — issued by https://omegaengine.ai (key vGgd...)Custom key set (e.g. self-hosted): --jwks=https://your-host/.well-known/jwks.json.
Exit codes: 0 verified · 1 not verified · 2 usage error.
Pin the trust anchor at issuance
The default JWKS URL trusts the omegaengine.ai domain. For verification that survives
domain loss or hijack, snapshot the key set when your attestation is issued and verify
against your pinned copy instead of the live URL:
# at purchase
curl -s https://omegaengine.ai/.well-known/jwks.json > omegaengine-jwks-pinned.json
# later — CLI against the pin, no trust in the live domain
npx -y @omegaengine/verify@latest attestation.json \
--jwks="data:application/json;base64,$(base64 < omegaengine-jwks-pinned.json)"// or fully offline with the library
import { verifyAttestation } from "@omegaengine/verify";
import { readFileSync } from "fs";
const jwks = JSON.parse(readFileSync("omegaengine-jwks-pinned.json", "utf8"));
const r = verifyAttestation(att, jwks); // no network — your pin is the trust anchorIf the live JWKS later differs from your pin, that is either a legitimate key rotation
(your pinned kid should still be published in the retired set) or a hijack to
investigate — check the dated snapshots OmegaEngine commits to its repo
(docs/attestation-jwks-snapshot-*.json) and any published security notices.
Library
import { verifyAttestation, verifyAttestationRemote } from "@omegaengine/verify";
// fetch the published JWKS and verify
const r = await verifyAttestationRemote(att);
if (r.valid) console.log("issued by", r.issuer);
// or verify against a JWKS you already hold (fully offline)
const r2 = verifyAttestation(att, jwks);Transparency log (inclusion + consistency)
Beyond authenticity, confirm an attestation was recorded in OmegaEngine's public, append-only transparency log (RFC 6962) — so a proof can't have been forged or backdated:
import { verifyInclusion, verifyInclusionRemote, verifyConsistency } from "@omegaengine/verify";
// fetch the inclusion proof + JWKS from a running instance and verify offline
const r = await verifyInclusionRemote(att);
if (r.valid) console.log("publicly logged:", r.reason);
// or verify a proof bundle you already hold (fully offline, no network)
const r2 = verifyInclusion(att, inclusion, jwks);
// monitors: prove the log was never rewritten between two tree sizes
const r3 = verifyConsistency(first, second, firstRoot, secondRoot, proof);verifyInclusion folds the audit path to the signed tree head root (RFC 6962) and
checks the tree head's EdDSA signature against the JWKS — the same key that signs
attestations. Proof bundles come from GET /api/transparency/proof/<id>; the signed head
from GET /api/transparency/sth.
OmegaReceipt v1 (portable decision receipts)
Since 0.3.0 the package also verifies OmegaReceipt v1 — the portable, signed
receipt POST /api/v2/judge embeds as meta.receipt when called with
"receipt": true (Pro+ plans). Same construction (Ed25519 JWS over a canonical
content hash), plus strict domain separation: the signed payload must carry
"omega:typ": "omega/receipt.v1", so a signature minted for an attestation or a
transparency-log tree head can never be replayed as a receipt.
import { verifyReceipt, verifyReceiptRemote } from "@omegaengine/verify";
// verify against a JWKS you already hold (fully offline)
const r = verifyReceipt(meta.receipt, jwks);
// or fetch the published JWKS first
const r2 = await verifyReceiptRemote(meta.receipt);verifyReceipt is fail-closed: content hash, field discipline (grantChain
must be [] or 1–5 unique root-first 64-hex grant hashes — see the grants
section below; disclosure must be null; counterparty must be null or
the exact well-formed shape below — anything else is INVALID),
EdDSA signature, the required omega:typ claim, subject binding
(sub == receiptId), and the emitter key-thumbprint binding all have to pass.
A receipt proves the record existed in exactly this form when it was signed
— key-holder attestation, never agent behavior. Spec: docs/OMEGA_RECEIPT_V1_RFC.md.
Two-sided receipt pairs (since 0.4.0)
A receipt may carry a counterparty binding:
"counterparty": {
"transactionId": "tx-2026-07-15.settlement-441",
"counterpartyBodyHash": "<sha256 of the OTHER party's pre-counterparty canonical body>",
"binding": "references"
}binding: "references" is named honestly: this receipt references that
unsigned body hash. A single populated receipt proves one-sided intent only — it
does not claim the counterparty referenced it back. Mutuality is a property of a
pair:
import { verifyReceiptPair, computeReceiptCoreHash } from "@omegaengine/verify";
const pair = verifyReceiptPair(receiptA, receiptB, jwks);
// pair.verdict: "mutual" | "one_way" | "invalid"
// pair.valid: true ONLY for "mutual" (fail-closed gate)verifyReceiptPair checks that both receipts verify individually, that each
side's counterpartyBodyHash equals the other side's pre-counterparty core
hash (computeReceiptCoreHash — the phase-1 hash of the two-phase construction),
and that both bindings name the same transactionId. Exactly one matching
direction is reported as one_way, never as mutual.
What a
mutualpair proves — and doesn't. Mutual attestation of the two bodies by the two signing keys, plus (if anchored) time of existence. It does not prove the transaction occurred, and it is not collusion resistance — two cooperating keys can mutually attest anything. Collusion resistance comes only from identity cost, external rails, and graph analysis.
Delegation grants — records, not permissions (since 0.4.0)
The package also verifies omega/grant.v1 delegation records and the
grantChain references a receipt may carry.
The record-only truth (read this before wiring anything). A grant RECORDS that a grantor delegated typed scopes to a recipient. Grants authorize NOTHING. A verified grant proves "X recorded delegating scopes to Y" — never "Y was allowed". A verified chain proves a recorded delegation lineage that narrows monotonically — never permission at any link. Do not consult grants (or grant chains) in any authorization decision; they are evidence for audits and disputes, not an access-control mechanism.
A receipt's grantChain is by reference: [] or an ordered list (1–5) of
64-hex grantHash values, root-first. verifyReceipt validates only that
shape — fetch the referenced grants and verify the chain yourself:
import { verifyGrant, verifyGrantChain } from "@omegaengine/verify";
// one record: shape → content hash → EdDSA JWS → required omega:typ ("omega/grant.v1") → sub binding
const g = verifyGrant(grant, jwks);
// a chain, root-first, offline (each grant embeds its parent's grantHash):
// depth ≤ 5, per-grant verification, no cycles, intact parent links, one org per
// chain, delegation continuity (child.grantor = parent.recipient, pinned
// key-thumbprint continuity), scope narrowing at EVERY link under the typed
// lattice (reject-on-unknown-kind), expiry monotonicity.
const c = verifyGrantChain([root, mid, leaf], jwks);
// c.verdict: "valid" | "invalid" · c.failedAt: index of the first failing linkGrants are born typed: the signed payload must carry
"omega:typ": "omega/grant.v1", so an attestation, tree-head, or receipt
signature can never be replayed as a grant (and an untyped legacy JWS is
INVALID). The v1 scope lattice has exactly three kinds — endpoint and
action-category (string equality; no wildcard semantics, * is an ordinary
character) and risk-ceiling (numeric; a child may only lower it) — and an
unknown kind anywhere invalidates the check (never "valid, scope ignored").
model-provenance.v1 receipts (since 0.6.0)
The signed AI-BOM answer: which models produced or influenced a decision's
verdict. verifyReceipt is profile-agnostic, so these receipts verify with
every published version >= 0.4; 0.6.0 adds the typed strict checker:
import { verifyReceipt, isModelProvenanceContents } from "@omegaengine/verify";
const ok = verifyReceipt(receipt, jwks).valid && isModelProvenanceContents(receipt.contents);
// contents.models: [] is a POSITIVE signed claim — no model influenced the verdict.
// The profile carries no cost fields by design: estimates never enter a signed artifact.CLI note (0.6.0): both --api=URL and --api URL now parse (older versions
silently ignored the space form and fell back to the default host).
Self-sovereign agent identity, revocation & witnesses (since 0.5.0)
Verify — offline, without trusting OmegaEngine — that an agent is who it claims, whether its key is revoked, and whether the transparency log itself is witnessed.
import {
verifyAgentIdentity, // self-signed omega/agent-identity.v1 (agent holds its own Ed25519 key)
verifyRevocation, // self-signed key revocation
verifyRecoveryRevocation, // revoke via a pre-designated recovery key (lost-primary case)
verifyRecoveryRevocationThreshold, // M-of-N recovery
verifyAnyRevocation, // dispatch self/recovery → { revokedThumbprint, revokedAt }
evaluateRevocationSet, // is thumbprint T revoked, given a set of records?
evaluateLiveness, // log-anchored liveness: order recovery vs revocation by transparency-log seq
verifyWitnessedCheckpoint, // threshold witness cosignatures over a signed tree head
} from "@omegaengine/verify";
// Identity is the RFC-7638 thumbprint of the AGENT's key — not a platform-assigned id.
const id = verifyAgentIdentity(proof); // { valid, keyThumbprint, agentId?, recoveryKeys? }
// A checkpoint is "witnessed" only when >= threshold registered witnesses co-signed
// the same (logId, treeSize, rootHash) — defeats split-view without trusting the log signer.
const w = verifyWitnessedCheckpoint(sth, cosignatures, { jwks, witnessKeys, threshold });
// w.valid · w.witnessCount · w.trustBasis: "witnessed" | "unwitnessed"All are born-typed and fail-closed, mirroring the server byte-for-byte. evaluateLiveness
trusts each record's log seq to the same degree it trusts the transparency log (the
single remaining assumption the witness network narrows) — it does not itself verify a
Merkle inclusion proof; that is called out honestly in the source.
Why a separate package?
The whole point of an attestation is that you don't have to trust the issuer. The old
v1 watermark was an HMAC — only OmegaEngine could check it. v2 is asymmetric: the public
key is published, so anyone can verify with this tool, with their own JOSE library,
or with openssl. This package is just the convenient path.
Attestations are automated red-team evidence, not a third-party certification. See
docs/ATTESTATION_VERIFICATION.mdfor the full method (including the raw path).
Apache-2.0.
