Skip to main content
Himmelblau supports several strategies for mapping Entra ID users and groups to POSIX UIDs and GIDs. You can use automatic range-based mapping, attributes stored directly in Entra ID, or a static override cache.

id_attr_map: choosing a mapping strategy

The id_attr_map option controls how UIDs and GIDs are derived:
ValueBehavior
name (default)Derives a UID/GID by hashing the user’s or group’s display name.
uuidDerives a UID/GID by hashing the object’s UUID.
rfc2307Reads uidNumber and gidNumber extension attributes stored on the Entra ID object. Recommended when migrating from on-prem AD with existing POSIX attribute sync.
[global]
id_attr_map = name

Automatic UID/GID ranges

idmap_range

Specifies the range of UIDs and GIDs available for automatic assignment. The default range is 200000-2000200000.
[global]
idmap_range = 200000-2000200000
IDs are assigned deterministically within this range based on a hash of the user or group name (or UUID, depending on id_attr_map).
If you change idmap_range, run sudo aad-tool cache-clear --full to remove stale UID/GID mappings that could cause overlaps, then restart himmelblaud.

subid_range

Specifies the range of subordinate IDs used to populate /etc/subuid and /etc/subgid for container support (Podman, rootless containers, etc.).
[global]
subid_range = 2100000000-4200000000
At login, Himmelblau automatically writes a 65536-ID slice from this range into /etc/subuid and /etc/subgid for each user. Slices are allocated deterministically based on a hash of the username. The default range is 2100000000-4200000000.

RFC2307 attributes in Entra ID

When id_attr_map = rfc2307, Himmelblau reads the uidNumber and gidNumber extension attributes directly from the Entra ID user or group object. These attributes must be registered as schema extensions and populated on each object.

Setting POSIX attributes on users

sudo aad-tool user set-posix-attrs \
  --schema-client-id <SCHEMA_CLIENT_ID> \
  --user-id user@domain.com \
  --uid 10001 \
  --gid 10001 \
  --home /home/user \
  --shell /bin/bash
The --schema-client-id must be the Client ID of the Entra ID application where the POSIX schema extensions were registered. That application must have User.ReadWrite.All permissions.

Setting POSIX attributes on groups

sudo aad-tool group set-posix-attrs \
  --schema-client-id <SCHEMA_CLIENT_ID> \
  --group-id <GROUP_OBJECT_ID> \
  --gid 10001

Pre-populating the local cache

Because UIDs and GIDs are normally fetched at login, objects that have never authenticated may not have their attributes cached locally. Use aad-tool enumerate to pre-populate the cache for all users and groups that have RFC2307 attributes:
sudo aad-tool enumerate --name admin@domain.com
The optional --client-id parameter specifies an Entra ID application with User.Read.All and Group.Read.All permissions. If omitted, Himmelblau uses the app_id from himmelblau.conf.

Static idmap cache

For migrations from on-prem Active Directory where UIDs and GIDs must be preserved exactly, you can add permanent static mappings that override the automatic assignment.

Adding a static user mapping

sudo aad-tool idmap user-add --name user@domain.com --uid 1234 --gid 1234
Maps the Entra ID user identified by UPN (or SAM-compatible name) to a fixed UID and primary GID.

Adding a static group mapping

sudo aad-tool idmap group-add --object_id <GROUP-GUID> --gid 1234
Maps the Entra ID group identified by its Object ID (GUID) to a fixed GID. Use the Object ID from the Entra admin portal.

Clearing the static idmap cache

sudo aad-tool idmap clear
Removes all entries from the static mapping cache. Subsequent UID/GID assignments fall back to the automatic strategy defined by id_attr_map.

Name mapping options

cn_name_mapping

When enabled (the default), users can log in with just the short form of their username (e.g., dave) instead of their full UPN (dave@contoso.com). Himmelblau resolves the short name to a UPN automatically.
[global]
cn_name_mapping = true

name_mapping_script

For environments where simple CN-to-UPN mapping is not sufficient, you can provide an executable script that accepts a mapped name as its only argument and prints the corresponding UPN to stdout. If the script does not recognize the name, it must return the input unchanged.
[global]
name_mapping_script = /etc/himmelblau/map-names.sh
Example script:
#!/bin/bash
if [[ "$1" =~ ^[a-zA-Z0-9._-]+$ ]]; then
    echo "$1@contoso.com"
else
    echo "$1"
fi

Build docs developers (and LLMs) love