add auth to frontend through lib #284

Merged
johnride merged 18 commits from feat/dashboard-auth into feat/fleet-operator-web-frontend-maud 2026-05-19 20:37:10 +00:00
Owner

Adds OIDC login support to the harmony-fleet-operator web dashboard using Zitadel SSO.

pkce was the recommended option for this since we don't need to hold on to any secret. We compute a value on server before sending the data to Zitadel who validates authenticity by recomputing the hash and comparing the two values.

pkce Auth flow

  1. User visits a protected dashboard route, like /devices.
  2. If no valid harmony_fleet_session cookie exists, the app redirects to /login.
  3. /login creates:
    • random state
    • random pkce_code_verifier
    • derived code_challenge = base64url(sha256(pkce_code_verifier))
  4. The app stores state and pkce_code_verifier in a temporary HTTP-only login-attempt cookie.
  5. The browser is redirected to Zitadel’s authorize endpoint with:
    • client_id
    • redirect_uri
    • scope
    • state
    • code_challenge
    • code_challenge_method=S256
  6. After SSO login, Zitadel redirects back to /auth/callback?code=...&state=....
  7. The callback handler:
    • parses the raw query into a strict success/failure enum
    • reads the temporary login-attempt cookie
    • validates returned state
    • exchanges code + pkce_code_verifier for tokens
    • validates the returned ID token using OIDC discovery/JWKS
    • creates a local harmony_fleet_session cookie
    • redirects to /
  8. Protected routes validate the local dashboard session cookie on each request.
  9. /logout clears the dashboard session cookie and redirects to /login.

Auth middleware responses depending on request type:

  • normal browser request: redirect to /login
  • SSE request: 401 authentication required
  • HTMX request: 401 with HX-Redirect: /login (HTMX redirect is more idiomatic than through Axum for this)
Adds OIDC login support to the harmony-fleet-operator web dashboard using Zitadel SSO. pkce was the recommended option for this since we don't need to hold on to any secret. We compute a value on server before sending the data to Zitadel who validates authenticity by recomputing the hash and comparing the two values. pkce Auth flow 1. User visits a protected dashboard route, like /devices. 2. If no valid harmony_fleet_session cookie exists, the app redirects to /login. 3. /login creates: - random state - random pkce_code_verifier - derived code_challenge = base64url(sha256(pkce_code_verifier)) 4. The app stores state and pkce_code_verifier in a temporary HTTP-only login-attempt cookie. 5. The browser is redirected to Zitadel’s authorize endpoint with: - client_id - redirect_uri - scope - state - code_challenge - code_challenge_method=S256 6. After SSO login, Zitadel redirects back to /auth/callback?code=...&state=.... 7. The callback handler: - parses the raw query into a strict success/failure enum - reads the temporary login-attempt cookie - validates returned state - exchanges code + pkce_code_verifier for tokens - validates the returned ID token using OIDC discovery/JWKS - creates a local harmony_fleet_session cookie - redirects to / 8. Protected routes validate the local dashboard session cookie on each request. 9. /logout clears the dashboard session cookie and redirects to /login. --- Auth middleware responses depending on request type: - normal browser request: redirect to /login - SSE request: 401 authentication required - HTMX request: 401 with HX-Redirect: /login (HTMX redirect is more idiomatic than through Axum for this)
reda added 2 commits 2026-05-13 20:17:45 +00:00
remove sensitive logs
Some checks failed
Run Check Script / check (pull_request) Failing after 49s
0f6b5912e3
reda added 4 commits 2026-05-14 21:04:13 +00:00
use lib for auth
Some checks failed
Run Check Script / check (pull_request) Failing after 47s
40e350b406
reda changed title from add files for auth to add auth to frontend through lib 2026-05-14 21:05:39 +00:00
reda added 1 commit 2026-05-15 13:30:35 +00:00
add logout to lib and refactor env config
Some checks failed
Run Check Script / check (pull_request) Failing after 43s
3f47a42530
reda added 2 commits 2026-05-15 14:41:36 +00:00
change hardcoded url to env
Some checks failed
Run Check Script / check (pull_request) Failing after 44s
28df370a11
reda added 1 commit 2026-05-15 16:18:41 +00:00
add import
Some checks failed
Run Check Script / check (pull_request) Failing after 49s
0caf89a364
reda added 1 commit 2026-05-15 16:22:30 +00:00
format code
Some checks failed
Run Check Script / check (pull_request) Failing after 2m6s
a73511058f
reda added 1 commit 2026-05-15 16:30:23 +00:00
disable logs for ci
Some checks failed
Run Check Script / check (pull_request) Failing after 2m22s
3eba221e13
reda added 1 commit 2026-05-15 16:36:23 +00:00
install k3d before check
Some checks failed
Run Check Script / check (pull_request) Failing after 2m7s
2d837b5ff8
reda added 1 commit 2026-05-15 16:40:50 +00:00
remove k3d installation and ignore test in ci
Some checks failed
Run Check Script / check (pull_request) Failing after 2m4s
17ae1ee698
reda added 1 commit 2026-05-15 16:45:33 +00:00
ignore tests
Some checks failed
Run Check Script / check (pull_request) Failing after 2m3s
1087717295
reda added 1 commit 2026-05-16 19:21:55 +00:00
move cookie mngmt to lib
Some checks failed
Run Check Script / check (pull_request) Failing after 46s
3d2a5b21cb
reda added 1 commit 2026-05-19 17:58:53 +00:00
remove private jar and add cookie validation
Some checks failed
Run Check Script / check (pull_request) Failing after 42s
682b3f6c9c
reda added 1 commit 2026-05-19 20:05:28 +00:00
add ui redesign and update auth lib
Some checks failed
Run Check Script / check (pull_request) Failing after 48s
bb19bb0255
johnride approved these changes 2026-05-19 20:36:47 +00:00
johnride merged commit 96e7d43b2f into feat/fleet-operator-web-frontend-maud 2026-05-19 20:37:10 +00:00
johnride deleted branch feat/dashboard-auth 2026-05-19 20:37:10 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NationTech/harmony#284
No description provided.