Last active
November 21, 2025 12:28
-
-
Save eqvinox/5094cf9453422749084da791c399815e to your computer and use it in GitHub Desktop.
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
| # SPDX-License-Identifier: Unlicense | |
| # netbox add-on to set up superuser/staff state & groups from keycloak | |
| # | |
| # necessary setup in keycloak: | |
| # Clients -(netbox client)-> Roles-> create superuser; assign users/groups/... to that role | |
| # Clients -(netbox client)-> Roles-> create staff; assign users/groups/... to that role | |
| # Clients -(netbox client)-> Client scopes -(the "dedicated" one)-> Add Mapper, -> | |
| # by configuration, Group Membership, Token Claim Name = "groups", full group path = off | |
| # (for the last one, alternatively, groups can be mapped through roles, if the indirection is nedeed) | |
| # | |
| # check with Client scopes -> Evaluate -> set user & target audience -> generated access token | |
| # should have ["resource_access"][<netbox ID>]["roles"] = [ ... ] | |
| # should have ["groups"] = [ ... ] | |
| # | |
| # superuser, staff & groups are overwritten on every login now; groups that don't exist in keycloak are removed | |
| # (it's not possible to have netbox-only groups for keycloak users, they'll get removed too) | |
| # | |
| # put somewhere python can find the file and do in netbox.configuration: | |
| # SOCIAL_AUTH_PIPELINE = ( | |
| # ... | |
| # 'keycloak_groups.keycloak_groups', # put it after user_details | |
| # ) | |
| from django.contrib.auth.models import User | |
| from users.models import Group | |
| def keycloak_groups(*, backend, response, user, **kwargs): | |
| resources = response.get("resource_access", {}).get(backend.auth_params()["client_id"], {}) | |
| roles = resources.get("roles", {}) | |
| user.is_superuser = "superuser" in roles | |
| user.is_staff = "staff" in roles or "superuser" in roles | |
| matched_netbox_groups = Group.objects.filter(name__in=response.get("groups", [])) | |
| user.groups.set(matched_netbox_groups) | |
| user.save() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment