RequestPrincipal
Who the gate let in, read from the request — never from a cookie, never from a session store. A gate that authenticates (app-runtime's `PasskeyGateMiddleware`, or anything built on `milpa/auth`'s `AuthenticateMiddleware`) leaves its verdict on the request under the attribute `milpa.auth`: an `AuthContext` — `isAuthenticated()`, and a public `actor` whose public `id` is the principal. The panel takes no dependency on `milpa/auth`, so it reads that shape by duck-typing, and fails closed: no attribute, a non-object, a context that does not say it is authenticated, an actor without a non-empty string id — each is «nobody», and the topbar shows no chip. What comes back is the ACTOR's id (`passkey:…`), never a session id: the session is the gate's, and the panel never sees it (greenhouse decisions/0206). The reader never calls what it cannot: a member answered by a method is read only when that method is public and needs no argument, and a call that throws reads as nobody — a foreign context is read, never trusted to behave.
RequestPrincipal::of()
public static function of(Psr\Http\Message\ServerRequestInterface $request): ?stringThe authenticated actor's id, or null when the request carries no authenticated context.
Parameters
| Name | Type | Description |
|---|---|---|
| $request | Psr\Http\Message\ServerRequestInterface |
RequestPrincipal::identity()
public static function identity(Psr\Http\Message\ServerRequestInterface $request): arrayThe identity authenticated for this request, with its declared scopes when readable. Null scopes mean unavailable; an empty list means the actor declared none. Neither grants authority, and no roles, claims, cookies or query parameters are used to invent scopes.
Parameters
| Name | Type | Description |
|---|---|---|
| $request | Psr\Http\Message\ServerRequestInterface |