advanced

Subordinate IDs

Manage subordinate UID and GID ranges for user namespaces in containers. Subordinate IDs enable unprivileged container usage by providing non-overlapping UID/GID ranges for container processes. Features include automatic range assignment, range generation, range statistics, and integration with container runtimes for secure, isolated container deployments without requiring privileged operations.

6 commands
advanced

Overview

Subordinate IDs (subids) provide non-overlapping UID and GID ranges for user namespaces in containerized environments. User namespaces enable unprivileged users to run containers by mapping container root (UID 0) to unprivileged UIDs outside the container, preventing privilege escalation while maintaining container functionality.

Each subid range assignment allocates 65,536 UIDs and 65,536 GIDs to a user, enabling containers to map their internal user namespace (UIDs 0-65535) to the user’s subordinate range on the host. This isolation ensures processes running as root inside a container run as unprivileged UIDs outside the container, eliminating privilege escalation risks from container breakouts.

User Namespace Mapping

Traditional containers: Container processes run as UIDs on the host system. If a process runs as root (UID 0) in the container, it runs as root (UID 0) on the host—a security risk if the container is compromised.

User namespaces: Container root (UID 0) maps to a subordinate UID range on the host. For example:

  • Container UID 0 → Host UID 200000 (subordinate range start)
  • Container UID 1000 → Host UID 201000
  • Container UID 65535 → Host UID 265535

The container sees UIDs 0-65535 internally, but on the host, these map to unprivileged UIDs 200000-265535. Even if an attacker compromises the container and gains root inside it, they only have UID 200000 on the host—an unprivileged user.

Automatic Range Assignment

IPA automatically generates non-overlapping subordinate ranges using subid-generate. Each generated range contains:

  • subuid: Starting UID for the subordinate user ID range (65,536 UIDs allocated)
  • subgid: Starting GID for the subordinate group ID range (65,536 GIDs allocated)

Important limitations:

  • subuid and subgid are always identical: They cannot be set independently. Both start at the same value and have the same size (65,536).
  • Range size is fixed: All ranges are exactly 65,536 UIDs and 65,536 GIDs. This size cannot be modified.
  • One range per user: Users are limited to a single subordinate ID range. Multiple ranges per user are not supported.
  • No manual deletion: Ranges cannot be manually deleted with subid-del (command is hidden). Ranges are only reclaimed when the user is deleted.

Ranges never overlap between users, ensuring containers for different users remain isolated. IPA tracks all assigned ranges and automatically selects free ranges for new assignments.

Integration with Container Runtimes

Container runtimes (Podman, Docker with userns-remap) query IPA for user subordinate ranges via /etc/subuid and /etc/subgid files populated by SSSD. When a user runs a container, the runtime:

  1. Queries user’s subordinate range from IPA via SSSD
  2. Creates a user namespace mapping container UIDs/GIDs to the subordinate range
  3. Starts the container with remapped UIDs/GIDs
  4. Container processes appear as subordinate UIDs on the host, not privileged UIDs

This enables unprivileged container operations without granting users dangerous capabilities.

Manage subordinate user and group ids for users

EXAMPLES

Auto-assign a subordinate id range to current user

ipa subid-generate

Auto-assign a subordinate id range to user alice:

ipa subid-generate --owner=alice

Find subordinate ids for user alice:

ipa subid-find --owner=alice

Match entry by any subordinate uid in range:

ipa subid-match --subuid=2147483649

Use Cases

Enabling Unprivileged Container Usage for Developers

Development teams need to run containers without requiring privileged access or sudo. Allocate subordinate ID ranges to enable rootless container execution.

# Allocate subordinate ID range for developer
ipa subid-generate --owner=alice

# View assigned range
ipa subid-find --owner=alice
  Unique ID: alice-subid1
  Description: Subordinate id range for alice
  Owner: alice
  SubUID range start: 200000
  SubGID range start: 200000
  SubUID range size: 65536
  SubGID range size: 65536

# Alice can now run unprivileged containers
# On alice's workstation:
podman run --rm -it alpine sh
  # Container root (UID 0) runs as UID 200000 on host
  # No privilege escalation possible

Bulk Subid Assignment for Team Onboarding

When onboarding a new team that will use containers, pre-allocate subordinate ranges for all team members.

# Get list of team members
ipa group-show devops-team --all | grep "Member users"
  Member users: alice, bob, charlie, david

# Allocate subid ranges for each team member
for user in alice bob charlie david; do
  ipa subid-generate --owner="$user"
  echo "Allocated subid range for $user"
done

# Verify all allocations
ipa subid-find --all
  # Shows ranges for all team members

# Team members can immediately start using containers

Investigating Which User Owns a Container Process

When monitoring host processes, identify which user owns a container based on subordinate UID.

# Host shows process running as UID 201523
ps aux | grep 201523
  201523    1234  0.0  0.1  container-process

# Find which user owns subordinate range containing UID 201523
ipa subid-match --subuid=201523
  Unique ID: alice-subid1
  Owner: alice
  SubUID range start: 200000
  SubUID range size: 65536

# UID 201523 is in alice's range (200000-265535)
# Container belongs to alice

Checking Subordinate ID Statistics

Monitor subordinate ID allocation to plan capacity and identify when ranges are exhausted.

# Show subordinate ID statistics
ipa subid-stats
  Subordinate id statistics
  Assigned subordinate ids: 147
  Available subordinate id space: 32621

# Calculate utilization
# Assigned: 147 ranges * 65536 = 9,633,792 UIDs allocated
# Available: 32621 ranges * 65536 = 2,137,554,656 UIDs available

# Plan for growth: 32621 ranges available supports 32621 additional users

Modifying Subid Description for Documentation

Add descriptive information to subordinate ID ranges for inventory and troubleshooting.

# Find subid ID for user
ipa subid-find --owner=alice
  Unique ID: alice-subid1

# Add description documenting purpose
ipa subid-mod alice-subid1 \
  --desc="Container range for DevOps team member Alice - assigned 2024-03-15"

# Verify description
ipa subid-show alice-subid1
  Unique ID: alice-subid1
  Description: Container range for DevOps team member Alice - assigned 2024-03-15
  Owner: alice
  SubUID range start: 200000

Troubleshooting Container User Namespace Failures

When users report container startup failures related to user namespaces, verify subordinate ID configuration.

# User reports: "Error: cannot set up namespace using newuidmap"

# Check if user has subordinate ID range assigned
ipa subid-find --owner=bob
  # 0 results - no subordinate ID assigned

# Allocate subordinate range
ipa subid-generate --owner=bob

# Verify SSSD populates /etc/subuid and /etc/subgid
# On bob's workstation:
grep bob /etc/subuid
  bob:200000:65536

grep bob /etc/subgid
  bob:200000:65536

# Bob can now start containers with user namespaces
podman run --rm alpine id
  uid=0(root) gid=0(root)
  # Inside container shows root
# Outside container shows UID 200000 (unprivileged)

Identifying Subordinate ID Range Conflicts

Detect if subordinate ranges unexpectedly overlap, indicating configuration errors.

# List all subid ranges with start values
ipa subid-find --all | grep -E "(Owner|SubUID range start)"
  Owner: alice
  SubUID range start: 200000
  Owner: bob
  SubUID range start: 265536
  Owner: charlie
  SubUID range start: 200000
  # Conflict: alice and charlie have same start!

# This should never happen with ipa subid-generate
# If found, indicates manual modification or corruption
# Investigate and fix by modifying one range

Self-Service Subid Generation

Allow users to generate their own subordinate ID ranges without administrator intervention.

# User alice generates own subid range
kinit alice
ipa subid-generate
  # Allocates range to alice automatically

# Verify self-allocated range
ipa subid-find --owner=alice
  Unique ID: alice-subid1
  Owner: alice
  SubUID range start: 200000

# Alice can immediately use containers without waiting for admin

Cleaning Up Subid Ranges for Decommissioned Users

When users leave the organization, reclaim their subordinate ID ranges to prevent resource exhaustion.

# User bob deactivated
ipa user-disable bob

# Find bob's subid ranges
ipa subid-find --owner=bob
  Unique ID: bob-subid1

# Note: No subid-del command exists
# Subordinate IDs are automatically cleaned when user is deleted
ipa user-del bob
  # Deletes user and associated subordinate ID ranges

# Verify cleanup
ipa subid-find --owner=bob
  # 0 results - ranges reclaimed

Documenting Container Infrastructure for Compliance

Generate subordinate ID allocation report for security audits and compliance documentation.

# Generate complete subid allocation report
echo "# Subordinate ID Range Allocation Report"
echo "Generated: $(date)"
echo ""

ipa subid-stats
echo ""

echo "## Allocated Ranges"
ipa subid-find --all | grep -E "(Unique ID|Owner|SubUID|SubGID)" | \
  awk 'BEGIN {RS=""; FS="\n"} {print $0; print ""}'

# Report documents:
# - Total ranges allocated
# - Available capacity
# - Per-user range assignments
# - Range start values for each user
# Supports compliance requirements for container isolation

Security Considerations

Subordinate ranges enable container breakout mitigation: Properly configured subordinate IDs prevent container root from having privileges on the host. However, if subordinate ranges overlap or are incorrectly configured, containers from different users could interfere with each other’s files.

Range overlap creates security boundaries breach: If two users have overlapping subordinate ranges, processes in one user’s container could access or modify files owned by UIDs in another user’s container. IPA’s automatic range generation prevents this, but manual modifications could introduce overlaps.

Large range size required for complex containers: The default 65,536 UID/GID range supports most containers, but very large containers with many distinct UIDs may exhaust the range. Increasing range size risks range overlap if not carefully managed.

Subordinate ranges don’t prevent all container escapes: User namespaces mitigate privilege escalation from container root to host root, but kernel vulnerabilities or misconfigured capabilities can still enable container breakout. Subordinate IDs are one layer of defense, not complete container security.

SSSD propagation delays create timing windows: After allocating subordinate ranges in IPA, SSSD must update /etc/subuid and /etc/subgid on client systems. During propagation delays, users may encounter errors starting containers even though ranges are assigned.

No automatic range revocation on user disable: Disabling a user doesn’t automatically reclaim their subordinate ID ranges. Ranges remain allocated until user deletion. Disabled users’ ranges consume capacity unnecessarily.

Subid statistics don’t account for deleted users: The available subordinate ID space calculation doesn’t immediately reflect deleted users’ reclaimed ranges. Statistics may show less available space than actually exists until database cleanup completes.

Manual range modification can break container isolation: Direct LDAP modifications to subordinate range values (start, size) can create overlaps or gaps that compromise container isolation. Always use IPA commands for subordinate ID management.

No per-range access controls: All users with subordinate ID ranges have equal range sizes and capabilities. There’s no mechanism to grant larger ranges to some users or restrict range usage based on policy.

Container runtime dependency: Subordinate ID effectiveness depends on container runtime support for user namespaces. Older runtimes or misconfigured systems may ignore subordinate ranges, running containers with privileged UIDs.

Troubleshooting

subid-generate Returns “No free subordinate id range available”

Symptom: Attempting to generate subordinate ID fails with error about no available ranges.

Diagnosis: IPA’s subordinate ID space exhausted or range allocation configuration issues.

Resolution: Check statistics and expand range or clean up unused ranges:

# Check current allocation
ipa subid-stats
  Assigned subordinate ids: 65000
  Available subordinate id space: 0
  # No ranges available

# This is extremely rare with default configuration
# Default supports ~65,000 users

# Review if cleanup needed
ipa subid-find --all | wc -l
  # If much larger than user count, stale ranges may exist

# Subordinate IDs auto-cleanup with user deletion
# Delete inactive users to reclaim ranges
ipa user-find --disabled=TRUE
  # Review disabled users

# Delete truly inactive users
ipa user-del old-user1
  # Reclaims subordinate ID range

Container Fails with “newuidmap: write to uid_map failed”

Symptom: Container startup fails with newuidmap or newgidmap errors.

Diagnosis: Subordinate ID ranges not present in /etc/subuid or /etc/subgid on client system.

Resolution: Verify SSSD configuration and force update:

# Check if user has subordinate range in IPA
ipa subid-find --owner=alice
  Unique ID: alice-subid1
  SubUID range start: 200000

# On client, check if range present in subuid/subgid files
grep alice /etc/subuid
  # Empty - SSSD hasn't populated file

# Verify SSSD subid configuration
grep -r subid /etc/sssd/sssd.conf
  # Should include subid provider configuration

# Restart SSSD to force update
systemctl restart sssd

# Wait for SSSD to fetch subordinate IDs
sleep 10

# Verify files populated
grep alice /etc/subuid
  alice:200000:65536

# Retry container start
podman run alpine
  # Should succeed now

Cannot Find Subid by SubUID Value

Symptom: ipa subid-match --subuid returns no results for known subordinate UID.

Diagnosis: UID value outside any allocated range, or incorrect UID value.

Resolution: Verify UID is actually from a subordinate range:

# Check if UID looks like a subordinate UID
# Subordinate UIDs typically start at 100000 or higher
# Regular UIDs are typically below 60000

# Try finding ranges near the UID
ipa subid-find --all | grep -B2 -A2 "201000"
  # Look for ranges containing that UID

# If UID is in an allocated range:
ipa subid-match --subuid=201000
  # Should return owning user

# If returns no results, UID may not be from subordinate range
# Verify on host where process runs
id 201000
  # Check if this is actually a subordinate mapped UID

Subid-find Shows No Ranges for User

Symptom: User reports container failures; ipa subid-find --owner=user shows no results.

Diagnosis: User has no subordinate ID range allocated.

Resolution: Allocate range for user:

# Verify user exists
ipa user-show alice

# No subordinate range exists
ipa subid-find --owner=alice
  # 0 results

# Allocate range
ipa subid-generate --owner=alice

# Verify allocation
ipa subid-find --owner=alice
  Unique ID: alice-subid1
  Owner: alice
  SubUID range start: 200000

# User must wait for SSSD update or manually refresh
# On client:
sss_cache -E

Cannot Modify Subid Range Start Value

Symptom: Want to change subordinate UID range start but no option in subid-mod.

Diagnosis: Range start values are not modifiable via IPA commands to prevent overlaps.

Resolution: Range starts are immutable by design for safety:

# Cannot change range start
ipa subid-mod alice-subid1 --subuid=300000
  # No such option

# Range allocation is permanent
# If range must change (extremely rare), delete user and recreate
# WARNING: This destroys all user data and container mappings

# Only do this if absolutely necessary
ipa user-del alice
ipa user-add alice --first=Alice --last=User
ipa subid-generate --owner=alice
  # Gets new random range

Subid-stats Shows Fewer Available Ranges Than Expected

Symptom: After deleting users, subid-stats still shows low available ranges.

Diagnosis: Statistics may not update immediately after user deletion.

Resolution: Wait for cleanup and verify statistics:

# Check statistics
ipa subid-stats
  Available subordinate id space: 100

# Delete inactive user
ipa user-del olduser

# Statistics may not update immediately
# Wait a few minutes
sleep 300

# Check again
ipa subid-stats
  Available subordinate id space: 101
  # Incremented after cleanup

# If statistics don't update, restart IPA services
ipactl restart

Multiple Subid Entries for Single User

Symptom: ipa subid-find --owner=alice shows multiple subordinate ID ranges for one user.

Diagnosis: Multiple subid-generate calls or manual creation. This is technically allowed but unusual.

Resolution: Verify if multiple ranges are intentional:

# Check user's ranges
ipa subid-find --owner=alice
  Unique ID: alice-subid1
  SubUID range start: 200000

  Unique ID: alice-subid2
  SubUID range start: 400000

# Multiple ranges are allowed but uncommon
# Containers will use the first range typically

# If unintended, delete extra ranges via user deletion/recreation
# Or document if intentional for special use cases

Container Processes Show Wrong UID Mapping

Symptom: Container process appears as wrong UID on host; doesn’t match expected subordinate range.

Diagnosis: Container runtime not using subordinate ranges, or range misconfiguration.

Resolution: Verify container runtime configuration:

# Check user's subordinate range
ipa subid-find --owner=alice
  SubUID range start: 200000

# Start container and check process UID
podman run -d alpine sleep 1000
ps aux | grep sleep
  alice     5678  ... sleep 1000
  # Shows alice's regular UID, not subordinate range

# Container not using user namespace
# Force user namespace usage
podman run --userns=keep-id -d alpine sleep 1000
ps aux | grep sleep
  200001    5679  ... sleep 1000
  # Now showing subordinate UID (200000 + 1)

Permission Denied When Running subid-generate

Symptom: Regular user cannot run ipa subid-generate for themselves.

Diagnosis: User lacks self-service permissions for subordinate ID generation.

Resolution: Grant self-service capability or use admin account:

# As regular user, try to generate
kinit alice
ipa subid-generate
  ipa: ERROR: Insufficient access

# Option 1: Admin allocates for user
kinit admin
ipa subid-generate --owner=alice

# Option 2: Grant self-service permission (advanced)
# Requires RBAC configuration to allow users to generate own subids
# This is environment-specific based on security policy

Subid Range Causing File Ownership Issues

Symptom: Files created in container have wrong ownership on host filesystem.

Diagnosis: Bind-mounted volumes with file ownership don’t account for subordinate UID mapping.

Resolution: Understand UID mapping for bind mounts:

# User's subordinate range starts at 200000
ipa subid-find --owner=alice
  SubUID range start: 200000

# Container creates file as UID 0 (root inside container)
podman run --rm -v /tmp/test:/data alpine touch /data/file
ls -ln /tmp/test/file
  -rw-r--r-- 1 200000 200000 0 ... /tmp/test/file
  # File owned by UID 200000 on host (container root=200000)

# Regular alice UID might be 1001
# Cannot access file owned by UID 200000

# Solution: Use --userns=keep-id for volume ownership compatibility
podman run --userns=keep-id --rm -v /tmp/test:/data alpine touch /data/file2
ls -ln /tmp/test/file2
  -rw-r--r-- 1 1001 1001 0 ... /tmp/test/file2
  # File owned by alice's regular UID

Commands

subid-find

Usage: ipa [global-options] subid-find [CRITERIA] [options]

Search for subordinate id.

Arguments

Argument Required Description


CRITERIA no A string searched in all relevant object attributes

Options

OptionDescription
--id IDUnique ID
--desc DESCSubordinate id description
--owner OWNEROwning user of subordinate id entry
--subuid SUBUIDStart value for subordinate user ID (subuid) range
--subgid SUBGIDStart value for subordinate group ID (subgid) range
--timelimit TIMELIMITTime limit of search in seconds (0 is unlimited)
--sizelimit SIZELIMITMaximum number of entries returned (0 is unlimited)
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.
--pkey-onlyResults should contain primary key attribute only (“id”)

subid-generate

Usage: ipa [global-options] subid-generate [options]

Generate and auto-assign subuid and subgid range to user entry

Options

OptionDescription
--owner OWNEROwning user of subordinate id entry
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.

subid-match

Usage: ipa [global-options] subid-match [CRITERIA] [options]

Match users by any subordinate uid in their range

Arguments

Argument Required Description


CRITERIA no A string searched in all relevant object attributes

Options

OptionDescription
--subuid SUBUIDMatch value for subordinate user ID
--timelimit TIMELIMITTime limit of search in seconds (0 is unlimited)
--sizelimit SIZELIMITMaximum number of entries returned (0 is unlimited)
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.
--pkey-onlyResults should contain primary key attribute only (“id”)

subid-mod

Usage: ipa [global-options] subid-mod ID [options]

Modify a subordinate id.

Arguments

ArgumentRequiredDescription
IDyesUnique ID

Options

OptionDescription
--desc DESCSubordinate id description
--setattr SETATTRSet an attribute to a name/value pair. Format is attr=value.
--addattr ADDATTRAdd an attribute/value pair. Format is attr=value. The attribute
--delattr DELATTRDelete an attribute/value pair. The option will be evaluated
--rightsDisplay the access rights of this entry (requires —all). See ipa man page for details.
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.

subid-show

Usage: ipa [global-options] subid-show ID [options]

Display information about a subordinate id.

Arguments

ArgumentRequiredDescription
IDyesUnique ID

Options

OptionDescription
--rightsDisplay the access rights of this entry (requires —all). See ipa man page for details.
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.

subid-stats

Usage: ipa [global-options] subid-stats [options]

Subordinate id statistics

Options

OptionDescription
--allRetrieve and print all attributes from the server. Affects command output.
--rawPrint entries as stored on the server. Only affects output format.

Related Topics