@gnufoo/canaad
v2.0.0
Published
WASM bindings for AAD canonicalization per RFC 8785
Maintainers
Readme
canaad-wasm
AAD canonicalization for the browser and Cloudflare Workers. Same spec, same bytes as canaad-core.
Initialize
WASM must be initialized once before any function calls.
Browser / Cloudflare Workers:
import init, { canonicalizeDefault } from '@gnufoo/canaad';
await init();Node.js:
import { readFileSync } from 'node:fs';
import { initSync, canonicalizeDefault } from '@gnufoo/canaad';
initSync({ module: readFileSync(new URL('./canaad_wasm_bg.wasm', import.meta.url)) });Default profile
const bytes = canonicalizeDefault('{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}');
// → Uint8Array
const str = canonicalizeDefaultString('{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}');
// → string
const ok = validateDefault('{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}');
// → booleanGeneric object layer
Canonicalize any valid JSON object — no required fields, no version check:
const bytes = canonicalizeObject('{"z":"last","a":"first"}');
// → Uint8Array
const str = canonicalizeObjectString('{"z":"last","a":"first"}');
// → '{"a":"first","z":"last"}'
const ok = validateObject('{"anything":"goes"}');
// → trueUse this layer to build custom profiles.
Hash
SHA-256 of the canonical form (default profile):
const sha = hash('{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}');
// → Uint8Array (32 bytes)Build
import { AadBuilder } from '@gnufoo/canaad';
const aad = new AadBuilder()
.tenant("org_abc")
.resource("secrets/db")
.purpose("encryption")
.timestamp(1706400000)
.extensionString("x_vault_cluster", "us-east-1")
.extensionInt("x_app_priority", 5)
.build(); // → Uint8Array
const str = new AadBuilder()
.tenant("org_abc")
.resource("secrets/db")
.purpose("encryption")
.buildString(); // → stringNumbers only — no BigInt. build() and buildString() reject NaN, Infinity, negative, fractional, and values above Number.MAX_SAFE_INTEGER.
Constants
SPEC_VERSION() // → 1 (current AAD spec version)
MAX_SAFE_INTEGER() // → 9007199254740991 (2^53 - 1, max allowed integer value)
MAX_SERIALIZED_BYTES() // → 16384 (16 KiB size limit)Errors
Failed calls throw with a descriptive message:
try {
canonicalizeDefault('{"v":1}');
} catch (e) {
console.error(e.message); // "missing required field: tenant"
}Build from source
wasm-pack build --target web --out-dir ../../pkg crates/canaad-wasm--target web exports an explicit init() you control — works with Cloudflare Workers and Vite.
