-
Notifications
You must be signed in to change notification settings - Fork 6.5k
fix(server): JWT token checks (#14930) #15004
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
base: master
Are you sure you want to change the base?
Conversation
|
@GeorgiYosifov would you mind adding unit tests? |
fc880c5 to
a61d5ee
Compare
|
Ok, I will add unit tests but I encounter that there is also problem with token revocation when I use "argocd cli". I will continue my work on the bug. |
e3f2c1c to
3af1087
Compare
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
3af1087 to
56fc1e5
Compare
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
|
@crenshaw-dev Can you review the PR at this state, before I add unit tests and test also with dex configuration manually? |
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #15004 +/- ##
==========================================
- Coverage 60.05% 59.97% -0.08%
==========================================
Files 343 343
Lines 57830 57910 +80
==========================================
+ Hits 34727 34733 +6
- Misses 20332 20406 +74
Partials 2771 2771 ☔ View full report in Codecov by Sentry. |
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
|
Unit tests are added, still remains to test it with Dex configured. |
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
|
Hi @andrii-korotkov-verkada, sorry for the late response. Would you proceed with the review and merge this PR? |
andrii-korotkov-verkada
left a comment
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.
Approved, but I don't have permissions to merge
Signed-off-by: GeorgiYosifov <[email protected]>
|
@GeorgiYosifov Let me know when the unit tests are fixed so I can merge |
| assert.ErrorIs(t, err, common.ErrTokenVerification) | ||
| }) | ||
|
|
||
| t.Run("OIDC provider is Dex, TLS is configured", func(t *testing.T) { |
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.
Why removing this unit test?
It seems like the new unint tests are not validating assert.ErrorIs(t, err, common.ErrTokenVerification)
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.
The unit test is shifted below in the same file:
argo-cd/util/session/sessionmanager_test.go
Lines 712 to 744 in 7a4e873
| t.Run("OIDC provider is Dex, TLS is configured", func(t *testing.T) { | |
| config := map[string]string{ | |
| "url": dexTestServer.URL, | |
| "dex.config": `connectors: | |
| - type: github | |
| name: GitHub | |
| config: | |
| clientID: aabbccddeeff00112233 | |
| clientSecret: aabbccddeeff00112233`, | |
| } | |
| // This is not actually used in the test. The test only calls the OIDC test server. But a valid cert/key pair | |
| // must be set to test VerifyToken's behavior when Argo CD is configured with TLS enabled. | |
| secretConfig := map[string][]byte{ | |
| "tls.crt": utiltest.Cert, | |
| "tls.key": utiltest.PrivateKey, | |
| } | |
| settingsMgr := settings.NewSettingsManager(t.Context(), getKubeClientWithConfig(config, secretConfig), "argocd") | |
| mgr := NewSessionManager(settingsMgr, getProjLister(), dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, NewUserStateStorage(nil)) | |
| mgr.verificationDelayNoiseEnabled = false | |
| claims := jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"argo-cd"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))} | |
| claims.Issuer = dexTestServer.URL + "/api/dex" | |
| token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims) | |
| key, err := jwt.ParseRSAPrivateKeyFromPEM(utiltest.PrivateKey) | |
| require.NoError(t, err) | |
| tokenString, err := token.SignedString(key) | |
| require.NoError(t, err) | |
| _, _, err = mgr.VerifyToken(tokenString) | |
| require.NoError(t, err) | |
| }) |
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.
I see that the file already have tests for error: "ErrTokenVerification". I don't mean to add more tests.
| tokenExpDuration := exp.Sub(issuedAt) | ||
| remainingDuration := time.Until(exp) | ||
| remainingDuration := time.Until(exp) | ||
| if remainingDuration > 0 && remainingDuration < autoRegenerateTokenDuration && capability == settings.AccountCapabilityLogin { |
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.
@GeorgiYosifov Can you write a comment in code to clearly explain the behavior for token that has no expiry. The admin token is a valid token even if it has no expiry. Project tokens with no expiry are also valid.
I feel like the parse method should not return an error for the project/admin tokens becasue we generate it without expiration. They are valid tokens that do not expire and do not need to be refreshed.
{
"iss": "argocd",
"sub": "proj:example:my-role",
"nbf": 1746656250,
"iat": 1746656250,
"jti": "1f80b115-566c-4d6b-ae68-cf21cba47d3b"
}Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
|
The old test from: "cmd/argocd/commands/logout_test.go" is removed because the new implementation here: https://github.com/argoproj/argo-cd/blob/e2020559f1984d7b7c844978268368278fa2ff83/cmd/argocd/commands/logout.go |
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
Signed-off-by: GeorgiYosifov <[email protected]>
|
@agaudreault and @crenshaw-dev can this changes be merged as it becomes harder and harder to keep changes up to date just to wait this PR to be merged? Is there something missing in order the PR to be merged? |
|
@GeorgiYosifov I have verified the changes locally by integrating it with the master branch and it works well. |
| } | ||
| req.AddCookie(cookie) | ||
|
|
||
| _, err = client.Do(req) |
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.
This http call needs to be made after reconfirming from the user, needs to be moved after checking thecanLogout.
| req.AddCookie(cookie) | ||
|
|
||
| _, err = client.Do(req) | ||
| errors.CheckError(err) |
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.
This method will cause a fatal error and cause the program to terminate abruptly. If the remote server is unavailable or errors out due to network issue, it is probably its better to give a warning and logout locally and clean up the local storage.
| return nil, "", common.ErrTokenVerification | ||
| } | ||
|
|
||
| id, _ := claims["jti"].(string) |
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.
better to check if the conversion to string was successful using an ok boolean (instead of ignoring). If the key is not found or if the conversion fails, id can be set to empty string probably with a warning log.
|
@GeorgiYosifov We are looking at speeding up the review and merge process. Please let us know if you can rebase the changes with the latest master branch. Let me know if you need any help. |
Fixes: #14930
OIDC, Dex and Admin token revocation is done correctly.
API and CLI entry points are corrected.
Unit tests are added for each implementation change.
Note on DCO:
If the DCO action in the integration test fails, one or more of your commits are not signed off. Please click on the Details link next to the DCO action for instructions on how to resolve this.
Checklist:
Please see Contribution FAQs if you have questions about your pull-request.