1329 Commits
Author SHA1 Message Date
Trong Huu Nguyen d0fccc8d61 build: go 1.26.6 2026-08-14 12:28:31 +02:00
Trong Huu Nguyen 967282e47b docs: unescape quotes in the new-client-auth-jwt-type row
The escaping came from the Go flag string and has no meaning in Markdown.
2026-08-10 12:37:31 +02:00
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 90ceca2382 build(deps): bump jwx to v3.2.0 2026-08-10 10:08:39 +02:00
Trong Huu Nguyen 578541414c ci: bump github actions 2026-08-10 10:06:48 +02:00
Trong Huu Nguyen b71e1b0b0f refactor(handler/sso/server): remove redundant logout overrides
These are no longer necessary after d2e01b2e.
2026-08-10 09:58:05 +02:00
Trong Huu Nguyen f2567ccdfe feat(mock): enforce unique jti and lifetime for client assertions 2026-08-06 13:22:10 +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 20f9a50fe4 ci: only run staticcheck and govulncheck for scheduled checks 2026-08-06 12:45:35 +02:00
Trong Huu Nguyen 14c526c443 build: use latest mock-oauth2-server [ci skip] 2026-08-04 09:19:05 +02:00
Kyrre HavikandGitHub c84349f422 fix(chart): use correct aivenapp spec 2026-08-03 10:44:17 +02:00
Trong Huu Nguyen aa74b67a33 refactor: remove unreachable functions
Both were reported by deadcode: retry.WithBase was never used, and
PrometheusMiddleware.Initialize is a leftover from the chi-prometheus
code this middleware was adapted from.
2026-07-28 12:52:45 +02:00
Trong Huu Nguyen cb14d1624f fix(metrics): record on the collector that is actually registered
When an equal collector was already registered, the caller kept using
its own instance, whose observations are never scraped. RegisterCollector
now returns the registered collector so callers can adopt it.
2026-07-28 12:52:45 +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 b99a00479d fix: annotate reviewed gosec findings
Each finding was reviewed individually; the annotations record why the
flagged code is safe rather than suppressing the rules globally.

- G101: viper configuration keys, not credentials
- G117: the marshalled value is the plaintext input to the encryption
  that immediately follows, or a token endpoint response that is
  required to carry tokens
- G118: the background deletion must outlive the request, so the
  request context deliberately is not used
- G124: cookie attributes are validated in config.Cookie.Validate
- G710: the redirect targets are relative by construction, validated by
  the url validators, or read from the provider's metadata document
2026-07-28 12:52:34 +02:00
Trong Huu Nguyen 9600b8ffda fix(mock): set ReadHeaderTimeout on the relying party server
The bare http.Server replaces the one httptest provides, dropping its
timeouts along with it.
2026-07-28 11:43:54 +02:00
Trong Huu Nguyen 29c7de357e fix(handler): scope the background session deletion error
The retry callback assigned to the enclosing if-scoped err instead of
declaring its own. Nothing read that variable after the handler
returned, so behaviour is unchanged.
2026-07-28 11:43:54 +02:00
Trong Huu Nguyen 0d6d4a0dff fix(http): encode the unauthenticated response as JSON
The response was built by concatenating the request path into a JSON
string. The path is percent-decoded, so it can contain quotes and
backslashes, which produced malformed JSON and let a caller inject
arbitrary keys into the object.
2026-07-28 11:43:54 +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 ea20e96f87 fix(metrics): log collector registration failures
Registration errors were discarded, leaving the collector silently
absent from the metrics endpoint while the vectors still recorded.
Duplicate registrations remain ignored; they are expected when several
instances are constructed in the same process.
2026-07-28 09:05:04 +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 4aef16afa4 build: move go tools to mise 2026-07-27 15:13:11 +02:00
Trong Huu Nguyen ff4df10853 build(deps): bump go dependencies 2026-07-27 14:46:43 +02:00
Trong Huu Nguyen cedece937e ci: bump github actions 2026-07-27 14:38:38 +02:00
Trong Huu Nguyen cc0f342955 build: go 1.26.5 2026-07-27 14:31:04 +02:00
Trong Huu Nguyen 704f455291 refactor(session): replace -1 sentinels with named constant
Introduce SecondsNotApplicable for *_in_seconds fields whose feature is
disabled (no inactivity timeout, auto-refresh off), replacing scattered
magic -1 values and the post-construction mutation in Verbose(). JSON
output is unchanged.
2026-06-10 16:58:52 +02:00
Trong Huu Nguyen 08cf4260e7 refactor(session): clarify token refresh scheduling
Consolidate the refresh schedule into a single NextRefresh function (leeway +
inactivity half-life, floored at the cooldown). ShouldRefresh now defers to it,
so the explicit cooldown gate is redundant and removed. Add doc comments naming
the mechanisms. No behavior change.
2026-06-10 16:58:41 +02:00
Trong Huu Nguyen 8fbd4656db fix(session): refresh tokens 30s before expiry instead of 5m
Refreshes are activity-based and synchronous-on-expiry, so the proactive
leeway only hides refresh latency and provides retry headroom; it is not
what prevents serving expired tokens. Shrink it from 5m to 30s to align
with identity provider guidance against refreshing long before expiry,
while keeping decent end-user UX.
2026-06-10 16:57:54 +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 e7788d29ab build(deps): bump direct dependencies 2026-06-09 09:58:08 +02:00
Trong Huu Nguyen 57c6d53d64 feat(charts): use otel endpoint from fasit 2026-06-05 13:53:09 +02:00
Trong Huu Nguyen 300809f0ff build: go 1.26.4 2026-06-03 09:18:28 +02:00
Trong Huu Nguyen f8b672549a fix(otel): use NewSchemaless to avoid semconv schema URL conflicts 2026-05-29 08:34:27 +02:00
Trong Huu Nguyen 6fa8f52718 build(deps): upgrade direct dependencies
- chi/v5 v5.2.5 -> v5.3.0
- redislock v0.9.4 -> v0.10.0
- x/crypto v0.51.0 -> v0.52.0
- miniredis/v2 v2.37.0 -> v2.38.0
- liberator cdeda47 -> 791cc0e
2026-05-26 14:12:20 +02:00
Trong Huu Nguyen c166595412 ci: update actions 2026-05-26 13:39:54 +02:00
Trong Huu Nguyen a8c5ad891f style: go fmt 2026-05-26 13:27:55 +02:00
Trong Huu Nguyen 8b88874ffb build: go get tool 2026-05-26 13:27:49 +02:00
Trong Huu Nguyen c7a625a0c5 ci: fasit-deploy@v4 2026-05-12 12:43:44 +02:00
Trong Huu Nguyen 66d2a14e47 fix(handler/error): respect log level parameter in respondError
The previous if/else only checked for WarnLevel, causing any other
level (e.g. InfoLevel in 24fb9b1) to fall through to Errorf. Use Logf to
dispatch on the actual level passed by callers.
2026-05-11 15:28:39 +02:00
Trong Huu Nguyen 8774f4dfab build(deps): update direct dependencies
- lestrrat-go/jwx/v3 v3.1.0 -> v3.1.1 (security hardening)
- redis/go-redis/v9 v9.18.0 -> v9.19.0 (bug fixes)
- riandyrn/otelchi v0.12.2 -> v0.12.3 (metrics fixes)
- golang.org/x/crypto v0.50.0 -> v0.51.0
- nais/liberator pseudo-version bump
2026-05-11 08:52:38 +02:00
Trong Huu Nguyen c3691be136 ci: add sandboxed daily checks for staticcheck, govulncheck, and tests 2026-05-11 08:35:59 +02:00
Trong Huu Nguyen 48a65a800d build: go 1.26.3 2026-05-08 09:00:59 +02:00