feat(auth): register the estate dashboard as an OIDC client - #84
Merged
Merged
Conversation
Adds `estate-dashboard`, the tribelt shape: a confidential client (client_secret_basic and client_secret_post) that also requires PKCE, authorization_code plus refresh_token, scopes openid profile email, no consent. Redirect https://estate.jorisjonkers.dev/auth/callback and post-logout redirect to the site root, with the .test variants. The secret comes from auth.clients.estate-dashboard.secret, supplied as AUTH_CLIENTS_ESTATE_DASHBOARD_SECRET. The dash-dropping AUTH_CLIENTS_ESTATEDASHBOARD_SECRET form does not resolve the @value placeholder; checked against a system-environment property source. The client is deliberately absent from DOWNSTREAM_CLIENT_PERMISSIONS. The dashboard reads ROLE_ADMIN from the roles claim itself and shows a non-admin its own Not-an-admin page, which a 403 from the authorize endpoint would pre-empt. The integration tests run the real flow and reach a code: authorize parameters go in the query string, because the authorization server reads a GET authorization request from the query string alone. The older downstream-client tests pass them through MockMvc param(), get 400 "OAuth 2.0 Parameter: response_type", and return early. An admin sees ROLE_ADMIN in the ID token, and again after a refresh; a non-admin gets a code and no ROLE_ADMIN. Closes #79
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Registers
estate-dashboardas a confidential OIDC client that also requires PKCE, for the estate delivery dashboard at estate.jorisjonkers.dev (JorisJonkers-dev/estate-dashboard).buildEstateDashboardClient(): authorization_code + refresh_token, client_secret_basic/post, PKCE required, no consent, default token settings, scopesopenid profile email, redirecthttps://estate.jorisjonkers.dev/auth/callback, post-logout redirecthttps://estate.jorisjonkers.dev/(plus the.testvariants every downstream client carries).DownstreamClientSecrets.estateDashboard, fromauth.clients.estate-dashboard.secret.Closes #79. Part of JorisJonkers-dev/deploy-kit#195.
Why this shape
The dashboard is admin-only, but the client is deliberately not in
DOWNSTREAM_CLIENT_PERMISSIONS. JorisJonkers-dev/estate-dashboard#2 has the dashboard readROLE_ADMINfrom the ID token'srolesclaim and show a non-admin its own Not-an-admin page; a 403 from the authorize endpoint would pre-empt that page. So every signed-in user gets a code, and refusing non-admins rests on the dashboard's own check. There is no newServicePermission, and no migration.The ID token already carries
roleswithROLE_ADMINfor admins, and the customizer re-reads the user on refresh, so a renewed token keeps it and a demoted admin loses it at the next renewal.Deploy prerequisites
auth.clients.estate-dashboard.secretinsecret/data/auth-api(written before the fleet-infra change lands).AUTH_CLIENTS_ESTATE_DASHBOARD_SECRETto the auth-api template. The dash-droppingAUTH_CLIENTS_ESTATEDASHBOARD_SECRETdoes not resolve the@Valueplaceholder; checked against a system-environment property source. Until then the@Valuedefault applies and the client is unusable in production.Verification
:api:test :api:ktlintCheck :api:detekt: 209/209, clean.:api:integrationTest(Testcontainers): 250/250.ROLE_ADMINin the ID token and again after a refresh-token grant; a non-admin gets a code and noROLE_ADMIN. Removing the client's registration turns both red.param(), get400 OAuth 2.0 Parameter: response_type, and return early, so they never reach a code. Fixing those is Make the downstream OIDC flow tests reach an authorization code #83.