Skip to content
v1.15.2July 6, 2026

Massu v1.15.2

**CRITICAL production fix: the `validate-key` cloud edge function returned HTTP 500 on every real API key (deploy drift), silently downgrading every Enterprise/Pro customer to Free** (`plan-2026-07-06-validate-key-deploy-drift`). The DEPLOYED `validate-key` Supabase edge function was a stale bundle that never receiv...

CRITICAL production fix: the validate-key cloud edge function returned HTTP 500 on every real API key (deploy drift), silently downgrading every Enterprise/Pro customer to Free (plan-2026-07-06-validate-key-deploy-drift). The DEPLOYED validate-key Supabase edge function was a stale bundle that never received the 2026-05-31 compareSync fix — it still called the async bcrypt compare(), which spawns a Web Worker the Supabase Edge Runtime forbids, so it threw → HTTP 500 on every real ms_live_ key. @massu/core's license path (validateLicense) treated the 500 as "Free", so every paid key silently resolved to Free (surfaced during git-safe-api-key dogfooding, 2026-07-05). The repo source was already correct; the fix redeploys it (wrong-key probe now returns 401, not 500) — no customer key changes, no re-hashing, no bcrypt/WebCrypto re-engineering (the cause was a missed deploy, not a library bug). Patch per semver: a bug fix with no API change. Incident: docs/incidents/2026-07-06-validate-key-deploy-drift-500.md.

Fixed

  • validate-key edge function 500'd on every real API key (deploy drift). The live bundle (version 8, 2026-05-31) still imported the async compare() (Web-Worker → forbidden in the Supabase Edge Runtime → throw → HTTP 500) five weeks after e7d67f6 fixed the repo source to route through verifyApiKeyHash/compareSync; the validate-key redeploy of that fix never actually landed. Verified from the deployed bundle via supabase functions download; blast radius confirmed = validate-key only (the other 6 API-key edge functions were already correct). Redeployed the correct source.
  • massu login / massu doctor reported "Free" when the license server had errored or was unreachable. validateLicense now returns a LicenseValidationOutcome (validated / rejected / server_error / network_error / grace / cache_fresh / no_endpoint / no_key); login and doctor distinguish an authoritative Free from a "could not validate (server error / offline) — tier UNKNOWN" state, so a server 500 is never misreported as a Free downgrade (this masking is why the outage looked like "Free").

Added

  • CR-60: API-key edge functions MUST be deploy-verified (three-layer structural drift-prevention). (1) A source drift-guard (website/src/tests/edge-async-bcrypt-compare-drift.test.ts, vitest, CI + pre-push) fails if any edge function imports or calls the async bcrypt compare( — hashing must route through verifyApiKeyHash/compareSync; catches a function bypassing the shared helper (which the Deno helper test cannot). (2) A canonical edge-deploy + post-deploy real-key smoke test (scripts/massu-deploy-edge-functions.sh) fails the deploy unless a known-good key validates (HTTP 200 + expected tier) and a wrong key returns 401 (scripts/massu-deploy.sh deploys only Vercel, so it could never have caught this). (3) A Guardian readiness watcher (massu_validate_key_readiness_watcher, hourly) POSTs a known-good key to the live gateway and fires CRITICAL on any 500 / non-200 / wrong tier — this class had zero alerting.

Try this release

Install the latest version of Massu and start governing your AI development today.