Skip to content
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

Switched to use Access API for checking expired token #230

Merged
merged 6 commits into from
Dec 9, 2024

Conversation

alexhung
Copy link
Member

@alexhung alexhung commented Dec 6, 2024

Remove mutex from RefreshAccessToken()

Switch to RW lock for pathConfigUserTokenRead() and pathUserTokenCreatePerform()

Add scripts for testing refreshable tokens creation and concurrent token generation

Fixes #225

Remove mutex from RefreshAccessToken()

Switch to RW lock for pathConfigUserTokenRead() and pathUserTokenCreatePerform()

Add scripts for testing refreshable tokens creation and concurrent token generation
@alexhung alexhung added the bug Something isn't working label Dec 6, 2024
@alexhung alexhung marked this pull request as ready for review December 6, 2024 19:11
danielmkn
danielmkn previously approved these changes Dec 6, 2024
benharosh
benharosh previously approved these changes Dec 6, 2024
@alexhung
Copy link
Member Author

alexhung commented Dec 8, 2024

@elestedt Would you be able to test this out before I merge this into master and release it?

@elestedt
Copy link

elestedt commented Dec 9, 2024

I will test it today. But I did notice that the API used requires some form of admin permissions. If you run this as a normal user the endpoint returns

{
  "errors" : [ {
    "code" : "FORBIDDEN",
    "message" : "Forbidden"
  } ]

response back. It would be better to use an endpoint that does not generate and "error" in the artifactory logs. Such as the /access/api/v1/tokens endpoint.

@elestedt
Copy link

elestedt commented Dec 9, 2024

When I tried to build, I had to change go.mod to go 1.22.0 from go 1.22 or I got a "Toolchain not available" error. Not sure why.

@elestedt
Copy link

elestedt commented Dec 9, 2024

The new method works flawlessly - if the user is a platform Admin. For normal users it always fails with

{"errors":["failed to refresh access token"]}

@elestedt
Copy link

elestedt commented Dec 9, 2024

I built a local version that uses /access/api/v1/tokens instead of the role endpoint - and then it seems to work for non-admin users. This endpoint however I realized is not ideal as if the user has many tokens it will take a fairly long time to complete. Some other comparable, but faster, endpoint is needed.

artifactory.go Outdated

logger.Debug("fetching Viewer role")

resp, err := b.performArtifactoryGet(config, "/access/api/v1/roles/Viewer")
Copy link

Choose a reason for hiding this comment

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

Just to be clear - this is the endpoint that seems to require some form of admin permissions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for building and testing in your environment. I don't think there's a faster Access API to use for checking.

I just had a Doh! moment as I realized the expiration value is part of the token. I just need to decode it and check if the exp value is passed/after the current time.

Copy link

Choose a reason for hiding this comment

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

Yeah - that would be a good inital check. But assumes that the system time pf vault server is matched with the artifactory server and tinezones are set correctly. Now adays it should be, but... So if you go that route, add it as a requirement for the plugin and maybe also still have a backup that if it fails to create a token it renews the refreshable.

Copy link

Choose a reason for hiding this comment

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

You also only have the expiry in the JWT, if someone uses a reference token, it's not there. Another requirement if you want to inspect the token.

Copy link
Member Author

Choose a reason for hiding this comment

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

😠 Never mind. To parse the token I need the public key from the root certificate, which requires a admin token to fetch.

Copy link
Member Author

Choose a reason for hiding this comment

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

@elestedt I found the API to use. The Get token by ID API will work for both admin and non-admin tokens.

Copy link

Choose a reason for hiding this comment

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

That will work, as long as save the token id of the refreshable token. Assume you will do a rotation immediately when it's set? (As the token id is not supplied by the user)

Copy link
Member Author

Choose a reason for hiding this comment

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

The API accepts me as the token ID to get info about the token (in header). It's a reasonable 'hack'.

Copy link
Member Author

Choose a reason for hiding this comment

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

Screenshot 2024-12-09 at 10 39 38 AM

Copy link

Choose a reason for hiding this comment

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

Yeah, that is a good way to do it. Non admin and time deterministic, maybe even constant.
Go for it.

@alexhung alexhung merged commit ae24671 into master Dec 9, 2024
2 checks passed
@alexhung alexhung deleted the GH-225-fix-concurrency-issue branch December 9, 2024 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refresh Token Concurrency issue
5 participants