@azmr/security
Release history for @azmr/security.
0.3.0
Minor Changes
-
c4f2c02: Add
createAccessControl— a framework-agnostic RBAC primitive:{resource, action, params} → {can, reason}.Policy is a static
Record<role, PolicyRule[]>grant map with"*"wildcards for role/resource/action, plus an optional per-ruleconditioncallback for record-level checks (e.g. ownership). An optionalresolvecallback lets a caller back checks with a database or any other backend —@azmr/securitynever imports a DB client itself, keeping this package dependency-agnostic. Fails closed by default (defaultEffect: "deny"); anonDecisionhook fires on every check (grant, deny, or resolver-sourced) for callers who want to wire it intocreateAuditLogger.Exported from both the Node entry point and
@azmr/security/browser— the module has no Node-only imports, and client-sidecan()checks are a legitimate UX-gating use case, though never a security boundary on their own.
0.2.0
Minor Changes
-
d70fccb: Upgrade workspace dependencies across the monorepo (pnpm 10 -> 11 tooling migration): React 18.3 -> 19.2 (
@azmr/ui), Zod 3.24 -> 4.4 (@azmr/security), better-sqlite3 11.7 -> 12.11 (@azmr/db), plus vitest, tsup, and@types/nodebumped to latest across all packages.typescriptstays pinned at^5.7.3(TypeScript 7 currently breakstsup's.d.tsbundling viarollup-plugin-dts). -
8b4512b: Add a browser-safe entry point (
@azmr/security/browser) exportingcreateRateLimiter,assertSafeIdentifier,sanitiseForLog, andvalidate- none of which touch Node.js built-ins. Fixes #10.Two functions moved into their own files, both for the same reason: a Node-only export sharing a file with browser-safe exports drags the Node dependency into any browser bundle re-exporting from that file, regardless of which specific export is actually used.
assertSafePath(usesnode:path) moved out ofsanitise.tsintopath-safety.tsvalidateEnv(readsprocess.env) moved out ofvalidate.tsintovalidate-env.ts- this one is a Node global reference rather than animport, so it doesn't fail the bundler build the way a missing module specifier does, it throwsReferenceErroronly if actually called client-side. Excluded from the browser entry; its own doc comment already describes it as a server-startup guard.
createJWTis also not included in the browser entry: it usesnode:crypto's synchronous HMAC/timingSafeEqual APIs, which have no browser equivalent - making it browser-safe would mean moving to the async Web Crypto API, a breaking change tosign()/verify()that's out of scope here.Verified two ways:
browser.test.tsrecursively walks the browser entry's full transitive import graph (not just direct re-exports) and asserts no file in it contains a Node builtin import (with or without thenode:prefix) or references a Node global (process,Buffer,__dirname,__filename) - this is the regression guard for thevalidateEnvclass of bug, which a plain import-statement check can't catch. Also manually builtapps/docs-next(Next.js/Turbopack) with a client component actually callingcreateRateLimiter/validatefrom@azmr/security/browser, confirming the fix against a real bundler.
Patch Changes
-
5bf56bb: Fix package metadata: mojibake in the description field (encoding mismatch, was showing garbled text on npm) and a missing LICENSE file in the published tarball despite being listed in
files.@azmr/aigot the same fixes plus missinghomepage/repository/author/keywords, but isn't included in this changeset - it's on changesets' ignore list and doesn't take version bumps this way.
0.1.0
Minor Changes
-
0a51a60: Phase 3 security hardening
@azmr/security: addcreateRateLimiter— sliding-window in-memory rate limiter with per-key tracking@azmr/security: addcreateJWT— HMAC-SHA256 JWT using Node built-in crypto, timing-safe verification, 15-min default expiry@azmr/db: addcreateColumnEncryption— AES-256-GCM column-level encryption with scrypt key derivation and GCM auth tag tamper detection@azmr/cli: addaudit:verifycommand — recomputes SHA-256 hashes and validates prevHash chain integrity of audit log files