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.
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:
- Queries user’s subordinate range from IPA via SSSD
- Creates a user namespace mapping container UIDs/GIDs to the subordinate range
- Starts the container with remapped UIDs/GIDs
- 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-generateAuto-assign a subordinate id range to user alice:
ipa subid-generate --owner=aliceFind subordinate ids for user alice:
ipa subid-find --owner=aliceMatch 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
| Option | Description |
|---|---|
--id ID | Unique ID |
--desc DESC | Subordinate id description |
--owner OWNER | Owning user of subordinate id entry |
--subuid SUBUID | Start value for subordinate user ID (subuid) range |
--subgid SUBGID | Start value for subordinate group ID (subgid) range |
--timelimit TIMELIMIT | Time limit of search in seconds (0 is unlimited) |
--sizelimit SIZELIMIT | Maximum number of entries returned (0 is unlimited) |
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print entries as stored on the server. Only affects output format. |
--pkey-only | Results 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
| Option | Description |
|---|---|
--owner OWNER | Owning user of subordinate id entry |
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print 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
| Option | Description |
|---|---|
--subuid SUBUID | Match value for subordinate user ID |
--timelimit TIMELIMIT | Time limit of search in seconds (0 is unlimited) |
--sizelimit SIZELIMIT | Maximum number of entries returned (0 is unlimited) |
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print entries as stored on the server. Only affects output format. |
--pkey-only | Results should contain primary key attribute only (“id”) |
subid-mod
Usage: ipa [global-options] subid-mod ID [options]
Modify a subordinate id.
Arguments
| Argument | Required | Description |
|---|---|---|
ID | yes | Unique ID |
Options
| Option | Description |
|---|---|
--desc DESC | Subordinate id description |
--setattr SETATTR | Set an attribute to a name/value pair. Format is attr=value. |
--addattr ADDATTR | Add an attribute/value pair. Format is attr=value. The attribute |
--delattr DELATTR | Delete an attribute/value pair. The option will be evaluated |
--rights | Display the access rights of this entry (requires —all). See ipa man page for details. |
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print 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
| Argument | Required | Description |
|---|---|---|
ID | yes | Unique ID |
Options
| Option | Description |
|---|---|
--rights | Display the access rights of this entry (requires —all). See ipa man page for details. |
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print entries as stored on the server. Only affects output format. |
subid-stats
Usage: ipa [global-options] subid-stats [options]
Subordinate id statistics
Options
| Option | Description |
|---|---|
--all | Retrieve and print all attributes from the server. Affects command output. |
--raw | Print entries as stored on the server. Only affects output format. |