Skip to content

Conversation

@alexander-applyinnovations
Copy link

@alexander-applyinnovations alexander-applyinnovations commented May 8, 2025

Closes #14250
Based on: #20928
Feature implemented by @wrmedford

This allows for generic JWTs to be used for authentication that are minted outside of Argo. Argo currently mints its own JWTs for auth outside of Dex, and this extends its capabilities to utilize JWTs that originate from Identity Aware Proxies.

Checklist:

  • Either (a) I've created an enhancement proposal and discussed it with the community, (b) this is a bug fix, or (c) this does not need to be in the release notes.
  • The title of the PR states what changed and the related issues number (used for the release note).
  • The title of the PR conforms to the Toolchain Guide
  • I've included "Closes [ISSUE #]" or "Fixes [ISSUE #]" in the description to automatically close the associated issue.
  • I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them.
  • Does this PR require documentation updates?
  • I've updated documentation as required by this PR.
  • I have signed off all my commits as required by DCO
  • I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
  • My build is green (troubleshooting builds).
  • My new feature complies with the feature status guidelines.
  • I have added a brief description of why this PR is necessary and/or what this PR solves.
  • Optional. My organization is added to USERS.md.
  • Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity).

wrmedford and others added 30 commits November 24, 2024 20:07
Signed-off-by: Wes Medford <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
Co-authored-by: Josh Soref <[email protected]>
Signed-off-by: Wes <[email protected]>
Co-authored-by: Josh Soref <[email protected]>
Signed-off-by: Wes <[email protected]>
Signed-off-by: Wes Medford <[email protected]>
@bunnyshell
Copy link

bunnyshell bot commented May 8, 2025

❌ Preview Environment undeployed from Bunnyshell

Available commands (reply to this comment):

  • 🚀 /bns:deploy to deploy the environment

@codecov
Copy link

codecov bot commented May 8, 2025

Codecov Report

Attention: Patch coverage is 55.83596% with 140 lines in your changes missing coverage. Please review.

Project coverage is 60.00%. Comparing base (f0d783b) to head (1445dcc).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
util/session/sessionmanager.go 45.53% 51 Missing and 10 partials ⚠️
util/oidc/provider.go 73.38% 21 Missing and 12 partials ⚠️
util/jwt/jwt.go 45.83% 25 Missing and 1 partial ⚠️
cmd/argocd/commands/project_role.go 0.00% 10 Missing ⚠️
util/settings/settings.go 20.00% 7 Missing and 1 partial ⚠️
server/logout/logout.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #22901      +/-   ##
==========================================
+ Coverage   59.96%   60.00%   +0.04%     
==========================================
  Files         343      343              
  Lines       57848    58053     +205     
==========================================
+ Hits        34686    34837     +151     
- Misses      20375    20428      +53     
- Partials     2787     2788       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alexander-applyinnovations alexander-applyinnovations marked this pull request as ready for review May 8, 2025 01:33
@alexander-applyinnovations alexander-applyinnovations requested review from a team as code owners May 8, 2025 01:33
@alexander-applyinnovations alexander-applyinnovations changed the title feat: Add generic JWT auth feat: Add generic JWT authentication (Alpha) May 8, 2025
@wrmedford
Copy link

Thank you for getting this across the line!

@alexander-applyinnovations
Copy link
Author

@crenshaw-dev I believe this would be a great addition to argo-cd. am very interested to see this PR merged, who would be the right person to review this, I am currently available to address any feedback.

@agaudreault agaudreault added this to the v3.2 milestone Jul 4, 2025
Copy link
Member

@agaudreault agaudreault left a comment

Choose a reason for hiding this comment

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

Adding my review, a lot of comment due to the size of the change, but looks good overall. I still havent reviewed provider.go and provider_test.go files. All other files are reviewed.


## External JWT Authentication Current Status: Alpha (Since v3.0.0)

Argo CD can be configured to verify JSON Web Tokens (JWTs) issued by an external authentication provider. This allows you to integrate Argo CD with existing authentication systems that issue JWTs.
Copy link
Member

Choose a reason for hiding this comment

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

Is this mutually exclusive with having an oidc/dex configuration? If so, the doc should mention that both cannot be configured.

jwkSetURL: "https://auth.example.com/.well-known/jwks.json"
# Optional: How long to cache the JWKS
cacheTTL: "1h"
# Optional: Expected audience for the JWT
Copy link
Member

Choose a reason for hiding this comment

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

To stay in sync with the OIDC configuration, could it be allowedAudiences instead?

Comment on lines +494 to +495
4. Extract the username and email from the specified claims
5. Use these values to identify the user within Argo CD
Copy link
Member

Choose a reason for hiding this comment

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

Multiple features in argo will use the groups claims and user info endpoint. This is possible to be configured using oidc and dex.

Since userInfo is another endpoint, how would that work in this case?

google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a
google.golang.org/grpc v1.72.1
google.golang.org/protobuf v1.36.6
gopkg.in/square/go-jose.v2 v2.6.0
Copy link
Member

Choose a reason for hiding this comment

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

This package is deprecated.

Comment on lines +19 to +22
// If it's *MapClaims (less common but possible), dereference and return.
if mapClaimsPtr, ok := claims.(*jwtgo.MapClaims); ok {
return *mapClaimsPtr, nil
}
Copy link
Member

Choose a reason for hiding this comment

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

What is causing this new behaviour?

Comment on lines +511 to +516
// Attempt to get settings manager from the verifier if possible
// This assumes the TokenVerifier implementation might expose settings
var settingsMgr *settings.SettingsManager
if sm, ok := authn.(*SessionManager); ok {
settingsMgr = sm.settingsMgr
}
Copy link
Member

Choose a reason for hiding this comment

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

Create another method on the interface, or provide another interface param to the middleware to GetToken(r *http.Request) string

prov, provErr := mgr.provider()
if provErr != nil {
// If OIDC/Dex is not configured, but we reached here, the token is invalid
return nil, "", fmt.Errorf("token issuer (%s) is not '%s' and OIDC provider is not available: %w", issuer, SessionManagerClaimsIssuer, provErr)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, "", fmt.Errorf("token issuer (%s) is not '%s' and OIDC provider is not available: %w", issuer, SessionManagerClaimsIssuer, provErr)
return nil, "", fmt.Errorf("failed to get provider for OIDC Validation: %w", provErr)

if errors.As(oidcErr, &tokenExpiredError) {
// Return minimal claims indicating SSO source for expired tokens
// Use issuer variable from above, handle potential error if it wasn't retrieved
issForExpired := ""
Copy link
Member

Choose a reason for hiding this comment

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

default to sso if not found?

Suggested change
issForExpired := ""
issForExpired := "sso"

return nil
}

// Check if JWT config specifies a groups claim
Copy link
Member

Choose a reason for hiding this comment

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

Remove comments

}

// Helper for pointer to bool
func boolPtr(b bool) *bool {
Copy link
Member

Choose a reason for hiding this comment

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

use ptr package


Verify(tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error)

VerifyJWT(tokenString string, argoSettings *settings.ArgoCDSettings) (*jwtgo.Token, error)
Copy link
Member

Choose a reason for hiding this comment

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

Instead of having a new VerifyJWT method on the existing provider interface, shouldn't you have a new implementation of the provider interface for JWT token? or have a new provider totally in something like /util/jwt/provider.go

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.

Configure ArgoCD to accept a JWT token provided in the HTTP header

3 participants