Skip to content

Instantly share code, notes, and snippets.

@eqvinox
Last active November 21, 2025 12:28
Show Gist options
  • Select an option

  • Save eqvinox/5094cf9453422749084da791c399815e to your computer and use it in GitHub Desktop.

Select an option

Save eqvinox/5094cf9453422749084da791c399815e to your computer and use it in GitHub Desktop.
# 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