-
Notifications
You must be signed in to change notification settings - Fork 8
feat: Token exchange for tiled insertion #1342
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
Open
ZohebShaikh
wants to merge
12
commits into
main
Choose a base branch
from
token-exchange
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1342 +/- ##
==========================================
+ Coverage 95.00% 95.15% +0.14%
==========================================
Files 42 43 +1
Lines 2765 2848 +83
==========================================
+ Hits 2627 2710 +83
Misses 138 138 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Option 1: Service account with write access
One approach is to use a service account that is allowed to write.
For example, we could create a service account (e.g.
ixx-tiled-writer) that has permissions for the ixx beamline only. This service account would be able to write to all ixx beamline sessions exposed viaixx-blueapi.diamond.ac.uk, but would not be able to write to sessions belonging to other beamlines.We will need to add AuthZ in blueapi to make sure that the person writing to the session has access to it.This would require creating a dedicated Keycloak client (
ixx-tiled-writer) with its own client ID and secret.This information will be added as a hard coded token claims as
{ "fedid": "ixx-tiled-writer", "permissions": ["ixx-admin"] }Downside:
If the client ID and secret are leaked, a malicious actor would gain read/write access to all ixx beamline sessions (though still not delete access). While scoped, this is still a significant risk.
An alternative service-account approach is to not hardcode any beamline permissions into the token at all. In this model, a single service account will have write to any beamline session, and
blueapiwould perform an explicit authorization check before allowing writes, ensuring the caller has access to the target beamline session.This is effectively equivalent to an API-key style integration with Tiled.
Security concern:
If this single service account is leaked, the attacker would gain read/write access to all beamline data (again, excluding delete). This is a much larger blast radius and therefore a serious vulnerability.
The core reason this problem exists is that, in this approach, we are not propagating end-user identity (
fedid) through to Tiled.While this approach is simpler to implement, it is significantly less secure, as a malicious actor could read data that is not intended for them.
Note: I couldn’t find a approach where we encode the fedid that we have got from the blueapi token into the service account token dynamically.(might not be possible because you will be able to impersonate anyone)
Option 2: Token exchange preserving user identity (
fedid)The second approach is more complex but significantly more secure: using Keycloak token exchange to preserve the original user identity and permissions.
In this model,
ixx-blueapiuses its client secret to exchange a user access token for another token that is scoped for Tiled. Importantly, the exchanged token retains the same user identity and permissions as the original token.This requires enabling the following settings on the
ixx-blueapiclient:"standard.token.exchange.enabled": "true""standard.token.exchange.enableRefreshRequestedTokenType": "SAME_SESSION"With token exchange:
ixx-blueapiclient secret is leaked, it cannot be used to gain additional access to Tiled data + You will need a access token with a valid session and access token only lasts for 5 mins inidentity-testand 1 minute inauthnImplications for
blueapi-cliTo support this, the
blueapi-cliKeycloak client must behave like other clients(argocd,etc) in the realm. In particular:offline_access)Because token exchange never creates a new user session, a service account alone cannot be used here. We therefore need a client that can establish a user session.
We will need device flow client (
ixx-blueapi-cli) with:ixx-blueapi(the private client backingixx-blueapi.diamond.ac.uk)ixx-blueapiI have verified that long scans continue to work correctly: the session remains active because the token is continually exchanged and the user is actively interacting with
blueapi, even though this happens in a machine-to-machine style workflow.Will this have any impact on the GDA side ,as far as I know GDA is per beamline so it could easily have a device flow client per beamline. ?
Testing changes
System tests were updated to use device flow login via Playwright, which opens a browser and performs a real login. This works correctly in CI.
This change was necessary because service accounts do not have user sessions and therefore cannot perform token exchange.
When using Playwright, you must run:
Alternatively, you can comment out the Playwright login and perform a manual login using:
References
https://www.keycloak.org/securing-apps/token-exchange
Related PR in Tiled
There is also a related PR in Tiled adding support for custom authentication in the Tiled client:
bluesky/tiled#1269