SessionAudit.qml — tamper-evident JSONL log of all session state changes: - Lock/unlock, secure/insecure transitions - Idle state machine transitions (active/dimmed/lock/sleep/wake) - PrepareForSleep, external lock signals, inhibitor lifecycle - Step-up auth success/failure, break-glass issued/consumed/expired - Grant expiry and revocation Hash chain: each entry includes md5 of previous entry. Sequence numbers detect gaps. Chain is validated on startup from the last entry. Uses Qt.md5() (not SHA256 — not available in QML). Advisory tamper- evidence, not cryptographic security. Log at: ~/.local/share/souveraine/session-audit.jsonl
3.7 KiB
3.7 KiB
Trust boundary matrix
Every session operation classified by caller type, required auth gate, and current enforcement status. This is the reference for what is gated and what is not — if an operation is not in this matrix, it is not gated.
Legend
| Column | Meaning |
|---|---|
| Operation | The IPC verb or internal action |
| Caller | Who can invoke it |
| Min tier | Minimum capability tier required |
| Gate | What enforces the tier |
| Status | enforced, partial, ungated |
Operations
| Operation | Caller | Min tier | Gate | Status |
|---|---|---|---|---|
session.lock() |
IPC / UI / logind signal | ambient | None (always allowed) | enforced |
session.unlock() |
Credential gate only | stepUp | LockContext PIN/PAM | enforced — IPC refuses |
session.suspend() |
IPC / UI | ambient | capability probe | enforced |
session.hibernate() |
IPC / UI | ambient | capability probe | enforced |
session.poweroff() |
IPC / UI | ambient | capability probe + polkit | enforced |
session.reboot() |
IPC / UI | ambient | capability probe + polkit | enforced |
session.logout() |
IPC / UI | ambient | None | enforced |
session.inhibit("idle") |
IPC / internal | ambient | reason required | enforced |
session.inhibit("sleep") |
IPC / internal | ambient | reason required | enforced |
session.state() |
IPC / agent | ambient | None (read-only projection) | enforced |
session.caps() |
IPC / agent | ambient | None (read-only projection) | enforced |
StepUpAuth.requestAuth() |
UI / agent | ambient | PAM conversation | enforced |
StepUpAuth.isGranted() |
UI / agent | ambient | None (read-only check) | enforced |
StepUpAuth.revokeGrant() |
UI / internal | ambient | None | enforced |
| Agent conversation | Souveraine IPC | ambient | Server auth token | enforced |
| Agent send with personal context | Souveraine IPC | personal | !screenLocked && !screenLockSecure | enforced via LockContentPolicy |
| Agent output on lock surface | Lock surface | ambient | LockContentPolicy.allowsOnLock() | enforced |
| In-flight agent response on lock | Lock surface | personal | Ai.qml redacts on screenLocked | enforced |
| Media metadata on lock surface | Lock surface | ambient (if opted) | LockContentPolicy.mediaMetadataAmbient | enforced |
| Media transport controls | Lock surface | ambient | LockContentPolicy.mediaControlsVisible | enforced |
| Lock screen power actions | Lock surface | ambient | Config.lock.security.requirePasswordToPower | enforced |
| Idle state transition | IdleCoordinator | ambient | nativeEnabled config | enforced |
| Sleep/suspend transition | SessionEvents | ambient | delay inhibitor + WlSessionLock.secure | enforced |
| Session audit trail | SessionAudit | ambient | append-only JSONL with hash chain | enforced |
Not yet gated (gaps)
| Operation | Caller | Required tier | Gap |
|---|---|---|---|
| Agent delete/push operations | Souveraine IPC | stepUp | StepUpAuth built but minTier metadata not wired |
| Agent physical access | Souveraine IPC | stepUp | StepUpAuth built but minTier metadata not wired |
| Break-glass override | Emergency | scoped grant | Done (StepUpAuth.breakGlass) |
| Boot-time IPC audit | Shell startup | ambient | Done (log in Session.qml) |
Notes
- The matrix is local-only: all callers are on the same machine, reachable only over quickshell's IPC socket by the user who owns the session.
- If a network-reachable caller is ever added, every row needs re-evaluation.
- The
personaltier gate is!screenLocked && !screenLockSecure— the session must not be locked and the compositor must not have secured the lock surface. This is a live check, not a cached bool. - The
stepUptier requires a recent (TTL-window) StepUpAuth grant for the relevant action family.