Validation: westside-admin#15 — hooks.server.ts admin role gate

validation-15-2026-05-03 Doc

validation pass

Ticket

forgejo_admin/westside-admin#15 (PR #20, merged). Implements the per-request `handle` hook that reads the encrypted session cookie, validates the JWT against the JWKS, populates event.locals.user, and enforces the admin realm role.

Environment

  • URL: https://westside-admin.tail5b443a.ts.net
  • Cluster image SHA at validation: 63e708dc (after #25 cookie-size fix and #27 azp-acceptance fix)
  • Test user: draneylucas@gmail.com (realm-roles include admin)

Checks

# Criterion How to Verify Result Evidence
1 Anonymous request to / 302s to /auth/login?redirect=/ curl unauthenticated GET / PASS Live curl: status 302, Location: /auth/login?redirect=%2F
2 Valid session cookie + admin role passes through Full SSO round-trip → GET / with cookies PASS GET / returned 200 with <code>&lt;h1&gt;westside-admin&lt;/h1&gt;</code>; Playwright headless Chromium also confirmed (no redirect loop)
3 /health bypasses auth gate (k8s probes) Pod readinessProbe hits /health unauthenticated PASS Pod has been Ready for 76s+ post-roll; readinessProbe hits /health and got 200
4 /auth/* bypasses auth gate GET /auth/login (no cookie) returns 302 to Keycloak (not to itself) PASS Live trace shows /auth/login → Keycloak /authorize, no recursive /auth/login
5 tampered/expired/wrong-key cookie treated as anonymous Implicit: previously-broken state had this exact behavior — wrong-aud rejection routed to anonymous redirect path (logged in #26's repro) PASS Bug #26 reproduced this code path: hook caught JwtVerificationError, deleted cookie, 302 to /auth/login. No 5xx ever observed.
6 cookie attributes correct (HttpOnly+Secure+SameSite=Lax+Path=/) Inspect Set-Cookie on /auth/callback response PASS Live curl captured: <code>HttpOnly; Secure; SameSite=Lax; Path=/</code> on the session cookie

Verdict

PASS — gate works for the validated user (admin role). The missing-admin path renders the (unauthorized) 403 group, validated separately under validation-17-2026-05-03.

Discovered Issues

Two surfaced during this validation pass: (1) cookie size exceeded browser limit — fixed in #24/PR#25; (2) JWT aud claim mismatch — fixed in #26/PR#27. Both were latent defects in code that statically passed QA but failed under live runtime conditions. Both now resolved.