Skip to content

Add support for OIDC login workflows to the HTTP API - #62

Draft
davidpcls wants to merge 27 commits into
bluesky:mainfrom
davidpcls:main
Draft

Add support for OIDC login workflows to the HTTP API#62
davidpcls wants to merge 27 commits into
bluesky:mainfrom
davidpcls:main

Conversation

@davidpcls

@davidpcls davidpcls commented Mar 13, 2026

Copy link
Copy Markdown

Description

This provides support for OIDC logins using the API, in both device and code flows. I was able to test this on both local and remote deployments of the http-server application and both would result in a completely non-interactive SSO workflow. For example this is what the login flow looks like using MS Entra:

from bluesky_queueserver_api.http import REManagerAPI
from bluesky_queueserver_api import BPlan
RM = REManagerAPI(http_server_uri="http://localhost:60610", http_auth_provider="entra/authorize")
RM.login()

At this point, with no other interaction, the user will be logged in. The API will spawn a browser and provided that the user has already logged in no interaction is required. Since the password login is still available this is a backwards compatible change, although obviously if the httpserver doesn't have OIDC support trying to login with OIDC isn't going to do much. An associated PR for the final changes to the bluesky-httpserver will be linked here soon.

Motivation and Context

This change is required to provide the other side of the OIDC support being added to the bluesky-httpserver. Without it you can't actually use the OIDC flow. We want this at the CLS so that we only use a single auth/authz provider. Since Tiled supports OIDC flows already and our facility is tightening security moving to SSO is required.

Summary of Changes for Release Notes

Changed both async and sync http api to be able to detect when OIDC is being used and start an OIDC login low, including spawning a browser session for authentication. Added unit tests for this along with scripts to allow running the unit tests locally.

Fixed

Added

  • OIDC support for HTTP api

Changed

Removed

How Has This Been Tested?

This was tested on Debian 13 based machines using firefox. I tested it in two ways, locally and remotely.

Httpserver config for testing

authentication:
  providers:
    - provider: entra
      authenticator: bluesky_httpserver.authenticators:OIDCAuthenticator
      args:
        audience: {application_id}
        client_id: {client_id}
        client_secret: ${BSKY_ENTRA_SECRET}
        well_known_uri: https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration
        confirmation_message: "You have logged in successfully."
api_access:
  policy: bluesky_httpserver.authorization:DictionaryAPIAccessControl
  args:
    users:
      pastld:
        roles:
          - admin
          - expert

Locally

I did this on localhost, with the queueserver and redis running locally. Both queueserver and redis were not modified. The queueserver config was basic.

Server Startup

export QSERVER_HTTP_SERVER_CONFIG=example_http_configs/entra_config.yml
export BSKY_ENTRA_SECRET=<secret>
uv run uvicorn --host localhost --port 60610 bluesky_httpserver.server:app

API Commands

from bluesky_queueserver_api.http import REManagerAPI
from bluesky_queueserver_api import BPlan
RM = REManagerAPI(http_server_uri="http://localhost:60610", http_auth_provider="entra/authorize")
RM.login()

Remotely

Server Startup

export QSERVER_HTTP_SERVER_CONFIG=example_http_configs/entra_config.yml
export BSKY_ENTRA_SECRET=<secret>
uv run uvicorn --host 0.0.0.0 --port 60610 bluesky_httpserver.server:app

API Commands

I've removed parts of the URL here for security reasons.

from bluesky_queueserver_api.http import REManagerAPI
from bluesky_queueserver_api import BPlan
RM = REManagerAPI(http_server_uri="https://<server_name>.<domain>:60610", http_auth_provider="entra/authorize")
RM.login()

TODO

  • This currently fails when you get a failed login, as the login attempt with the queueserver api does not end. This needs to be fixed
  • Undo some of the changes to pyproject unless they are necessary. No need to change how project requirements are set.

This is working with the changes to the HTTP server, but has not been
refined at all.
Signed-off-by: David Pastl <david.pastl@lightsource.ca>
Breaking out existing unit tests into separate files for readability.
Added OIDC unit tests.
The workflow had names, but for some reason on github each workflow
didn't follow that name. Thsi attempts to fix that and make it easier to
see what each workflow did.
This dramatically speeds up unit tests, from around 1.5h to 10 minutes
by running multiple docker containers in parallel as workers. This is
almost certainly not the most optimzied way of doing this, but I found
it useful to reduce test times.
Updated the docs to include instructions on how to build this project
locally, along with how to use the new parallel run tool I added.

Added / updated the parallel CI run tool. This was dropping the unit
test run times from hours to around 9 minutes for unit tests on a
single python version, or around 30 minutes when testing all possible
python versions.

Added a fix for a failing unit test
This allows us to use pixi / uv now. The CI workflows should all still
function the same.
@davidpcls

Copy link
Copy Markdown
Author

I've tried to get the unit tests working properly, but I'm having some issues that I think are related to how the tests run and not the tests themselves. The tests run cleanly locally with my parallel processing script, but I think that's because of how the tests run when they're broken up into such small chunks. There isn't a chance for a lingering test to break another like I believe is happening here.

@davidpcls

Copy link
Copy Markdown
Author

So, these tests reliably pass on my personal github account. I'm a little confused by why they reliably fail on this PR.

I'm going to leave as is for now until I hear back from someone here, as I think all I'm going to do is introduce more changes that people may or may not want in trying to fix the unit test runner reliability.

@davidpcls

Copy link
Copy Markdown
Author

This currently fails when you get a failed login, as the login attempt with the queueserver api does not end.

@davidpcls

Copy link
Copy Markdown
Author

@dmgav I'm going to clean up this now too so we can have full OIDC type auth support in the api, then I'll submit it for review.

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.

1 participant