Skip to content

v3.3.1

Choose a tag to compare

@github-actions github-actions released this 12 Aug 08:34
· 119 commits to master since this release

Security fix — caller-supplied policy clock

evaluatePolicy resolves its clock as context.timestamp ?? new Date(). All three governor call sites spread caller-supplied params into the PolicyContext and then re-assert the trusted fields (model, tier, budget tiers, cost_center) — but timestamp was missing from that re-assertion at every site.

Impact. A caller could supply the clock that policy time-window rules are matched against: escaping a live curfew rule, or inflicting a dormant one. The same forged value also reached PolicyResult.evaluatedAt, which flows into denial evidence.

Who is most exposed. packages/server (usertrust-server) wraps the headless governor, so there the caller is a remote tenant over HTTP and the value arrives in a request body. The two in-process govern.ts routes require code already running inside your process.

Who should upgrade. Anyone using policy timeWindows on usertrust-server, or calling the headless governor with caller-supplied params. We cannot survey adopters of the published packages — if you use time-window rules anywhere, take this patch.

What did not change. PolicyContext.timestamp remains a legitimate trusted-host input for a host that builds its own context and calls evaluatePolicy directly; only the request-body route through the governors is closed. Time-window matching remains local time by contract — moving it to UTC would have silently altered deny behavior for every deployed policy carrying a window.

Evidence. clock-shadow.test.ts: four decision-level pairs (escape a live window / inflict a dormant one) across all three sites, each holding the forged value constant and moving only the real clock, plus one explicitly-declared vacuity guard. Verified failing-first twice — in TDD order during implementation, and re-confirmed from a clean revert in an isolated replica (8 failed / 1 passed, the pass being the guard). Post-fix 9/9; full suite green in CI.

PR #95 · commit ab7177d. No API changes; drop-in from 3.3.0.