@crelis/verify
v0.1.0
Published
Offline verifiers for Crelis Execution Grants and audit checkpoints (EdDSA JWS + JWKS).
Maintainers
Readme
@crelis/verify (TypeScript / JavaScript)
Offline verifiers for Crelis Execution Grants and audit checkpoints
(evidence). Each is a standard EdDSA JWS you verify against the tenant's
published JWKS with jose — offline, no call
back to Crelis, no shared secret. Verification is fail-closed and honest about
what it cannot check offline.
npm install @crelis/verify # peer runtime dep: joseESM, Node ≥ 18 (uses WebCrypto). Ships type declarations.
Verify an execution grant
import { verifyGrant, GrantInvalid } from "@crelis/verify";
const tenant = "acme";
const jwks = await (await fetch(
`https://<host>/grants/t/${tenant}/.well-known/jwks.json`)).json();
try {
const r = await verifyGrant(token, {
jwks,
tenantId: tenant, // bound to the JWKS you fetched
endpointId: "pay.enforce", // the exact seat presenting the grant
audience: "pay.internal", // that endpoint's REGISTERED audience
actionType: "wire_transfer", // the action you are about to run
resource: "payee-42", amount: 100.0,
});
// r.claims.* are cryptographically bound. r.signatureVerified === true, but
// r.chainVerified / r.replayChecked / r.revocationChecked are false (online-only).
} catch (e) {
if (e instanceof GrantInvalid) return deny(e.reason);
throw e;
}verifyGrant throws GrantInvalid (with .reason) on a bad signature, wrong
type, expiry, wrong audience, wrong tenant, wrong endpoint, wrong
action/resource/amount, or a missing binding. tenantId, endpointId and
audience are required; the action is required unless you pass
requireAction: false (for an advisory/observe-only seat).
Offline-valid is not authority to execute. A grant is single-use
(max_uses: 1); consume its jti once and check revocation online before acting.
Verify audit evidence (checkpoints)
import { verifyCheckpoint, detectRegression, verifySequence } from "@crelis/verify";
const jwks = await (await fetch(
`https://<host>/evidence/t/${tenant}/.well-known/jwks.json`)).json();
const cp = await verifyCheckpoint(token, { jwks, tenantId: tenant }); // throws if not authentic
// Compare two checkpoints you retained (earlier -> later):
const problem = detectRegression(olderCp, newerCp); // null | "TRUNCATION: ..." | "REWRITE: ..." | "BACKDATING: ..."
// Or verify a whole retained run at once:
const cps = await verifySequence([t0, t1, t2], { jwks, tenantId: tenant });A checkpoint proves integrity of the prefix, non-repudiation, and — across
checkpoints you retain — no truncation/rewrite/backdating. It does not prove
inclusion of a specific event (needs a Merkle proof), that an entry is true, or
independent time (issued_at is Crelis's clock). Retain the checkpoints you are
given — the guarantee is real only once a copy lives where Crelis cannot reach.
Compatibility
Versioned independently of the Trust Engine. The compatibility surface is the
token format (grant ver ceap/1, checkpoint version
crelis-audit-checkpoint/1); a change to either is a MAJOR bump here.
Apache-2.0 · © Crelis Labs Pte. Ltd. (UEN 202634291E)
