Skip to content

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

Open
davidpcls wants to merge 21 commits intobluesky:mainfrom
davidpcls:main
Open

Add support for OIDC login workflows to the HTTP API#62
davidpcls wants to merge 21 commits intobluesky:mainfrom
davidpcls:main

Conversation

@davidpcls
Copy link
Copy Markdown

@davidpcls davidpcls commented Mar 13, 2026

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=
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>.:60610", http_auth_provider="entra/authorize")
RM.login()

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.

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