142 Commits
Author SHA1 Message Date
Trong Huu Nguyen a8399a8f8f test: merge split test files into their package test files
The redirect and provider fetch tests lived in files of their own for no
reason other than how they were added.
2026-08-10 12:36:09 +02:00
Trong Huu Nguyen c399a781b6 fix(openid/provider): remove every alg=none key from the JWKS
RemoveKey shifts later keys into the removed index, so a forward loop skipped
the key after each removal. Two adjacent alg=none keys left the second one in
the set handed to signature verification.
2026-08-10 12:35:25 +02:00
Trong Huu Nguyen 4d67da8e61 test(crypto): generate JWK fixtures for any signature algorithm
Client assertion signing is algorithm-agnostic, but the fixtures only
produced RS256 keys, so nothing proved it. Covers RSA, ECDSA and Ed25519,
including both RFC 9864 identifiers.

Also drops a kty assignment that jwx ignores and that would have mislabelled
non-RSA keys had it taken effect.
2026-08-10 12:34:22 +02:00
Trong Huu Nguyen 6cf48cd668 feat(openid/config): validate client assertion alg against provider metadata
Fail at startup rather than on the first token request when the identity
provider does not accept the client assertion algorithm. The check is
skipped when the provider omits the field, which is optional in Discovery.
2026-08-10 12:33:16 +02:00
Trong Huu Nguyen 2c708d554c feat(openid/config): require and expose the client JWK algorithm
Both the assertion signer and the provider validation derived the algorithm
from the key and had to handle a missing "alg" that NewClientConfig already
rejects. Validate it once at construction and keep the result.
2026-08-10 12:32:04 +02:00
Trong Huu Nguyen f3f76fccc8 refactor(config)!: rename id-token-signing-alg to jwks-fallback-alg
The flag never described id_token verification. It assigns an algorithm to
provider JWKS keys that omit "alg", which is a compatibility shim for
providers such as Azure and ID-porten.

BREAKING CHANGE: openid.id-token-signing-alg is now openid.jwks-fallback-alg.
A config file with the old key fails to start. The old environment variable
is ignored and the value falls back to RS256.
2026-08-10 12:30:25 +02:00
Trong Huu Nguyen 47c10f5a9b fix(openid/client): mint new client assertions for each PAR retry 2026-08-06 13:12:15 +02:00
Trong Huu Nguyen b870e8ec7b fix(openid/client): cap client assertion lifetime to 5 seconds 2026-08-06 12:57:36 +02:00
Trong Huu Nguyen 070a4127ae test: cover the hardened provider fetch and client redirect policy
Verified that the redirect test fails without the CheckRedirect policy:
without it the redirect is followed and the target is reached.
2026-07-28 12:52:45 +02:00
Trong Huu Nguyen 4b56c77ddb fix(openid/client): refuse redirects for credential-bearing requests
Requests to the token and pushed authorization endpoints carry the
client secret or a signed client assertion. Following a redirect would
forward those credentials to a host the provider never advertised.
2026-07-28 11:43:53 +02:00
Trong Huu Nguyen 4d1d591448 fix(openid): bound and validate the provider metadata fetch
The metadata document was fetched with http.Get, which has no deadline,
so a hung connection blocked startup indefinitely. The response status
was never checked either, leaving an error page to surface as a JSON
decoding error.

The fetch now runs with a 10s deadline derived from the context passed
in from main, goes through the shared transport so it is traced and
pooled, and rejects any non-200 response.
2026-07-28 11:43:48 +02:00
Trong Huu Nguyen c56625d842 fix: check or explicitly ignore returned errors
Satisfies errcheck. Errors that carry no actionable information are
ignored explicitly: writes to an already-committed response, and closing
a fully read response body or file.

Test fixture setup asserts with require.NoError instead, since a failure
there means the fixture itself is broken.
2026-07-28 09:04:59 +02:00
Trong Huu Nguyen c6e711cd85 refactor: drop redundant embedded field selectors
Satisfies staticcheck QF1008.
2026-07-28 09:04:42 +02:00
Trong Huu Nguyen 9f3d10fcaf feat(openid/client): set nbf claim for client assertions 2026-06-09 10:00:22 +02:00
Trong Huu Nguyen c02a932d72 feat(openid): support domain_hint for authorization grant 2026-03-03 09:38:24 +01:00
Trong Huu Nguyen 02842773d3 style: go fix 2026-03-03 08:35:11 +01:00
Trong Huu Nguyen 466d0132e9 feat(openid): support logout_hint for RP-initiated logouts 2026-01-16 09:18:30 +01:00
Trong Huu Nguyen da69847027 feat(openid): add opt-in toggle for typ header in accordance with RFC7523bis
Some providers require that the `typ` header has a value exactly equal
to `client-authentication+jwt` in accordance with changes introduced by
RFC7523bis.

This commit allows for opting in to setting the `typ` header with this new value.

The default behaviour is to use the previous de facto standard value, `JWT`.
Once the changes in RFC7523bis lands in the affected standards and
identity providers start supporting the new `typ` header (Entra ID being
notable for not supporting this as of this commit), we will default to
use `client-authentication+jwt`.
2025-08-26 08:29:27 +02:00
Trong Huu Nguyen 75ff84ba28 refactor: suppress some noisy startup logs 2025-07-09 13:33:40 +02:00
Trong Huu Nguyen 4bf3b1bdd4 refactor: move string generator to crypto package 2025-06-16 09:55:44 +02:00
Trong Huu Nguyen 4e1c8e68f8 feat(openid): retry front-channel logouts 2025-06-16 09:55:44 +02:00
Trong Huu Nguyen 1a138c66a3 refactor: move retry package 2025-06-16 09:55:42 +02:00
Trong Huu Nguyen b3c2c72155 feat(openid): only set max_age parameter for prompt=login
We generally don't want to instruct the identity provider
to attempt full reauthentication when switching accounts
with `prompt=select_account`.
2025-06-11 13:28:52 +02:00
Trong Huu Nguyen 052d310280 fix(openid): require expires_in for token responses
While RFC 6749 specify this field as recommended:

> If omitted, the authorization server SHOULD provide the
> expiration time via other means or document the default value.

and equivalently the OIDC Core spec specifies the same field as optional,
we will explicitly enforce that these fields are returned from the AS.

This isn't a breaking change as the existing session refresh logic implicitly
depends on this field and its value.

While there are probably some providers that omit the `expires_in` field
or sets it to zero with the intent of returning access tokens that do not
expire, we assume these are relatively rare. We might revisit this
at some point in the future, should our assumptions be wrong.
2025-06-11 13:07:18 +02:00
Trong Huu Nguyen bf2f97f400 feat: set more session and token-related span attributes 2025-06-10 13:51:15 +02:00
Trong Huu Nguyen 9bb5ac9210 fix(openid/client): also accept acr and locale params when no defaults are configured 2025-05-23 09:00:45 +02:00
Trong Huu Nguyen b9963b19f9 refactor(openid): clean up id_token validation tests 2025-05-23 08:59:42 +02:00
Trong Huu NguyenandThomas Krampl c5ec362e60 feat(session): update id_token in session if returned from refresh grant
Co-authored-by: Thomas Krampl <thomas.siegfried.krampl@nav.no>
2025-05-22 15:52:15 +02:00
Trong Huu Nguyen 259bf635d1 chore(deps): bump github.com/lestrrat-go/jwx from v2 to v3 2025-05-21 10:38:26 +02:00
Trong Huu Nguyen ca8c09ae10 fix(openid/client): flatten audience for client assertion
In accordance with OpenID Connect 1.0 Core, draft 36 incorporating
errata set 3:

> aud
>    REQUIRED. Audience. The aud (audience) Claim. [...] The Audience value MUST be the OP's Issuer Identifier passed as a string, and not a single-element array.
2025-04-02 13:44:37 +02:00
Trong Huu Nguyen 01241f91ac perf: replace bytes.Buffer with strings.Builder 2025-04-02 11:53:30 +02:00
Trong Huu Nguyen 39d695e104 fix(openid/client): retry server errors for PAR 2025-03-06 10:05:58 +01:00
Trong Huu Nguyenandsindrerh2 79ac15d455 feat(otel): consistency passthrough for spans and attributes
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-30 14:03:39 +01:00
Sindre Rødseth HansenandTrong Huu Nguyen 07b542a2f5 feat(openid/error): add spans and attributes
Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-30 14:03:39 +01:00
Sindre Rødseth HansenandTrong Huu Nguyen dd0373b72d feat(openid/client): add spans and attributes
Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-30 14:03:38 +01:00
Trong Huu Nguyenandsindrerh2 787b54beeb refactor(crypto): move to internal
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-30 14:03:36 +01:00
Sindre Rødseth HansenandTrong Huu Nguyen ca77435d6a feat(http): propagate traceparent for httpclient
Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-30 14:03:30 +01:00
Trong Huu Nguyen 9c8055bcd6 feat(openid/client): fall back to default value for invalid parameter values
Instead of erroring when receiving non-empty, invalid parameters, we fall back to
the configured (if any) default value for the identity provider, which
is already validated with its metadata document on start-up.

This prevents end-users from being exposed to unnecessary errors.
2025-01-27 08:44:07 +01:00
Sindre Rødseth Hansenandtronghn c07077a148 refactor: extract method for making authCodeURL
Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-24 10:02:15 +01:00
Trong Huu Nguyen c147a5a19e refactor(openid): extract request params for remaining grants, minor cleanups 2025-01-24 08:07:54 +01:00
Trong Huu Nguyen 062e7b09ce fix(openid/client): prompt parameter is optional 2025-01-24 08:07:54 +01:00
Trong Huu Nguyen 0b32d8839c test(openid/client): add negative assertions for unwanted parameters 2025-01-24 08:07:52 +01:00
Trong Huu Nguyenandsindrerh2 110dd64750 refactor(openid/client): extract authorization code parameters
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-23 12:03:42 +01:00
Trong Huu Nguyenandsindrerh2 642457b950 refactor(openid/client): extract oauth request method
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-23 10:17:13 +01:00
Sindre Rødseth HansenandTrong Huu Nguyen ade44f0950 refactor: remove indirection layer for login client
Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-23 08:48:32 +01:00
Sindre Rødseth HansenandTrong Huu Nguyen c442000be4 feat: implement PAR for relying party
Fixes #235

Co-authored-by: tronghn <trong.huu.nguyen@nav.no>
2025-01-23 08:48:32 +01:00
Trong Huu Nguyenandsindrerh2 6be5a1ebe5 wip: implement PAR for relying party
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-23 08:48:32 +01:00
Trong Huu Nguyenandsindrerh2 909060d8fd feat(mock): implement PAR for identity provider
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-23 08:48:28 +01:00
Trong Huu Nguyenandsindrerh2 64e9167e05 refactor(openid/client): remove indirection layer for login callback
Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-21 09:39:23 +01:00
Trong Huu Nguyenandsindrerh2 75f98debc5 feat(openid/client): validate iss parameter if provider declares authorization_response_iss_parameter_supported
Fixes #306.

Co-authored-by: sindrerh2 <sindre.rodseth.hansen@nav.no>
2025-01-21 09:39:21 +01:00