Skip to content

Conversation

@alepane21
Copy link
Contributor

@alepane21 alepane21 commented Dec 23, 2025

By default, we force to check that the jwks keys have the use param set to "sig". By standard the value is optional and it could also be left empty.
With this PR I introduce two changes:

  • make the jwt validation errors more visible when logging debug level messages (nothing changes on the graphql error description)
  • allow to configure in the router the allowed "use" values

Summary by CodeRabbit

  • New Features
    • Added configuration to specify allowed JWKS "use" values and propagated it through authentication and JWKS handling.
  • Bug Fixes
    • Masked internal error details for unauthorized authentication responses and standardized unauthorized error payloads.
  • Tests
    • Added tests validating authentication behavior for allowed/denied JWKS "use" scenarios.
  • Documentation
    • Schema and testdata updated to include the new allowed_use configuration option.

✏️ Tip: You can customize this high-level summary in your review settings.

Checklist

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

Adds JWK "use" customization across tests, JWKS server, crypto marshalling, and token-decoder plumbing; propagates AllowedUse through supervisor and config/schema; masks unauthorized error details in GraphQL and websocket flows; and adds tests exercising the new use behavior.

Changes

Cohort / File(s) Summary
JWKS crypto & server options
router-tests/jwks/crypto.go, router-tests/jwks/jwks.go, router-tests/cmd/jwks-server/main.go
Added MarshalJWKWithUse(use jwkset.USE) to Crypto implementations and preserved MarshalJWK() as default; introduced ServerOption API (WithUse, WithProviders), serverConfig, and NewServerWithOptions(); JWKS server now marshals keys using configured use. Import reorder in jwks-server main (cosmetic).
Token decoder & allowed-use handling
router/pkg/authentication/jwks_token_decoder.go
Added AllowedUse propagation: JWKSConfig includes AllowedUse; introduced toJwksetUseType to map strings to jwkset.USE; createKeyFunc now accepts useWhitelist and applies it to keyfunc options; entries record allowedUse; error paths updated for invalid values.
Configuration & schema
router/pkg/config/config.go, router/pkg/config/config.schema.json, router/pkg/config/testdata/config_full.json
Added AllowedUse []string to JWKSConfiguration; added allowed_use schema entry (enum: "sig", "enc", "", default ["sig"]); testdata JWKS entries augmented with AllowedUse keys (null).
Supervisor / authenticator wiring
router/core/supervisor_instance.go
Propagates JWKS AllowedUse into authentication.JWKSConfig and passes the computed use whitelist into the token decoder construction.
Error handling / masking
router/core/access_controller.go, router/core/graphql_prehandler.go, router/core/websocket.go
On auth failure, join underlying error with ErrUnauthorized; GraphQL and websocket flows now mask or forward ErrUnauthorized so responses do not expose internal error details while preserving HTTP status codes.
Tests
router-tests/authentication_test.go
Added TestUseCustomization suite that starts JWKS test server with WithUse/WithProviders, builds tokens, and asserts authentication success/failure and X-Authenticated-By header for default vs allowed-use-empty-string scenarios.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the two main objectives: improving authorization error logging and enabling JWKS 'use' customization, matching the substantial changes across multiple files.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-c10641fe10f3397d7c9f7f0bc0308321faad5b6e-nonroot

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 79.41176% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.84%. Comparing base (45d65c4) to head (993f646).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
router/pkg/authentication/jwks_token_decoder.go 76.00% 3 Missing and 3 partials ⚠️
router/core/supervisor_instance.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2431       +/-   ##
===========================================
+ Coverage   36.95%   60.84%   +23.88%     
===========================================
  Files         834      229      -605     
  Lines      113800    23839    -89961     
  Branches     4693        0     -4693     
===========================================
- Hits        42052    14504    -27548     
+ Misses      70150     8089    -62061     
+ Partials     1598     1246      -352     
Files with missing lines Coverage Δ
router/core/access_controller.go 79.31% <100.00%> (ø)
router/core/graphql_prehandler.go 80.38% <100.00%> (-0.22%) ⬇️
router/core/websocket.go 75.46% <100.00%> (+0.06%) ⬆️
router/pkg/config/config.go 80.51% <ø> (ø)
router/core/supervisor_instance.go 0.00% <0.00%> (ø)
router/pkg/authentication/jwks_token_decoder.go 81.93% <76.00%> (-1.89%) ⬇️

... and 627 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alepane21 alepane21 changed the title feat: improve logging of auth errors feat: improve logging of authorization errors and allow use customization Dec 24, 2025
@alepane21 alepane21 marked this pull request as ready for review December 24, 2025 17:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
router/core/websocket.go (1)

399-410: Consider adding debug logging for the original error.

The error sanitization correctly prevents leaking internal error details to clients. However, unlike handleAuthenticationFailure in graphql_prehandler.go (which logs the original error at debug level on line 1143), this path silently discards the underlying error details. Consider adding a debug log to aid troubleshooting:

🔎 Suggested improvement
 			if h.accessController != nil {
 				handler.request, err = h.accessController.Access(w, r)
 				if err != nil {
 					statusCode := http.StatusForbidden
 					errorMessage := err
 					if errors.Is(err, ErrUnauthorized) {
 						statusCode = http.StatusUnauthorized
 						errorMessage = ErrUnauthorized
 					}
+					requestLogger.Debug("Failed to authenticate websocket connection from initial payload", zap.Error(err))
 					http.Error(handler.w, http.StatusText(statusCode), statusCode)
 					_ = handler.writeErrorMessage(requestID, errorMessage)
 					handler.Close(false)
 					return
 				}
 			}
router/pkg/authentication/jwks_token_decoder.go (2)

255-265: Consider clarifying the behavior for empty slice vs. nil.

The function returns [UseSig] when allowedUse is nil, but returns an empty slice when allowedUse is []string{}. This distinction might be confusing:

  • nil[UseSig] (default, restricts to "sig" use)
  • []string{} (empty slice) → [] (empty whitelist, might block all keys)
  • []string{""}[USE("")] (allows empty "use")

While this appears intentional for the use case, consider either:

  1. Treating empty slice the same as nil (return default), or
  2. Adding a comment explaining this behavior
💡 Optional: Treat empty slice as default
 func getUseWhitelist(allowedUse []string) []jwkset.USE {
-	if allowedUse == nil {
+	if len(allowedUse) == 0 {
 		return []jwkset.USE{jwkset.UseSig}
 	}
 
 	useWhitelist := make([]jwkset.USE, len(allowedUse))
 	for i, u := range allowedUse {
 		useWhitelist[i] = jwkset.USE(u)
 	}
 	return useWhitelist
 }

48-48: Add validation for AllowedUse values in getUseWhitelist().

The AllowedUse strings are cast directly to jwkset.USE without validation. While the jwkset library provides IANARegistered() for validation, the application should validate against the known USE values ("sig" and "enc" per RFC 7517) before passing them downstream. This prevents invalid values from propagating to the jwkset library.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8237c8d and 8fc525c.

📒 Files selected for processing (12)
  • router-tests/authentication_test.go
  • router-tests/cmd/jwks-server/main.go
  • router-tests/jwks/crypto.go
  • router-tests/jwks/jwks.go
  • router/core/access_controller.go
  • router/core/graphql_prehandler.go
  • router/core/supervisor_instance.go
  • router/core/websocket.go
  • router/pkg/authentication/jwks_token_decoder.go
  • router/pkg/config/config.go
  • router/pkg/config/config.schema.json
  • router/pkg/config/testdata/config_full.json
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.
📚 Learning: 2025-07-21T14:46:34.879Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.

Applied to files:

  • router-tests/cmd/jwks-server/main.go
  • router/pkg/config/config.schema.json
  • router/pkg/authentication/jwks_token_decoder.go
  • router/core/supervisor_instance.go
  • router/pkg/config/testdata/config_full.json
  • router-tests/jwks/jwks.go
  • router/pkg/config/config.go
📚 Learning: 2025-11-19T15:13:57.821Z
Learnt from: dkorittki
Repo: wundergraph/cosmo PR: 2273
File: router/core/graphql_handler.go:0-0
Timestamp: 2025-11-19T15:13:57.821Z
Learning: In the Cosmo router (wundergraph/cosmo), error handling follows a two-phase pattern: (1) Prehandler phase handles request parsing, validation, and setup errors using `httpGraphqlError` and `writeOperationError` (in files like graphql_prehandler.go, operation_processor.go, parse_multipart.go, batch.go); (2) Execution phase handles resolver execution errors using `WriteError` in GraphQLHandler.ServeHTTP. Because all `httpGraphqlError` instances are caught in the prehandler before ServeHTTP is invoked, any error type checks for `httpGraphqlError` in the execution-phase WriteError method are unreachable code.

Applied to files:

  • router/core/graphql_prehandler.go
📚 Learning: 2025-07-21T15:06:36.664Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/config/config.schema.json:1637-1644
Timestamp: 2025-07-21T15:06:36.664Z
Learning: In the Cosmo router project, when extending JSON schema validation for security-sensitive fields like JWKS secrets, backwards compatibility is maintained by implementing warnings in the Go code rather than hard validation constraints in the schema. This allows existing configurations to continue working while alerting users to potential security issues.

Applied to files:

  • router/pkg/config/config.schema.json
  • router/pkg/config/testdata/config_full.json
  • router/pkg/config/config.go
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections.

Applied to files:

  • router/pkg/config/config.schema.json
  • router/pkg/authentication/jwks_token_decoder.go
  • router/core/supervisor_instance.go
  • router/pkg/config/testdata/config_full.json
  • router/pkg/config/config.go
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections. The validation store maintains its own internal supported algorithms map that gets returned regardless of input parameters.

Applied to files:

  • router/pkg/config/config.schema.json
  • router/pkg/authentication/jwks_token_decoder.go
  • router/core/supervisor_instance.go
  • router/pkg/config/testdata/config_full.json
  • router/pkg/config/config.go
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: In the Cosmo router codebase, JSON schema validation prevents null values in TrafficShapingRules subgraph configurations, making nil checks unnecessary when dereferencing subgraph rule pointers in NewSubgraphTransportOptions.

Applied to files:

  • router/pkg/config/config.schema.json
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: router/pkg/config/config.schema.json forbids null values for traffic_shaping.subgraphs: additionalProperties references $defs.traffic_shaping_subgraph_request_rule with type "object". Therefore, in core.NewSubgraphTransportOptions, dereferencing each subgraph rule pointer is safe under schema-validated configs, and a nil-check is unnecessary.

Applied to files:

  • router/pkg/config/config.schema.json
  • router/pkg/config/testdata/config_full.json
📚 Learning: 2025-09-29T10:28:07.122Z
Learnt from: dkorittki
Repo: wundergraph/cosmo PR: 2192
File: router/pkg/config/config.go:1028-1029
Timestamp: 2025-09-29T10:28:07.122Z
Learning: The deprecation strategy for IntrospectionEnabled field in router/pkg/config/config.go is to first mark it as deprecated, then migrate all call sites to use IntrospectionConfig.Enabled, and finally remove the deprecated field. The envDefault tag should be kept during the deprecation period for backward compatibility.

Applied to files:

  • router/pkg/config/config.go
📚 Learning: 2025-08-28T09:59:19.999Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2167
File: router/core/supervisor_instance.go:196-204
Timestamp: 2025-08-28T09:59:19.999Z
Learning: In router/pkg/config/config.go, the BackoffJitterRetry struct uses envDefault tags to provide default values for Algorithm ("backoff_jitter") and Expression ("IsRetryableStatusCode() || IsConnectionError() || IsTimeout()"), ensuring that even when YAML configs omit these fields, valid defaults are applied automatically, preventing ProcessRetryOptions from rejecting empty values.

Applied to files:

  • router/pkg/config/config.go
🧬 Code graph analysis (3)
router/core/graphql_prehandler.go (2)
router/core/access_controller.go (1)
  • ErrUnauthorized (16-16)
router/pkg/pubsub/datasource/error.go (1)
  • Error (3-6)
router/core/websocket.go (1)
router/core/access_controller.go (1)
  • ErrUnauthorized (16-16)
router-tests/jwks/jwks.go (2)
router-tests/jwks/crypto.go (1)
  • Crypto (17-23)
router-tests/cmd/jwks-server/main.go (1)
  • NewServerWithCrypto (214-252)
🔇 Additional comments (9)
router-tests/jwks/crypto.go (1)

17-23: LGTM! Clean interface extension.

The new MarshalJWKWithUse method is properly added to the interface, and existing implementations correctly delegate MarshalJWK() to the new method with the default jwkset.UseSig value, maintaining backward compatibility.

router-tests/cmd/jwks-server/main.go (1)

52-56: LGTM! Import reorganization only.

No functional changes; imports were simply reordered for consistency.

router/core/access_controller.go (1)

51-53: LGTM! Good error composition pattern.

Using errors.Join(err, ErrUnauthorized) preserves the underlying authentication error for debugging and logging while ensuring errors.Is(err, ErrUnauthorized) still returns true. This enables the sanitization logic in graphql_prehandler.go and websocket.go to mask internal error details from clients.

router/pkg/config/testdata/config_full.json (1)

489-542: LGTM! Test data updated to reflect new schema.

The AllowedUse field is correctly added to each JWKS entry with null values, which will exercise default behavior during testing.

router/core/graphql_prehandler.go (1)

1149-1158: LGTM! Proper error sanitization for security.

The implementation correctly sanitizes error details in the GraphQL response while preserving the full error for logging (line 1143), request context (line 1142), and observability spans (lines 1146-1147). This prevents leaking sensitive authentication failure details to clients.

router/pkg/config/config.go (1)

486-501: LGTM! AllowedUse field added correctly.

The AllowedUse []string field is properly added to JWKSConfiguration. Based on learnings, validation for JWKS configuration fields is handled at the JSON schema level rather than runtime validation in Go code.

router/core/supervisor_instance.go (1)

290-309: LGTM! Configuration propagation is correct.

The AllowedUse field is properly propagated from the JWKS configuration to the authentication.JWKSConfig, consistent with how other JWKS settings are passed through.

router-tests/authentication_test.go (1)

4019-4134: LGTM! Well-structured test for the new "use" customization feature.

The test properly validates both the default behavior (rejecting tokens when JWK has empty "use" field) and the customized behavior (allowing empty "use" when explicitly configured). The helper functions follow existing patterns and make the test readable.

router-tests/jwks/jwks.go (1)

136-215: LGTM! Clean refactoring to options-based initialization.

The introduction of the options pattern is idiomatic and maintains backward compatibility. Key improvements:

  1. Backward compatibility: NewServerWithCrypto still works via delegation
  2. Flexibility: Options allow customizing "use" parameter without breaking existing code
  3. Good defaults: Default use is UseSig, preserving previous behavior
  4. Validation: Checks that at least one provider is specified

The refactoring properly supports the new JWKS "use" customization feature while keeping the API clean.

alepane21 and others added 3 commits December 24, 2025 18:26
…401-on-router-with-valid-token' into ale/eng-8704-jwt-authentication-401-on-router-with-valid-token
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
router/pkg/authentication/jwks_token_decoder.go (1)

156-160: Add USE validation for secret-based JWKS to respect AllowedUse configuration.

Line 159 hardcodes jwkset.UseSig in the JWK metadata for secret-based JWKS, but the configured AllowedUse is never validated during token verification. Unlike HTTP-based JWKS (which uses keyfunc's UseWhitelist), secret-based JWKS stores allowedUse in the keyFuncEntry but the custom keyFuncWrapper (lines 194-240) never checks it against the JWK's declared USE. This means a user configuring AllowedUse to exclude "sig" will have no effect for secret-based keys.

Either:

  1. Validate entry.allowedUse in the keyFuncWrapper similarly to how entry.allowedAlgorithms is validated (lines 212-229), or
  2. Document that secret-based JWKS always uses "sig" and users must include "sig" in AllowedUse.
🤖 Fix all issues with AI agents
In @router/pkg/authentication/jwks_token_decoder.go:
- Around line 186-190: The secret-based branch building keyFuncEntry is missing
the allowedAlgorithms field, causing algorithm validation to skip for those
entries; update the append call that creates keyFuncEntry (the one passing jwks,
aud: audiencesMap[key], allowedUse: c.AllowedUse) to also set allowedAlgorithms:
c.AllowedAlgorithms (or the appropriate source used by the URL-based path) so
keyFuncWrapper can correctly validate entry.allowedAlgorithms during token
verification.
- Around line 255-265: toJwksetUseType currently casts strings to jwkset.USE
without validation; change it to validate each allowedUse entry (e.g., for each
u do use := jwkset.USE(u) and call use.IANARegistered() or equivalent) and
return an error if any value is invalid so initialization fails fast; update the
signature to return ([]jwkset.USE, error) and propagate that error to the
decoder initialization call sites so the decoder fails on bad configuration
rather than during token verification.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f8dc80 and 0d036cf.

📒 Files selected for processing (1)
  • router/pkg/authentication/jwks_token_decoder.go
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/config/config.schema.json:1637-1644
Timestamp: 2025-07-21T15:06:36.664Z
Learning: In the Cosmo router project, when extending JSON schema validation for security-sensitive fields like JWKS secrets, backwards compatibility is maintained by implementing warnings in the Go code rather than hard validation constraints in the schema. This allows existing configurations to continue working while alerting users to potential security issues.
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections. The validation store maintains its own internal supported algorithms map that gets returned regardless of input parameters.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2025-07-21T14:46:34.879Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2026-01-06T12:37:21.521Z
Learnt from: asoorm
Repo: wundergraph/cosmo PR: 2379
File: router/pkg/connectrpc/operation_registry_test.go:381-399
Timestamp: 2026-01-06T12:37:21.521Z
Learning: In Go code (Go 1.25+), prefer using sync.WaitGroup.Go(func()) to run a function in a new goroutine, letting the WaitGroup manage Add/Done automatically. Avoid manual wg.Add(1) followed by go func() { defer wg.Done(); ... }() patterns. Apply this guidance across all Go files in the wundergraph/cosmo repository where concurrency is used.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: build-router
  • GitHub Check: Analyze (go)
  • GitHub Check: integration_test (./events)
  • GitHub Check: image_scan
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_test
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
🔇 Additional comments (3)
router/pkg/authentication/jwks_token_decoder.go (3)

48-48: LGTM: AllowedUse field added to configuration.

The new field follows the existing pattern and enables customization of JWK "use" values as intended.


267-284: LGTM: UseWhitelist parameter properly propagated.

The signature change and implementation correctly pass the useWhitelist to the keyfunc.Options, enabling JWK "use" filtering at the library level.


77-77: Remove the unused allowedUse field from keyFuncEntry.

The allowedUse field is assigned in the struct (lines 135, 189) but never accessed. The actual use case is handled at initialization time (lines 127, 182) where toJwksetUseType(c.AllowedUse) converts the config value and passes it directly to createKeyFunc. The stored field in keyFuncEntry is dead code and should be removed.

⛔ Skipped due to learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
router/pkg/authentication/jwks_token_decoder.go (2)

164-164: Potential mismatch between hardcoded USE and AllowedUse filter.

Line 164 hardcodes USE: jwkset.UseSig when creating a JWK from a secret, but lines 187-190 allow users to configure custom AllowedUse values. If a user sets AllowedUse to anything other than ["sig"] (e.g., ["enc"]), the UseWhitelist filter will reject the created JWK since its metadata has use: "sig".

This creates a configuration that can never succeed for secret-based JWKs with non-sig use values.

Consider one of these approaches:

  1. Use the first value from AllowedUse to set the JWK's USE metadata (with validation that only one value is provided for secret-based configs)
  2. Disallow AllowedUse customization for secret-based JWKs and document this limitation
  3. Remove the UseWhitelist filtering for secret-based paths since the USE is internally controlled

Also applies to: 187-201


282-298: Remove UseWhitelist field assignment from keyfunc.Options — field does not exist in v3.6.2.

Line 291 attempts to assign useWhitelist to keyfuncOptions.UseWhitelist, but the keyfunc.Options struct does not have a UseWhitelist field in v3.6.2. The JWK "use" whitelist behavior in keyfunc v3.6.2 is controlled via JWKUse and JWKUseNoWhitelist constants instead. Either remove the useWhitelist parameter and assignment, or update the implementation to use the correct keyfunc API for configuring JWK "use" whitelist behavior.

🧹 Nitpick comments (1)
router/pkg/authentication/jwks_token_decoder.go (1)

77-77: Consider whether this field is needed.

The allowedUse field is stored in each keyFuncEntry (lines 140, 200) but never referenced in the validation logic (lines 205-251). If it's intended for future use or debugging, consider adding a comment to clarify its purpose.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d036cf and 6784b60.

📒 Files selected for processing (1)
  • router/pkg/authentication/jwks_token_decoder.go
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/config/config.schema.json:1637-1644
Timestamp: 2025-07-21T15:06:36.664Z
Learning: In the Cosmo router project, when extending JSON schema validation for security-sensitive fields like JWKS secrets, backwards compatibility is maintained by implementing warnings in the Go code rather than hard validation constraints in the schema. This allows existing configurations to continue working while alerting users to potential security issues.
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2025-09-17T18:13:31.021Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2224
File: router/pkg/authentication/jwks_token_decoder.go:176-199
Timestamp: 2025-09-17T18:13:31.021Z
Learning: In router/pkg/authentication/jwks_token_decoder.go, when AllowEmptyAlgorithm is true, the allowedAlgorithms slice is populated by getSupportedAlgorithms() from validation_store.go, ensuring it's never empty and preventing unintended token rejections. The validation store maintains its own internal supported algorithms map that gets returned regardless of input parameters.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2025-07-21T14:46:34.879Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2025-07-21T15:06:36.664Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/config/config.schema.json:1637-1644
Timestamp: 2025-07-21T15:06:36.664Z
Learning: In the Cosmo router project, when extending JSON schema validation for security-sensitive fields like JWKS secrets, backwards compatibility is maintained by implementing warnings in the Go code rather than hard validation constraints in the schema. This allows existing configurations to continue working while alerting users to potential security issues.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
📚 Learning: 2026-01-06T12:37:21.521Z
Learnt from: asoorm
Repo: wundergraph/cosmo PR: 2379
File: router/pkg/connectrpc/operation_registry_test.go:381-399
Timestamp: 2026-01-06T12:37:21.521Z
Learning: In Go code (Go 1.25+), prefer using sync.WaitGroup.Go(func()) to run a function in a new goroutine, letting the WaitGroup manage Add/Done automatically. Avoid manual wg.Add(1) followed by go func() { defer wg.Done(); ... }() patterns. Apply this guidance across all Go files in the wundergraph/cosmo repository where concurrency is used.

Applied to files:

  • router/pkg/authentication/jwks_token_decoder.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: build-router
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: image_scan
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
router/pkg/authentication/jwks_token_decoder.go (3)

48-48: LGTM: Field addition follows project patterns.

The AllowedUse field is appropriately typed and positioned. Consistent with project learnings, field validation is handled at the JSON schema level rather than runtime Go validation.


127-141: LGTM: Proper error handling and validation flow.

The URL-based configuration path correctly:

  • Validates AllowedUse values via toJwksetUseType with descriptive error context
  • Propagates the useWhitelist to key function creation
  • Stores the configuration for reference

266-280: LGTM: Proper validation with backward-compatible defaults.

The function correctly:

  • Defaults to UseSig when AllowedUse is empty, preserving backward compatibility
  • Validates each use value via IANARegistered() to prevent invalid configurations
  • Provides clear error messages for unsupported values

Copy link
Contributor

@dkorittki dkorittki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@alepane21 alepane21 merged commit c8f945d into main Jan 12, 2026
30 checks passed
@alepane21 alepane21 deleted the ale/eng-8704-jwt-authentication-401-on-router-with-valid-token branch January 12, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants