Skip to content

Conversation

@WhammyLeaf
Copy link

@WhammyLeaf WhammyLeaf commented Nov 24, 2025

This PR adds support a couple of new config variables, which are useful to have available in an enterprise setting with a more complex azure setup. They are:

  • Scopes, which defaults to the currently hardcoded values when not set
  • TokenValidatonFuncs, which is a list custom validation functions to apply to the raw accces
  • SkipIssuerCheck, SkipExpiryCheck, SkipAudienceCheck, which are booleans that, when true, bypass the corresponding checks on the access token

I still have not added any documentation, but I can do that once I get the go-ahead.

Summary by CodeRabbit

  • New Features

    • Make OAuth2/OIDC scopes configurable via environment and builder with sensible defaults.
    • Add flags to skip issuer, audience, and expiry checks via environment and builder.
    • Allow registering custom token validation callbacks.
  • Bug Fixes

    • Token validation and discovery now consistently respect configured scopes and skip flags across flows.

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

@coderabbitai
Copy link

coderabbitai bot commented Nov 24, 2025

Walkthrough

Adds configurable OIDC/OAuth2 options: Scopes, three Skip* boolean flags, and TokenValidationFuncs; wires them through Config builder/FromEnv, provider initialization, OIDC validator execution, OAuth2 handler scopes, and discovery metadata; adds parseBoolEnv helper and related imports.

Changes

Cohort / File(s) Summary
Configuration layer
config.go
Added Scopes []string, SkipIssuerCheck bool, SkipAudienceCheck bool, SkipExpiryCheck bool, and TokenValidationFuncs []func(claims jwt.MapClaims) error to Config; added builder methods WithScopes, WithSkipIssuerCheck, WithSkipAudienceCheck, WithSkipExpiryCheck; added parseBoolEnv(key string, defaultVal bool) bool; wired env vars OIDC_SCOPES, OIDC_SKIP_AUDIENCE_CHECK, OIDC_SKIP_ISSUER_CHECK, OIDC_SKIP_EXPIRY_CHECK into FromEnv; imports updated (strconv, strings, github.com/golang-jwt/jwt/v5).
Provider/validator layer
provider/provider.go
Added same Skip* flags and TokenValidatorFuncs to provider Config and OIDCValidator; initializer now passes cfg.SkipIssuerCheck / SkipAudienceCheck / SkipExpiryCheck into verifier and assigns TokenValidatorFuncs; OIDC and HMAC validation paths execute configured token validation callbacks after core checks.
OAuth2 handler
handlers.go
Added Scopes []string to OAuth2Config; handler and NewOAuth2ConfigFromConfig use cfg.Scopes with fallback to ["openid","profile","email"] instead of hard-coded scopes.
Discovery metadata
metadata.go
Discovery metadata scopes_supported now uses dynamic h.config.Scopes (proxy branch retains fixed scopes).

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Conf as ConfigBuilder / FromEnv
    participant Prov as Provider (createProvider)
    participant Val as OIDCValidator
    participant TF as TokenValidationFuncs

    App->>Conf: build config (WithScopes / FromEnv / WithSkipX / TokenValidationFuncs)
    note right of Conf `#E8F6FF`: Config includes Scopes, Skip* flags,\nand TokenValidationFuncs
    Conf->>Prov: createProvider(cfg)
    Prov->>Val: init validator with Skip* flags\nand TokenValidationFuncs
    Val->>Val: perform core validations (issuer / aud / expiry)
    alt core checks pass or are skipped
        Val->>TF: iterate TokenValidationFuncs(claims)
        TF-->>Val: error / nil
    end
    Val-->>Prov: validation result
    Prov-->>App: provider uses configured scopes & validator
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review focus:
    • Env parsing for OIDC_SCOPES and boolean flags (parseBoolEnv) and fallback semantics.
    • Nil-safety and propagation of TokenValidationFuncs through Config → Provider → OIDCValidator.
    • Correct mapping of Skip* flags into verifier configuration and ensuring intended checks are bypassed.

Possibly related issues

  • [Feat]: Add more config options #10 — Adds the same configuration fields and env/builder wiring (scopes, skip checks, token validation funcs); aligns with this PR's objectives.

Poem

🐰 I hop through code with eager paws,
Scopes tucked in my tiny laws,
Flags that skip and funcs that pry,
I nibble bugs and let checks fly.
A carrot cheer for builds gone high. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Add more config variables' is vague and generic, using non-descriptive language that doesn't convey specific information about which config variables are added or their purpose. Consider a more specific title such as 'Add token validation and OIDC configuration options' or 'Support custom scopes and token validation skips' to better describe the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14f9009 and 65f35e5.

📒 Files selected for processing (2)
  • config.go (4 hunks)
  • provider/provider.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
config.go (2)
provider/provider.go (1)
  • Logger (24-29)
logger.go (1)
  • Logger (22-27)
🔇 Additional comments (4)
provider/provider.go (2)

33-40: LGTM with security caveat.

The new configuration fields are correctly defined. However, these flags bypass critical security validations.

Ensure these flags are:

  1. Documented with clear security warnings
  2. Used only in development/testing environments
  3. Never enabled in production

Consider adding runtime warnings when these checks are disabled.


209-211: LGTM!

The validator configuration correctly maps the new config flags to the OIDC verifier settings, replacing the previously hardcoded false values.

config.go (2)

34-38: LGTM!

The configuration fields are correctly defined with appropriate documentation.


318-320: Missing test coverage for security bypass flags.

Verification confirms no tests exist for the new skip flags. Critical test coverage gaps:

  • Environment variable parsing tests (OIDC_SKIP_AUDIENCE_CHECK, OIDC_SKIP_ISSUER_CHECK, OIDC_SKIP_EXPIRY_CHECK)
  • Validation that flags default to false (secure-by-default)
  • Independent flag behavior verification
  • Combined flag scenarios

Add tests covering all above cases before merging, particularly to ensure security defaults are maintained.

@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch from bd04072 to 8d50963 Compare November 24, 2025 14:44
@WhammyLeaf WhammyLeaf changed the title Add more custom config vars Support skipping OIDC validation checks Nov 24, 2025
@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch 2 times, most recently from 31b7df3 to 5fbe515 Compare November 24, 2025 15:23
Copy link

@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

🧹 Nitpick comments (2)
config.go (2)

36-39: LGTM: Skip validation flags added correctly.

The three boolean fields are well-named and properly integrated into the Config struct. They default to false (validation enabled), which is the safe default.

Optional: Consider adding doc comments to each field explaining the security implications of skipping these validation checks, especially for users who may not fully understand OIDC security requirements.


327-338: LGTM: Robust boolean parsing with safe defaults.

The parseBoolEnv helper correctly uses strconv.ParseBool to handle standard boolean representations and safely falls back to the default value on parse errors or empty values. This fail-safe approach ensures validation remains enabled by default.

Optional: Consider logging parse errors to aid debugging when users provide invalid boolean values (e.g., "yes" instead of "true"). However, the current silent fallback is safe and acceptable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd04072 and 5fbe515.

📒 Files selected for processing (2)
  • config.go (5 hunks)
  • provider/provider.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • provider/provider.go
🧰 Additional context used
🧬 Code graph analysis (1)
config.go (2)
provider/provider.go (1)
  • Logger (24-29)
logger.go (1)
  • Logger (22-27)
🔇 Additional comments (4)
config.go (4)

5-5: LGTM: Import added for boolean parsing.

The strconv import is necessary for the parseBoolEnv helper and is correctly placed.


127-135: LGTM: Skip flags correctly propagated to provider config.

The mapping from Config to provider.Config is correct, including the previously identified copy-paste error on line 135 which has been properly fixed (now correctly maps SkipExpiryCheck to cfg.SkipExpiryCheck).


235-251: LGTM: Builder methods follow the pattern correctly.

The three new builder methods are properly implemented following the fluent builder pattern. Documentation comments are correct and consistent (previous typos have been fixed).


319-321: LGTM: Environment variable parsing implemented correctly.

The skip flags are properly initialized from environment variables using the parseBoolEnv helper, which correctly handles boolean values. Safe defaults (false = validation enabled) are used, and the environment variable names follow clear naming conventions.

@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch from 5fbe515 to 4d5a1f7 Compare November 27, 2025 09:09
Copy link

@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

Caution

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

⚠️ Outside diff range comments (1)
provider/provider.go (1)

264-267: Explicit audience validation runs even when SkipAudienceCheck is true.

When cfg.SkipAudienceCheck is set to true, the go-oidc library skips its audience check (via SkipClientIDCheck at line 211), but validateAudience() at line 265 still runs unconditionally. This makes the skip flag ineffective.

-	// Validate audience claim for security (explicit check)
-	if err := v.validateAudience(rawClaims); err != nil {
-		return nil, fmt.Errorf("audience validation failed: %w", err)
-	}
+	// Validate audience claim for security (explicit check) unless skipped
+	if !v.skipAudienceCheck {
+		if err := v.validateAudience(rawClaims); err != nil {
+			return nil, fmt.Errorf("audience validation failed: %w", err)
+		}
+	}

You'll need to store cfg.SkipAudienceCheck in OIDCValidator during initialization.

🧹 Nitpick comments (4)
metadata.go (1)

245-245: Inconsistent scopes in metadata endpoints.

HandleOIDCDiscovery now uses dynamic h.config.Scopes, but GetAuthorizationServerMetadata() (lines 285 and 317) still uses hardcoded []string{"openid", "profile", "email"}. This inconsistency could confuse clients depending on which metadata endpoint they query.

Consider updating GetAuthorizationServerMetadata() to also use h.config.Scopes for consistency:

 // In native mode (line 285):
-	"scopes_supported":                      []string{"openid", "profile", "email"},
+	"scopes_supported":                      h.config.Scopes,

 // In proxy mode (line 317):
-	"scopes_supported":                      []string{"openid", "profile", "email"},
+	"scopes_supported":                      h.config.Scopes,
config.go (2)

234-262: Consider adding builder method for TokenValidationFuncs.

For consistency with the fluent builder pattern, consider adding a WithTokenValidationFuncs method:

// WithTokenValidationFuncs sets custom token validation functions
func (b *ConfigBuilder) WithTokenValidationFuncs(funcs []func(claims jwt.MapClaims) error) *ConfigBuilder {
	b.config.TokenValidationFuncs = funcs
	return b
}

This allows users to configure custom validation functions via the builder API.


38-43: Add security warnings for skip flags.

Skipping issuer, audience, or expiry checks significantly weakens token security and should only be used in development/testing. Consider logging warnings in Validate() or during initialization when these flags are enabled:

// In Validate() or SetupOAuth():
if c.SkipIssuerCheck {
    logger.Warn("SECURITY: Issuer check disabled - not recommended for production")
}
if c.SkipAudienceCheck {
    logger.Warn("SECURITY: Audience check disabled - not recommended for production")
}
if c.SkipExpiryCheck {
    logger.Warn("SECURITY: Expiry check disabled - tokens may be accepted after expiration")
}
provider/provider.go (1)

66-82: HMACValidator doesn't respect skip flags.

The new skip flags (SkipIssuerCheck, SkipAudienceCheck, SkipExpiryCheck) and TokenValidatorFuncs are only implemented for OIDCValidator. HMACValidator still performs audience validation unconditionally (line 117) and expiry validation (line 112 via validateTokenClaims).

For API consistency, consider implementing these flags for HMACValidator as well, or document that these flags only apply to OIDC providers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fbe515 and 4d5a1f7.

📒 Files selected for processing (4)
  • config.go (7 hunks)
  • handlers.go (4 hunks)
  • metadata.go (1 hunks)
  • provider/provider.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
config.go (2)
provider/provider.go (1)
  • Logger (24-29)
logger.go (1)
  • Logger (22-27)
🔇 Additional comments (2)
handlers.go (1)

181-195: LGTM!

The scopes configuration with sensible defaults is well implemented. The fallback to ["openid", "profile", "email"] when no scopes are provided ensures backward compatibility.

provider/provider.go (1)

269-275: LGTM!

The custom token validation function execution is correctly implemented. Ranging over a nil slice is safe in Go, so no nil check is needed.

@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch from 4d5a1f7 to 8beec21 Compare November 27, 2025 09:12
Copy link

@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

♻️ Duplicate comments (1)
config.go (1)

321-321: Empty OIDC_SCOPES produces [""] instead of empty slice.

When OIDC_SCOPES is unset or empty, strings.Split("", " ") returns [""] (a slice with one empty string), not an empty slice. This bypasses the default scopes fallback in NewOAuth2ConfigFromConfig (which checks len(scopes) == 0).

Use strings.Fields which handles empty strings correctly:

-	scopes := strings.Split(getEnv("OIDC_SCOPES", ""), " ")
+	scopesEnv := getEnv("OIDC_SCOPES", "")
+	var scopes []string
+	if scopesEnv != "" {
+		scopes = strings.Fields(scopesEnv)
+	}

Alternatively, using strings.Fields directly works because it returns nil for empty/whitespace-only input:

-	scopes := strings.Split(getEnv("OIDC_SCOPES", ""), " ")
+	scopes := strings.Fields(getEnv("OIDC_SCOPES", ""))
🧹 Nitpick comments (1)
metadata.go (1)

271-322: Inconsistent scopes handling between discovery endpoints.

HandleOIDCDiscovery (line 245) now uses dynamic h.config.Scopes, while GetAuthorizationServerMetadata (lines 285 and 317) still uses hardcoded []string{"openid", "profile", "email"}.

This inconsistency could confuse clients querying different metadata endpoints. Consider using h.config.Scopes consistently across both methods.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d5a1f7 and 8beec21.

📒 Files selected for processing (4)
  • config.go (7 hunks)
  • handlers.go (4 hunks)
  • metadata.go (1 hunks)
  • provider/provider.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • provider/provider.go
🧰 Additional context used
🧬 Code graph analysis (1)
config.go (2)
provider/provider.go (1)
  • Logger (24-29)
logger.go (1)
  • Logger (22-27)
🔇 Additional comments (8)
config.go (5)

3-10: LGTM on imports.

The new imports (strconv, strings, and jwt/v5) are correctly added to support the new boolean parsing, scope handling, and token validation functions.


24-44: LGTM on new configuration fields.

The new Scopes, Skip*Check, and TokenValidationFuncs fields are well-structured and provide the flexibility needed for customizable OIDC validation.


131-141: LGTM on provider config mapping.

The field mappings are now correct. The previously reported copy-paste error (where SkipExpiryCheck was incorrectly mapped to cfg.SkipAudienceCheck) has been fixed.


234-262: LGTM on builder methods.

The new fluent builder methods follow the established pattern and the documentation comments have been corrected.


339-351: LGTM on parseBoolEnv helper.

The implementation correctly uses strconv.ParseBool to handle standard boolean values (true, false, 1, 0, t, f, etc.) and provides sensible defaults for empty or invalid values.

handlers.go (3)

49-49: LGTM on new Scopes field.

The new Scopes field in OAuth2Config properly supports dynamic scope configuration.


96-101: LGTM on OAuth2 config initialization.

The scopes are correctly passed to the underlying oauth2.Config.


181-195: LGTM on scopes initialization with default fallback.

The fallback logic is correct: if no scopes are configured, default to ["openid", "profile", "email"]. This will work correctly once the strings.Split issue in config.go line 321 is fixed (empty env should yield an empty slice, not [""]).

@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch from 20bc22e to 8a7df45 Compare November 27, 2025 09:27
Signed-off-by: Christian Troelsen <christian.troelsen@tryg.dk>

fix suggestions by coderabbit

Signed-off-by: Christian Troelsen <christian.troelsen@tryg.dk>
@WhammyLeaf WhammyLeaf force-pushed the add-more-custom-config-vars branch from 8a7df45 to 4be258d Compare November 27, 2025 09:28
@WhammyLeaf WhammyLeaf changed the title Support skipping OIDC validation checks Add more config variables Nov 27, 2025
@WhammyLeaf
Copy link
Author

@tuannvm Could be nice if you could have a look at this 😄

Copy link

@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: 3

Caution

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

⚠️ Outside diff range comments (1)
provider/provider.go (1)

265-267: Explicit audience validation doesn't respect SkipAudienceCheck flag.

When SkipAudienceCheck is true (line 211 sets SkipClientIDCheck: cfg.SkipAudienceCheck), the OIDC verifier skips audience validation. However, the explicit validateAudience call on line 265 always runs, regardless of the flag. This creates inconsistent behavior where the audience check is only partially skipped.

Apply this diff to conditionally skip the explicit audience check:

 	if err := idToken.Claims(&rawClaims); err != nil {
 		return nil, fmt.Errorf("failed to extract raw claims: %w", err)
 	}
 
-	// Validate audience claim for security (explicit check)
-	if err := v.validateAudience(rawClaims); err != nil {
-		return nil, fmt.Errorf("audience validation failed: %w", err)
+	// Validate audience claim for security (explicit check) if not skipped
+	if v.audience != "" {
+		if err := v.validateAudience(rawClaims); err != nil {
+			return nil, fmt.Errorf("audience validation failed: %w", err)
+		}
 	}

Note: This assumes that when SkipAudienceCheck is true, the audience field should be set to empty string during initialization. If that's not the case, you'll need to store the skip flag in the validator struct or pass it through another mechanism.

🧹 Nitpick comments (2)
provider/provider.go (1)

269-276: Consider adding validation function index to error message.

The error message for failed validation functions could be more informative by including which function failed. This would help with debugging when multiple validation functions are registered.

 	// Run extra validation functions
-	for _, fn := range v.TokenValidatorFuncs {
+	for i, fn := range v.TokenValidatorFuncs {
 		err := fn(rawClaims)
 		if err != nil {
-			return nil, fmt.Errorf("validation function failed with error: %w", err)
+			return nil, fmt.Errorf("validation function %d failed: %w", i, err)
 		}
 	}
config.go (1)

132-141: Consider renaming TokenValidationFuncs for consistency.

There's a naming inconsistency between the two Config structs:

  • oauth.Config.TokenValidationFuncs (line 43 in this file)
  • provider.Config.TokenValidatorFuncs (line 41 in provider/provider.go)

While the mapping on line 140 correctly uses TokenValidatorFuncs, having different names for the same concept can cause confusion. Consider renaming one to match the other for consistency across the codebase.

Suggested approach: Rename TokenValidationFuncs to TokenValidatorFuncs in this file to match the provider package:

-	TokenValidationFuncs []func(claims jwt.MapClaims) error
+	TokenValidatorFuncs []func(claims jwt.MapClaims) error

Then update line 140:

-		TokenValidatorFuncs: cfg.TokenValidationFuncs,
+		TokenValidatorFuncs: cfg.TokenValidatorFuncs,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8beec21 and bdae26e.

📒 Files selected for processing (4)
  • config.go (7 hunks)
  • handlers.go (4 hunks)
  • metadata.go (2 hunks)
  • provider/provider.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • handlers.go
  • metadata.go
🧰 Additional context used
🧬 Code graph analysis (1)
config.go (2)
provider/provider.go (1)
  • Logger (24-29)
logger.go (1)
  • Logger (22-27)
⏰ 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). (1)
  • GitHub Check: code-review
🔇 Additional comments (7)
provider/provider.go (2)

59-63: LGTM!

The OIDCValidator struct properly reflects the new configuration fields. The addition of TokenValidatorFuncs and explicit logger field storage aligns well with the validation flow enhancements.


208-214: Based on the web search results, I can now provide the verification findings:

The skip flags are properly documented and work as documented in go-oidc v3.

The search confirmed:

  • SkipClientIDCheck — exists and skips audience validation; must be true if ClientID is empty
  • SkipExpiryCheck — exists and skips token expiry check (documented for special/testing cases)
  • SkipIssuerCheck — exists and skips issuer verification (with warnings to independently verify)

However, there is one potential edge case worth noting: The go-oidc documentation states that SkipClientIDCheck must be set to true if ClientID is empty, otherwise it should be false. Since the code maps cfg.Audience to the ClientID field, verify that your configuration validates this constraint—specifically, if cfg.Audience is empty, ensure cfg.SkipAudienceCheck is true, or the verifier will fail. Check that this validation exists in your config validation logic.


The skip flags work as expected and are secure when used appropriately. The mapping from cfg.SkipAudienceCheck to SkipClientIDCheck is consistent with go-oidc's design. Ensure your config validation enforces the constraint that when audience is empty, skip-audience-check must be true.

config.go (5)

3-10: LGTM!

The new imports (strconv, strings, jwt/v5) are all properly utilized: strconv for boolean parsing, strings for splitting scopes, and jwt for the MapClaims type in validation functions.


234-262: LGTM!

The new builder methods (WithScopes, WithSkipIssuerCheck, WithSkipAudienceCheck, WithSkipExpiryCheck) correctly follow the fluent API pattern and properly set the corresponding Config fields.


322-326: LGTM!

The scopes parsing correctly handles the empty environment variable case by initializing an empty slice and only splitting when the value is non-empty. This avoids the [""] issue that would bypass default scope fallback logic.


336-339: LGTM!

The FromEnv method correctly integrates the new configuration options. The use of parseBoolEnv with false as the default is appropriate for security-sensitive skip flags, ensuring checks are enabled by default.


345-356: LGTM!

The parseBoolEnv helper properly handles boolean environment variables using strconv.ParseBool, which supports standard formats (true/false, 1/0, t/f, etc.). The fallback to default values for empty or invalid inputs is appropriate.

Audience string
ClientID string
ClientSecret string
Scopes []string
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add documentation for Scopes field.

The Scopes field lacks documentation explaining its purpose and default behavior. Users need to understand what scopes are used when this field is empty.

-	Scopes       []string
+	// Scopes defines the OAuth2 scopes to request during authentication.
+	// When empty, defaults to ["openid", "profile", "email"] for OIDC providers.
+	Scopes       []string
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Scopes []string
// Scopes defines the OAuth2 scopes to request during authentication.
// When empty, defaults to ["openid", "profile", "email"] for OIDC providers.
Scopes []string
🤖 Prompt for AI Agents
In config.go around line 24, the Scopes []string field is undocumented; add a Go
doc comment above the field explaining what Scopes represent (the OAuth/API
permission scopes the application will request), what happens when the slice is
empty (e.g., default scopes are applied or none are requested), and any
examples/default values or precedence rules; keep the comment concise and follow
Go doc style (starts with "Scopes ...").

Comment on lines +39 to +43
// Token validation configuration
SkipIssuerCheck bool
SkipAudienceCheck bool
SkipExpiryCheck bool
TokenValidationFuncs []func(claims jwt.MapClaims) error
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add comprehensive documentation for token validation configuration.

These security-sensitive fields need detailed documentation explaining their purpose, security implications, and proper usage. The section comment "Token validation configuration" is insufficient for fields that can weaken security when misconfigured.

 	// Token validation configuration
+	// 
+	// SkipIssuerCheck bypasses issuer validation in OIDC tokens.
+	// WARNING: Only use in development or when implementing custom issuer validation.
+	// Skipping issuer checks allows tokens from any issuer to be accepted.
 	SkipIssuerCheck      bool
+	
+	// SkipAudienceCheck bypasses audience validation in OIDC tokens.
+	// WARNING: Only use in specific multi-tenant scenarios with custom audience validation.
+	// Skipping audience checks allows tokens intended for other services to be accepted.
 	SkipAudienceCheck    bool
+	
+	// SkipExpiryCheck bypasses expiration validation in OIDC tokens.
+	// WARNING: Only use for testing. Production systems should never accept expired tokens.
 	SkipExpiryCheck      bool
+	
+	// TokenValidationFuncs provides custom validation logic that runs after standard validation.
+	// Each function receives raw token claims and should return an error if validation fails.
+	// This field must be set programmatically (cannot be configured via environment variables).
+	// Use this to implement application-specific validation (e.g., custom claims, role checks).
 	TokenValidationFuncs []func(claims jwt.MapClaims) error
🤖 Prompt for AI Agents
In config.go around lines 39 to 43, the token validation configuration fields
currently have only the brief comment "Token validation configuration"; expand
this into comprehensive field-level documentation: for SkipIssuerCheck,
SkipAudienceCheck, and SkipExpiryCheck describe what each toggle does, the
security risks of enabling it, when (if ever) it may be acceptable to enable,
and recommend alternatives (e.g., validating via configuration-driven expected
issuer/audience values); for TokenValidationFuncs describe the function
signature, when these custom validators are invoked, expected behavior (return
nil on success, error on failure), threading/ordering considerations, and
guidance to avoid bypassing core checks; keep the comments concise but explicit,
and ensure they mention default/secure settings and that disabling checks should
require explicit justification.

Comment on lines +33 to +41
Provider string
Issuer string
Audience string
JWTSecret []byte
Logger Logger
SkipIssuerCheck bool
SkipAudienceCheck bool
SkipExpiryCheck bool
TokenValidatorFuncs []func(claims jwt.MapClaims) error
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add documentation for security-sensitive configuration fields.

The newly added fields (SkipIssuerCheck, SkipAudienceCheck, SkipExpiryCheck, TokenValidatorFuncs) lack documentation explaining their purpose, usage, and security implications. These are security-critical settings that bypass standard OAuth2/OIDC validation checks.

Add documentation comments explaining:

  • What each Skip* flag does
  • When these flags should be used (and when they shouldn't)
  • Security risks of bypassing these checks
  • Example use cases for TokenValidatorFuncs

Example:

// Config holds OAuth configuration (subset needed by provider)
type Config struct {
	Provider            string
	Issuer              string
	Audience            string
	JWTSecret           []byte
	Logger              Logger
	
	// SkipIssuerCheck bypasses issuer validation in OIDC tokens.
	// WARNING: Only use this in development or when implementing custom issuer validation.
	// Skipping issuer checks allows tokens from any issuer to be accepted.
	SkipIssuerCheck     bool
	
	// SkipAudienceCheck bypasses audience validation in OIDC tokens.
	// WARNING: Only use this in specific multi-tenant scenarios with custom audience validation.
	// Skipping audience checks allows tokens intended for other services to be accepted.
	SkipAudienceCheck   bool
	
	// SkipExpiryCheck bypasses expiration validation in OIDC tokens.
	// WARNING: Only use this for testing. Production systems should never accept expired tokens.
	SkipExpiryCheck     bool
	
	// TokenValidatorFuncs provides custom validation logic that runs after standard OIDC validation.
	// Each function receives the raw token claims and should return an error if validation fails.
	// Use this to implement application-specific claim validation (e.g., checking custom claims, roles).
	TokenValidatorFuncs []func(claims jwt.MapClaims) error
}
🤖 Prompt for AI Agents
In provider/provider.go around lines 33 to 41, the new fields SkipIssuerCheck,
SkipAudienceCheck, SkipExpiryCheck and TokenValidatorFuncs lack documentation;
add Go doc comments above each field describing what the flag does, when it may
be used and when it must not (development-only, testing, or very specific
trusted multi-tenant scenarios), and the security risks of bypassing standard
OIDC validations (e.g., accepting tokens from any issuer, tokens intended for
other audiences, or expired tokens). For TokenValidatorFuncs document that these
are post-validation hooks that receive jwt.MapClaims and must return an error on
failure, give a short example use case (custom claim or role checks), and
recommend default behavior (do not set skip flags in production; prefer
TokenValidatorFuncs for application-specific checks). Ensure the comments use
clear WARNING language and appear immediately above each field.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

SkipAudienceCheck flag currently has no effect; see inline.

SkipExpiryCheck: false, // Verify expiration
SkipIssuerCheck: false, // Verify issuer
SkipClientIDCheck: cfg.SkipAudienceCheck,
SkipExpiryCheck: cfg.SkipExpiryCheck,

Choose a reason for hiding this comment

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

⚠️ Logic: SkipAudienceCheck never disables audience validation because ValidateToken still calls validateAudience unconditionally. Please gate that call (or skip it) when the flag is true so the new config option has an effect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants