Entra ID Groups to NetBox 4.x Groups

When using the built-in SSO (Single Sign-On) in NetBox with Entra ID, the Active Directory (AD) group or role information for the users is not available out of the box.

Based on the discussions in NetBox repo I tested and wrote down a short memo of getting the users’ groups usable in NetBox. In this scenario Entra ID will send the groups, and the authentication pipeline in NetBox will create and assign NetBox groups based on those AD groups. Depending on the configurations in the Entra side, you can also use roles instead of groups.

I like to use the /opt/netbox/netbox/local directory for these kinds of local customizations as it is not conflicting with the NetBox git repository, so here is my /opt/netbox/netbox/local/custom_auth.py:

import logging

from netbox.authentication import Group


logger = logging.getLogger("netbox.local.custom_auth")


class AuthFailed(Exception):
    pass


def set_groups(response, user, *args, **kwargs):
    try:
        groups = response["groups"]
    except KeyError:
        logger.error("No groups attribute for %s", user.username)
        raise AuthFailed("No groups attribute")
    logger.info(
        "Groups assigned to %s: %s",
        user.username,
        ", ".join(groups),
    )

    # Ensure that only Entra ID-provided information is used
    user.groups.clear()
    user.is_superuser = False

    for group in groups:
        if group == "AdminGroup":
            logger.info("User %s is superuser", user.username)
            user.is_superuser = True
            user.save()
        netbox_group, created = Group.objects.get_or_create(name=group)
        netbox_group.users.add(user)
        if created:
            logger.info("Created new group: %s", group)

If you haven’t configured logging in NetBox, you can leave out all the logging-related code above.

Roles work similarly to groups, just use the roles attribute of the response object instead of groups.

To the end of /opt/netbox/netbox/netbox/configuration.py, add these:

REMOTE_AUTH_BACKEND = "social_core.backends.azuread.AzureADOAuth2"
SOCIAL_AUTH_AZUREAD_OAUTH2_KEY = "this_is_the_application_id"
SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET = "this_is_the_secret_value"
# Default is FirstnameLastname, I prefer the UPN/email
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
# See /opt/netbox/netbox/netbox/settings.py for the default pipeline,
# copy it and add the local customization to that list
SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'netbox.authentication.user_default_groups_handler',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    'local.custom_auth.set_groups',
)

Restart netbox and netbox-rq services.

Tested with NetBox 4.2.7. See also the NetBox documentation: https://netboxlabs.com/docs/netbox/en/stable/administration/authentication/microsoft-entra-id/

2 Comments

Add a Comment
  1. Hey Markku. I tried your approach today, using groups instead of roles. I can login with my EntraID, the user gets created in Netbox, the group gets created but the name is the uid. You know how to change/map id to name?

    1. Hi, try to make Entra ID return the groups as names and not GUIDs. If that is not possible for any reason, you can modify custom_auth.py to map GUIDs manually to human-readable group names with a dict.

Leave a Reply