Skip to content

Allow pushing user-allocation membership to Keycloak#249

Merged
QuanMPhm merged 1 commit into
nerc-project:mainfrom
QuanMPhm:ops_948/auth_kc
Jun 2, 2026
Merged

Allow pushing user-allocation membership to Keycloak#249
QuanMPhm merged 1 commit into
nerc-project:mainfrom
QuanMPhm:ops_948/auth_kc

Conversation

@QuanMPhm

@QuanMPhm QuanMPhm commented Oct 3, 2025

Copy link
Copy Markdown
Contributor

Closes nerc-project/operations#948. More details in the commit message
There are still some questions I have below, so this is still a draft for now.

Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/tests/functional/openshift/test_allocation.py Outdated
@QuanMPhm

QuanMPhm commented Oct 6, 2025

Copy link
Copy Markdown
Contributor Author

@knikolla Two more questions:

  1. Do we also want validate_allocations to add PIs to Keycloak groups for pre-existing allocations?
  2. When a PI adds a user to an Coldfront project or allocation, do those users also get added to a the project's Keycloak group?

Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/tasks.py Outdated
Comment thread src/coldfront_plugin_cloud/tests/functional/openshift/test_allocation.py Outdated
@QuanMPhm

Copy link
Copy Markdown
Contributor Author

@knikolla I've addressed your comments except one. Also, do you have responses to these questions?

Comment thread src/coldfront_plugin_cloud/base.py Outdated
@knikolla

Copy link
Copy Markdown
Collaborator

@QuanMPhm please resolve conflicts. Are there any questions that I missed answering?

@QuanMPhm

Copy link
Copy Markdown
Contributor Author

@knikolla Just this one. I will resolve the conflicts while waiting for your answer

@knikolla

Copy link
Copy Markdown
Collaborator

@knikolla Just this one. I will resolve the conflicts while waiting for your answer

Responded.

@QuanMPhm QuanMPhm force-pushed the ops_948/auth_kc branch 2 times, most recently from a217f31 to 0358cb7 Compare March 20, 2026 20:28
@QuanMPhm QuanMPhm marked this pull request as ready for review March 20, 2026 20:41
Comment thread src/coldfront_plugin_cloud/openshift.py Outdated
Comment thread src/coldfront_plugin_cloud/base.py Outdated

@knikolla knikolla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Did a quick first pass and provided some comments.

Also this needs to be possible configurable via a setting.

@knikolla

Copy link
Copy Markdown
Collaborator

@QuanMPhm Actually, another thought, do you think it would make sense to implement this in the Keycloak plugin? https://github.com/nerc-project/coldfront-plugin-keycloak

It could listen to signals in the same way that the cloud plugin listens to signals. It already has a keycloak client implemented.

And there is nothing in pushing users to a Keycloak group that is specific to either OpenShift or OpenStack.

@QuanMPhm

Copy link
Copy Markdown
Contributor Author

@knikolla I see that it does make sense to seperate the Keycloak functionality from the rest of the plugin. It makes sense to me. I forgot that repo existed. There would need to be some overhaul to add integration and unit tests to coldfront-plugin-keycloak. Is that fine?

@knikolla

Copy link
Copy Markdown
Collaborator

@knikolla I see that it does make sense to seperate the Keycloak functionality from the rest of the plugin. It makes sense to me. I forgot that repo existed. There would need to be some overhaul to add integration and unit tests to coldfront-plugin-keycloak. Is that fine?

For now let's keep it here (as not to frontload the work) and we can easily split it out later if needed. Perhaps try implementing it here via signals so as to keep it loosely coupled so that if we need to split it later it doesn't require a lot of uncoupling.

@QuanMPhm

QuanMPhm commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

@knikolla @larsks I have a question about the Coldfront Keycloak PR. I know we previously decided to represent user-membership to an allocation by adding them to a Keycloak group with the same name as the ALLOCATION_PROJECT_ID . Would it make more sense for the group name to be the allocation's ID on Coldfront instead? This has a stronger guarantee of uniqueness, and we won't have to disambiguate for projects with the same name in different clusters. Developers or tools can correlate the allocation id to the on-cluster project id by using the Coldfront API.

@knikolla knikolla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looking much better. Almost there.

A follow-up to this (after we merge the validate_allocations refactor) should investigate how to cleanly implement this in validate_allocations too.

Comment thread src/coldfront_plugin_cloud/attributes.py Outdated
@knikolla

knikolla commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator

Looking much better. Almost there.

A follow-up to this (after we merge the validate_allocations refactor) should investigate how to cleanly implement this in validate_allocations too.

Actually... I would make it a whole separate CLI command. validate_keycloak_groups.

@QuanMPhm

QuanMPhm commented Apr 8, 2026

Copy link
Copy Markdown
Contributor Author

@knikolla I've allowed the group name template string to accept any allocation attribute. Further documentation is in the docstring for the function _get_keycloak_group_name

@QuanMPhm QuanMPhm requested a review from knikolla April 8, 2026 14:38
@knikolla

knikolla commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

@naved001 would appreciate a pass from you.

@knikolla knikolla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Had some more time to think about how to expose enabling/disable the feature.

Comment thread src/coldfront_plugin_cloud/tasks.py Outdated
Comment thread src/coldfront_plugin_cloud/tasks.py
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/tasks.py
Comment thread src/coldfront_plugin_cloud/kc_client.py
Comment thread src/coldfront_plugin_cloud/kc_client.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds Keycloak integration to push ColdFront allocation membership into Keycloak group membership, driven by a resource-level group-name template and exercised via new functional tests/CI workflow.

Changes:

  • Add Keycloak client + tasks to add/remove allocation users to/from Keycloak groups based on a configurable template.
  • Wire Keycloak add/remove behavior into allocation-user signals when Keycloak is enabled via environment.
  • Introduce Keycloak functional tests and CI scripts/workflow to run them.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/coldfront_plugin_cloud/tests/functional/keycloak/test_keycloak.py Adds functional tests validating Keycloak user/group membership behavior for allocation changes.
src/coldfront_plugin_cloud/tests/functional/keycloak/init.py Introduces package for Keycloak functional tests.
src/coldfront_plugin_cloud/tasks.py Adds Keycloak client caching and add/remove group membership tasks; adds group-name templating helper.
src/coldfront_plugin_cloud/signals.py Hooks Keycloak add/remove tasks into allocation user add/remove signals behind an env flag.
src/coldfront_plugin_cloud/management/commands/validate_allocations.py Tweaks logging/comment wording related to user sync validation.
src/coldfront_plugin_cloud/kc_client.py Adds a Keycloak admin API client for groups/users operations.
src/coldfront_plugin_cloud/attributes.py Adds resource attribute for Keycloak group name template.
requirements.txt Adds requests dependency for the Keycloak client.
ci/setup-keycloak.sh Adds Keycloak container bootstrap script for CI/local functional tests.
ci/run_functional_tests_keycloak.sh Adds a runner script to execute Keycloak functional tests with required env vars.
.github/workflows/test-functional-keycloak.yaml Adds a GitHub Actions workflow to run Keycloak functional tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/coldfront_plugin_cloud/tasks.py
Comment thread src/coldfront_plugin_cloud/tasks.py
Comment thread src/coldfront_plugin_cloud/tasks.py Outdated
Comment thread src/coldfront_plugin_cloud/signals.py
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread ci/setup-keycloak.sh
Comment thread ci/setup-keycloak.sh Outdated
Comment thread src/coldfront_plugin_cloud/tests/functional/keycloak/test_keycloak.py Outdated
Comment thread src/coldfront_plugin_cloud/kc_client.py
Comment thread src/coldfront_plugin_cloud/kc_client.py
@QuanMPhm QuanMPhm force-pushed the ops_948/auth_kc branch 2 times, most recently from 51df802 to 6cb51d7 Compare April 10, 2026 20:01
@QuanMPhm QuanMPhm requested review from knikolla and naved001 April 13, 2026 12:54
@QuanMPhm

Copy link
Copy Markdown
Contributor Author

@knikolla @naved001 I have responded to all comments

Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread src/coldfront_plugin_cloud/signals.py
Comment thread ci/setup-keycloak.sh
Comment thread src/coldfront_plugin_cloud/kc_client.py Outdated
Comment thread ci/setup-keycloak.sh Outdated
A Keycloak admin client has been added
When `activate_allocation` is called, the user is added
to a Keycloak group named using a format string defined in the
allocation's resource attribute "Format String for Keystone Group Names"
If the user does not already exist in Keycloak, the case is ignored for now

Keycloak integration is optional, toggled by setting the env var "KEYCLOAK_BASE_URL"
Authentication to Keycloak is done via client credentials grant

When `deactivate_allocation` is called, the user is removed from the Keycloak group

New functional test added for Keycloak integration

A comment in `validate_allocations` has been updated to
reflect the more restrictive validation behavior, where users on cluster projects
will be removed if they are not part of the Coldfront allocation (rather
than if they are not registered on Coldfront at all).
@QuanMPhm

QuanMPhm commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all comments, except one waiting for @knikolla response

@QuanMPhm QuanMPhm merged commit 57beb08 into nerc-project:main Jun 2, 2026
5 checks passed
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.

Investigate centralizing authorization for NERC users in Keycloak

5 participants