4.3 The authd Path

For any identity other than SYSTEM, the token comes from authd. peinit does not resolve identities, does not know whether a principal is local or from a domain, and does not want to: routing is authd's whole purpose.

The division is not that peinit lacks the privilege to mint — it plainly has it, and uses it for the SYSTEM path (§4.2). It is that the privilege set and integrity level an identity carries are policy, and policy is authd's. A second component deciding it in parallel is a disagreement waiting to happen, and peinit has already shipped one: its hand-written privilege bit table had four wrong entries, silently stripping privileges a service had asked to keep.

4.3.1 The request #

peinit sends a ServiceAttest on /run/logon.sock, specified as PGSS Logon §2.19. It carries two strings:

FieldValue
identityThe definition's Identity value, verbatim
serviceThe name of the service being started

authd answers with AccessGranted carrying the token as an SCM_RIGHTS descriptor, or AccessDenied. There is no credential exchange, because a service identity has no credential and must never acquire one — a machine that could authenticate its own services unattended would have to hold their secrets.

authd derives the per-service SID from service and adds it to the token, so the SID that distinguishes one service from another comes from the authority on this path rather than from peinit (§4.4). Note that authd cannot verify service: the process it names does not exist yet, so there is no token to interrogate. peinit is trusted on it, which is the reason for the restriction below.

4.3.2 This request must come from PID 1 #

authd authorises a ServiceAttest on two facts: that the peer's token names SYSTEM, and that the peer is PID 1. The second is not redundant. SYSTEM alone is every platform daemon on the machine, so without it, compromising any one of them would yield a token for any service identity authd would mint.

That makes it a standing constraint on this crate: the connection is opened by peinit's own process and must never be opened by a forked helper. Nothing in the code enforces it. If it is ever broken the symptom is every non-SYSTEM service failing to start at boot with an authorisation error, which reads like a fault in authd rather than like a refactor.

4.3.3 The token is weaker than a user's, deliberately #

An attested token is minted one rung lower on the impersonation ratchet than a credentialled logon: Impersonation rather than Delegation.

The evidence behind it does not travel. A credential a principal source verified is something another machine could in principle have checked too; peinit's word is evidence on this machine only. A service token that could be forwarded off the box on the strength of it would let one system's PID 1 act as an arbitrary account on another.

Because the level is a ratchet, nothing derived from a service's token can exceed it either.

4.3.4 Failure is a failure #

Every non-SYSTEM service start depends on authd being reachable, and every one of them fails if it is not. Only services using the SYSTEM path are unaffected; platform services such as eventd and lpsd use the authority too.

peinit orders around that dependency rather than merely suffering it. The authority declares Provides = ["authn"], and peinit derives a hard dependency on whoever fills that role for every service whose Identity — or whose HookIdentity, where it has hooks — is not SYSTEM (§7.6). Nothing is written on the consumer side: the edge comes from the same field that creates the requirement, so a new service cannot forget it.

Until that existed the ordering was left to each definition, and all three LocalService definitions in the tree omitted it — so a service needing a token routinely reached this code before the socket was bound and failed its launch with ENOENT, on most boots, recovering only through its restart policy.

This is the intended behaviour rather than a limitation. The client that preceded it returned a freshly minted SYSTEM token whenever it could not do better, so a service declaring LocalService ran with peinit's entire privilege set — and status output reported it as LocalService, which is what kept the problem invisible from outside. A service that does not start is visible; a service running as the wrong principal is not.

summarize_token now refuses to describe a token as an identity it does not carry: where the declared identity predicts a user SID, a token carrying a different one fails the launch rather than being reported under the name that was asked for. It is only checked where the identity predicts a SID — a principal name is authd's to resolve, and peinit has nothing to compare it against.

4.3.5 What may be attested #

authd accepts the platform's own service identities — SYSTEM, LocalService, NetworkService, and the per-service virtual account selected by Service — which no principal source holds and for which no credential could exist.

Anything else must be designated in the principal's own record as usable for a service logon, and until that designation exists authd refuses it. So a definition naming an ordinary principal does not start. That is the property the design exists to guarantee: without it, the service manager would be an oracle that mints a credential-free token for anybody on the machine.

4.3.6 The service’s own virtual account #

Identity=Service asks authd to use the per-service SID (§4.4) as the user SID, as well as including it in the token’s groups. The spelling Service is case-insensitive. Each service name therefore selects a separate virtual account without creating an account in a principal source or enabling a credentialled logon.

The derived groups include Everyone (S-1-1-0), Authenticated Users (S-1-5-11), Local (S-1-2-0), and Service (S-1-5-6), together with the kernel’s per-session logon SID. It does not acquire SYSTEM or LocalService membership. Privileges, integrity, owner and default DACL still come from authd’s policy evaluation; choosing a distinct user SID grants no extra privileges by itself.

With Identity=LocalService, the user SID is the shared S-1-5-19 instead. The service’s own SID remains a group, so ACLs can still distinguish two services that share that account. Use Service when their user identities should also be distinct.

Service takes the same derived hard dependency on the providers of the authn role as other non-SYSTEM identities (§7.6). On the standard platform that provider is authd; an explicit Requires=authd is unnecessary.

4.3.7 The interface is authd's #

peinit speaks the protocol through libauthd, which is its definition, rather than encoding the message itself. A second implementation of a wire format that mints identity is the kind of duplication that fails silently and in the worst place.

Edit this page