Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/TRUST-BOUNDARY-MATRIX.md

64 lines
3.7 KiB
Markdown

# 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 `personal` tier 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 `stepUp` tier requires a recent (TTL-window) StepUpAuth grant for the
relevant action family.