id: Check the User and Groups a CI Step Runs As
id prints the effective user and group IDs plus supplementary groups, the first thing to check when a CI step hits permission denied.
Permission errors and Docker volume-ownership mismatches both come down to which UID/GID a step runs as. id answers that in one line, and the numbers, not the names, are what the kernel enforces.
What it does
id shows the user ID (uid), primary group (gid), and the supplementary groups the current process belongs to, by name and number. -u, -g, and -G print just the uid, gid, or group list; -n adds names. The numeric UID/GID is what file permissions are checked against, which matters across container boundaries where names may not map.
Common usage
id
id -u # numeric uid (0 = root)
id -un # username (like whoami)
id -nG # supplementary group names
stat -c '%u:%g' /workspace # uid:gid that owns a pathOptions
| Flag | What it does |
|---|---|
| (none) | uid, gid, and all groups (names + numbers) |
| -u | Numeric user ID |
| -g | Numeric primary group ID |
| -G | All group IDs |
| -n | Print names instead of numbers (with -u/-g/-G) |
In CI
When a step fails with "Permission denied" on a mounted path, compare id -u to the file owner from stat -c %u <path>: a Docker volume created by root (uid 0) is unwritable by a step running as a non-root user, and vice versa. Many runners execute steps as a non-root user, so a Dockerfile that assumed root will hit ownership errors that id makes obvious.
Common errors in CI
A "Permission denied" or "EACCES" on a bind-mounted directory is almost always a UID mismatch: the directory is owned by a UID that does not exist or is not yours inside the container. id -u plus stat -c %u confirms it; the fix is matching the UID (--user $(id -u):$(id -g) on docker run) or chowning the mount. Group membership added mid-session does not apply until a new login shell.