Credential Projection
KACS tokens are the sole identity-based authorization mechanism. Linux applications do not know tokens exist — they call getuid(), getgid(), getgroups(), read /proc/self/status, and assume the numbers they see determine their access rights. KACS projects token identity onto standard Linux credentials so unmodified applications function normally.
When a KACS token is installed on a process, the process's Linux credentials are set to match:
- The token's user SID maps to a UID via the directory's
uidNumberattribute. If nouidNumberis set, the UID defaults to 65534 (nobody). No algorithmic mapping. - The token's primary group SID maps to a GID via the directory's
gidNumberattribute, with the same fallback. - The token's group SIDs map to supplementary GIDs where
gidNumberattributes exist. getuid(),getgid(),getgroups()return these projected values./proc/<pid>/statusreflects them.
§12.1.1 Consequences
- Under normal token projection, no process runs as UID 0 unless it holds the SYSTEM token (
S-1-5-18). - Home directories work naturally —
getpwuid(getuid())returns the correct home directory because the UID is real and consistent with NSS/LDAP. - Different services get different UIDs, providing incidental defense-in-depth alongside KACS enforcement.
§12.1.2 Projection is one-way
Token state flows into credential fields, never the reverse. The projected credentials are observational compatibility data; the token is the authority.
Projection reflects all groups regardless of their enabled/disabled state — AdjustGroups MUST NOT trigger projection recalculation.
Projected credentials reflect the effective token — which is the impersonated token during impersonation, or the primary token otherwise. When a service thread impersonates a client and creates a file, the file is owned by the client's projected UID, quotas are charged to the client, and audit is attributed to the client. This matches the Windows model where the impersonation token governs all operations during impersonation.
The current_fsuid() patch reads the projected UID from current->cred (the effective credential), which carries the effective token. During impersonation, this is the impersonated token's projected UID. After kacs_revert, it returns to the primary token's projected UID.
getuid() reads current->real_cred->uid (the primary credential's UID), which is always the primary token's projected UID regardless of impersonation. This means during impersonation: getuid() returns the service's UID, current_fsuid() returns the client's UID. This is the correct and intended behavior.
uid0 utility (see the setuid section) explicitly overrides cred->uid to 0 for legacy compatibility. In that case, getuid() returns 0 rather than the projected UID. current_fsuid() still returns the projected UID from the effective token — uid0 affects the Linux credential fields but not the KACS projection path.§12.1.3 Projected UIDs
Every token carries pre-computed projected UID/GID values, computed by authd at token creation time and stored on the token. KACS MUST NOT resolve SID-to-UID mappings at runtime.
uidNumber/gidNumber values from a single unified counter across all principal types. This ensures every SID projects to a unique number regardless of which Linux namespace it lands in.