-
Notifications
You must be signed in to change notification settings - Fork 9
Minor cleanup for token handling #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe changes introduce a new Changes
Sequence Diagram(s)sequenceDiagram
participant Controller as Reconciler (Client/Exporter)
participant Resource as Client/Exporter
participant Signer as OIDC Signer
Controller->>Resource: Call Username(prefix)
Resource-->>Controller: Return constructed username
Controller->>Signer: Call UnsafeValidate(token)
Signer-->>Controller: Return validation result
Controller->>Controller: Process authorization decision
sequenceDiagram
participant Requestor as Token Requestor
participant Signer as OIDC Signer
Requestor->>Signer: Token(username)
alt Valid prefix
Signer-->>Requestor: Return generated token
else
Signer-->>Requestor: Return tokenPlaceholder
end
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
🔭 Outside diff range comments (2)
internal/oidc/op.go (2)
95-109:⚠️ Potential issueSecurity concern: Token validation bypass.
The
UnsafeValidatemethod allows bypassing JWT validation for placeholder tokens. This could be exploited if the placeholder token is exposed or guessed.Consider:
- Adding logging for placeholder token usage
- Implementing rate limiting
- Adding environment-specific validation
func (k *Signer) UnsafeValidate(token string) error { + // TODO: Add rate limiting + // TODO: Add logging if token == tokenPlaceholder { + // TODO: Add environment-specific validation return nil }
111-124: 💡 Verification agent
⚠️ Potential issue🧩 Analysis chain
Review token expiration policy.
The token expiration is set to 365 days with a FIXME comment about key rotation. This extended duration increases the security risk if tokens are compromised.
🌐 Web query:
What is the recommended JWT token expiration time for access tokens?💡 Result:
The recommended expiration time for JWT access tokens is minutes to a maximum of 24 hours, with shorter durations preferred for enhanced security[2][3][4]. Here's a detailed breakdown:
Key Recommendations
- Best practice: Limit validity to minutes or hours rather than days/months[4]
- Maximum threshold: 24 hours (configurable via access policies)[2][3]
- Default configurations:
- Okta: 5 minutes minimum, 24 hours maximum[2]
- Auth0: 24 hours default (adjustable)[3]
Security Considerations
Shorter expiration times help:
- Reduce attack surface if tokens are compromised
- Minimize impact of potential token leaks
- Avoid long-term dependency on static credentials[4]
For sensitive applications, many security experts recommend:
- 30 minutes for standard web apps
- 5-15 minutes for high-security systems
- Even shorter for financial transactions or healthcare systems
To implement securely:
# Example Python configuration for 1-hour expiration from datetime import datetime, timedelta expiration = datetime.utcnow() + timedelta(hours=1) payload = { "sub": "user123", "exp": expiration, # other claims... }Always validate the
expclaim server-side and use refresh tokens for longer sessions[4]. For systems requiring granular control, implement token revocation mechanisms alongside short expirations.Citations:
- 1: https://devforum.zoom.us/t/how-can-i-know-when-my-jwt-token-will-expire/83881
- 2: https://support.okta.com/help/s/article/What-is-the-lifetime-of-the-JWT-tokens?language=en_US
- 3: https://community.auth0.com/t/how-jwt-expiration-works/93049
- 4: https://curity.io/resources/learn/jwt-best-practices/
- 5: https://learn.microsoft.com/en-us/answers/questions/845791/jwt-token-expiration-and-authorization
Action Needed: Update Token Expiration Duration
The JWT token issued in
internal/oidc/op.go(lines 111–124) currently has an expiration set to 365 days. Industry best practices recommend a much shorter lifetime—typically in the range of minutes to a maximum of 24 hours (with many systems using around 1 hour). This extended duration can significantly increase the security risk if a token is compromised.
Update Suggestion: Change the token expiration from:
ExpiresAt: jwt.NewNumericDate(time.Now().Add(365 * 24 * time.Hour)), // FIXME: rotate keys on expirationto a shorter duration, for example:
ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Hour)), // adjust token lifetime as neededAdditional Consideration: Review the key rotation mechanism (as noted by the FIXME comment) to ensure that token revocation and refresh processes are robust and in line with the revised, shorter token validity period.
🧹 Nitpick comments (4)
api/v1alpha1/client_helpers.go (1)
5-11: Consider clarifying usage expectations and edge cases.The logic is straightforward, but it may be helpful to add a docstring describing how the custom username interacts with the prefix. Consider scenarios where the prefix is empty or the user-supplied username is missing.
api/v1alpha1/exporter_helpers.go (1)
5-11: Refactor to avoid duplicating similar code inClientandExporter.This method closely mirrors
Client’sUsernamefunction. For cleaner code maintenance, consider extracting a shared helper function that accepts a string like"client"or"exporter"as an additional argument.internal/controller/exporter_controller.go (2)
109-109: Consider adding monitoring for token validation failures.The switch to
UnsafeValidateshould be monitored to detect potential security issues.Consider adding metrics or structured logging:
-if !ok || r.Signer.UnsafeValidate(string(token)) != nil { +if !ok { + logger.Info("token field missing in secret") + return false, r.Delete(ctx, secret) +} +if err := r.Signer.UnsafeValidate(string(token)); err != nil { + logger.Info("token validation failed", "error", err) + return false, r.Delete(ctx, secret) +}
194-199: Consider adding retry logic for token generation.Token generation could fail due to temporary issues. Consider implementing retry logic with backoff.
func (r *ExporterReconciler) secretForExporter(exporter *jumpstarterdevv1alpha1.Exporter) (*corev1.Secret, error) { + var token string + var err error + for retries := 0; retries < 3; retries++ { + token, err = r.Signer.Token(exporter.Username(r.Signer.Prefix())) + if err == nil { + break + } + time.Sleep(time.Duration(retries+1) * time.Second) + } if err != nil { return nil, err }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
api/v1alpha1/client_helpers.go(1 hunks)api/v1alpha1/exporter_helpers.go(1 hunks)internal/authorization/basic.go(3 hunks)internal/controller/client_controller.go(2 hunks)internal/controller/exporter_controller.go(2 hunks)internal/oidc/op.go(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: e2e-tests
🔇 Additional comments (4)
internal/controller/client_controller.go (2)
155-155: Good simplification by directly callingUsernameon the client instance.Removing the extra dependency on the authorization package streamlines the code. This direct call also makes the code more self-explanatory by leveraging the newly introduced
Usernamehelper.
96-96:❓ Verification inconclusive
Confirm the security implications of using
UnsafeValidate.Replacing a signature verification call with an "unsafe" validation method may introduce security risks. If this change is intentional, consider documenting the rationale or adding clarifying comments to reduce confusion. Otherwise, use a more secure validation approach to avoid inadvertently relaxing security.
Below is a script to locate additional usages of
UnsafeValidateand confirm whether they are all intended:
🏁 Script executed:
#!/bin/bash # This script searches for all occurrences of UnsafeValidate across the codebase including context lines rg -A5 "UnsafeValidate("Length of output: 107
Security Confirmation Required: Validate
UnsafeValidateUsageThe code at
internal/controller/client_controller.go:96callsr.Signer.UnsafeValidate(string(token)), bypassing standard signature verification. This approach could introduce security risks if the use ofUnsafeValidateisn’t intentional and thoroughly verified.
- Action Items:
- Confirm that the use of
UnsafeValidateis deliberate and its implications are fully understood.- Document the rationale with inline comments if this insecure validation is necessary.
- If available, consider switching to a more secure validation method to maintain robust security practices.
Note: The initial shell script to locate usages of
UnsafeValidatefailed because the regex pattern wasn’t escaped properly. Please run the corrected command manually for further verification:rg -A5 "UnsafeValidate\("internal/authorization/basic.go (2)
16-18: Good abstraction using the Authorizer interface.Returning the interface instead of the concrete type improves flexibility and follows the interface segregation principle.
33-37: Consistent username validation pattern.The code now uses a consistent pattern for username validation across both Exporter and Client cases.
Also applies to: 46-50
Summary by CodeRabbit
New Features
Refactor