mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-07 16:03:21 +00:00
- Resolve a guest JWT on the lowercased email. Accounts are stored lowercased, so a mixed-case `email` claim slipped past the no-account gate and resolved an account holder to a guest, and split the activity rows the seat count reads. `has_any_account` now normalises its input too (index-friendly, not `lower(email)`). - Cap the auth-cache entry for a guest JWT at 5 minutes rather than the token's `exp` (up to 24h). A guest JWT is revocable only by the workspace switch or by rotating the key; the short entry makes a rotated or cleared key bite on re-verification, and makes the day-keyed activity dedupe reachable across a midnight (the second-day row was never written). - Audit `users.login_guest` only when the upsert freshly inserts the row (`xmax = 0`), decided atomically by the DB, so concurrent first requests and separate API nodes emit it at most once a day. - JWKS hardening: read the body with a 1MB cap instead of buffering any size; an alg-less RSA key accepts the whole RSA family instead of being forced to RS256; a failed fetch serves the last good keys (or a short negative entry) so an unreachable issuer is hit at most once per 30s however much unauthenticated `jwt_guest_` traffic arrives, and an unknown `kid` never triggers a fetch; lower the fetch timeouts to 5s/10s. - Settings copy: note that the JWKS should point at an issuer you control, since neither `iss` nor `aud` is bound. - Tests: a mixed-case account and an over-24h lifetime are refused; unit tests pin `jwk_algorithms` (including the alg-less RSA family) and a JWK-derived key verifying a real token. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VF3v6LA9399gNphmZaHYG3