Unix-Socket Peer Credentials: Authenticate a Local Device Client at the Correct Boundary

Authenticate a local socket client using kernel-supplied credentials at the boundary your authorization policy actually needs. SO_PEERCRED supplies a connection-related snapshot; it is not a continuously refreshed statement about whoever currently writes each byte. If authority must follow each message, evaluate message credentials and an explicit protocol instead of assuming a connected descriptor permanently identifies one unchanged process.

This guide pins Linux v6.12 credential implementation and Linux man-pages 6.12. Its main case is a connected AF_UNIX stream service. It does not claim the same option works for arbitrary network sockets or every Unix-socket type. No namespace, privilege or security-policy changes were executed.

Separate three admission questions

First ask who may reach the socket endpoint. For pathname sockets, directory and socket permissions contribute to that boundary on Linux; an abstract address does not acquire filesystem permissions merely because its name looks like a path. Endpoint reachability is useful defense, but it does not replace checking the connected peer.

Second ask which kernel identity the selected API reports and when it was captured. Third ask which commands that identity may perform. A locally authenticated maintenance account should not automatically receive every device-control operation. Keep the identity-to-operation mapping in a small, reviewable policy table.

Do not authorize from a UID, PID or username sent as ordinary application payload. Such fields can be useful labels, but they are peer claims. Match policy to verified credential information and retain a connection generation so decisions cannot accidentally migrate to a reused descriptor.

A timeline separates connection-time credential capture, later privilege or descriptor changes and the command-level authorization decision, highlighting snapshot versus message attribution.
Original admission-boundary model. A stored peer identity does not continuously authenticate every later holder of the socket.

Understand the SO_PEERCRED snapshot

The Unix-socket reference describes credentials associated with connect, listen or socketpair. For the connected stream case, the server observes the client’s connection-time identity, while the client-side peer information relates to the listening endpoint. A socket pair records the creating context. Calling getsockopt again later does not turn that stored snapshot into a live credential lookup.

The v6.12 Unix-socket implementation stores credential and process references during connection setup and copies the listening endpoint’s peer credential record to the connecting socket. This is a concrete reason to establish the service’s privilege state before the relevant socket lifecycle boundary, rather than relying on a later privilege drop to rewrite old peer records.

Use a full struct ucred buffer, initialize its length and verify the returned size and syscall result. Missing or malformed results must not become a zero-initialized “root” identity. The returned structure provides PID, UID and GID; it is not a complete list of supplementary groups or application roles.

Interpret identities in the receiving namespace

The v6.12 socket option implementation converts stored effective UID and GID into the caller’s current user namespace and reports the PID through the relevant PID-namespace view. Therefore raw numbers should be interpreted within the service’s configured namespace and mapping context. A UID printed inside a container is not automatically the same authority as the identical number in another namespace.

The user-namespace documentation also describes translation of credentials crossing Unix sockets. Define the service’s policy against its own stable view, and treat unmapped or unexpected identities as explicit denial cases. Do not create an allow rule for a generic overflow identity merely to make namespace tests pass.

PID is useful diagnostic context but not a durable authorization token. Looking up a process later by numeric PID introduces lifecycle and reuse issues. Reading a process name or command line also does not establish that the original peer is still the current holder of the connection.

Account for descriptor inheritance and forwarding

A connected socket can be inherited by a child or passed to another process. The old connection snapshot does not automatically update to describe every later user of that reference. If your admission policy assumes that only the original peer can issue commands, enforce that assumption through the surrounding process and descriptor design or choose a stronger per-request protocol.

For example, a privileged broker might establish a connection and then intentionally hand the descriptor to a less privileged worker. A server that authorizes every later request solely from the original SO_PEERCRED snapshot is authorizing the connection’s retained capability. That may be a valid design, but it must be deliberate and revocable under an explicit lifecycle, not mistaken for fresh caller authentication.

Required boundary Evidence to evaluate
Admit a connection under fixed authority SO_PEERCRED snapshot plus endpoint and descriptor-lifetime policy.
Attribute individual messages SO_PASSCRED/SCM_CREDENTIALS with complete ancillary parsing and message framing.
Authorize a device operation Verified identity mapped to permitted command, state and resource.
Revoke an existing session Explicit server-side session policy; credential snapshots do not provide automatic revocation.

Use message credentials with their actual guarantees

Enabling SO_PASSCRED permits SCM_CREDENTIALS delivery. The documented default includes the sender’s PID, real UID and real GID when the sender supplies no explicit credential message. This differs from the effective-ID conversion used by SO_PEERCRED in the pinned source.

Explicit SCM_CREDENTIALS values are kernel-checked, but suitably privileged senders can supply values outside the ordinary unprivileged restrictions. Do not describe them as cryptographic identity or assume that all supported senders have identical ability to select credentials. Apply the namespace and privilege model that the product actually permits.

For a request-oriented protocol, validate the credential record and reject missing or truncated control information before acting. Bind credentials to the correctly framed request; a stream parser must not reuse one message’s credentials as an unrestricted label for later bytes. Keep this decoder separate from untrusted payload identity fields.

Qualify the lifecycle rather than one happy connection

An executed host check on x86-64 Linux 6.18.44 created a socket pair in one process and verified that SO_PEERCRED matched that creator’s PID and effective IDs. It demonstrates only that local observation. It does not establish privilege-drop behavior, namespace translation, forwarded-socket policy or per-message attribution.

Proposed integration tests cover an allowed and denied local account, connection before and after the intended privilege transition, inherited and explicitly forwarded descriptors, missing message credentials and relevant namespace mappings. Use disposable identities and an approved isolated environment; the article does not prescribe changing production accounts or weakening access controls.

The release artifact should identify the credential API, capture time, namespace view, accepted identities, permitted operations and session-revocation behavior. A successful local connection proves reachability. The policy and lifecycle evidence establish whether that connection is allowed to control the device.

Similar Posts