docs(auth): document runtime projection operations
This commit is contained in:
@@ -68,3 +68,14 @@ values into tickets, logs, or evidence.
|
||||
|
||||
Check readiness with `tht auth check`; add `--json` for the machine contract. Use
|
||||
`tht doctor --json` for the aggregate installation report.
|
||||
|
||||
## Projected server installations
|
||||
|
||||
This section applies only when a Linux `profile: server` descriptor declares a runtime projection.
|
||||
The canonical authentication root stays root-owned and is the only authority. The container reads
|
||||
only the separate read-only runtime projection selected by `CURRENT`; it never falls back to the
|
||||
canonical files or to a previous generation. Run projected mutations and repairs through the
|
||||
root-operated `tht` commands documented in the [server guide](server.md), and never edit runtime
|
||||
files directly.
|
||||
|
||||
Mac, Windows, and local direct-file authentication remain unchanged when the projection is absent.
|
||||
|
||||
@@ -8,7 +8,13 @@ workspaceRepository:
|
||||
branch: main
|
||||
access: ssh
|
||||
authentication:
|
||||
configDirectory: "/absolute/path/to/thothii-auth"
|
||||
# Root-operated source of truth; it is never mounted into core.
|
||||
configDirectory: "/srv/example/thothii/auth-canonical"
|
||||
runtimeProjection:
|
||||
# The only authentication bind exposed to core by the automatic override.
|
||||
directory: "/srv/example/thothii/auth-runtime"
|
||||
uid: 10001
|
||||
gid: 10001
|
||||
overrides:
|
||||
- "/absolute/path/to/ThothII/deploy/compose.session-server.yaml.example"
|
||||
- "/absolute/path/to/ThothII/deploy/compose.git-ssh.yaml"
|
||||
|
||||
@@ -88,6 +88,73 @@ Expected: the parent is `operator_uid:10001 750`; source/operator are
|
||||
`10001:10001 750`; backups are `0:0 700`. Re-run the empty `getent` checks after creation. Do not
|
||||
make `/srv/thothii` a shared application directory.
|
||||
|
||||
## Projected server authentication: canonical root and runtime projection
|
||||
|
||||
For a server descriptor that declares `authentication.runtimeProjection`, authentication has two
|
||||
different roots. The **canonical authentication root** (`authentication.configDirectory`) is the
|
||||
root-operated source of truth. It and its regular files are `root:root 0700/0600`. The **runtime
|
||||
projection** is a separate Linux-only tree for the container reader: its root, `generations`, and
|
||||
generation directories are `10001:10001 0700`; `CURRENT`, `manifest.json`, `auth.yaml`, and (for
|
||||
local mode) `users.yaml` are `10001:10001 0600`. The publisher assigns the numeric IDs directly;
|
||||
it does not create a host user or group for 10001.
|
||||
|
||||
The runtime projection has only `CURRENT` and `generations/<64-lowercase-hex>/`. `CURRENT` selects
|
||||
one complete immutable generation. A successful configure, user mutation, restore, or explicit
|
||||
publish first blocks `CURRENT`, then verifies a new immutable generation, then makes it ready.
|
||||
The selected generation and up to two predecessor generations are retained; no operator edits a
|
||||
generation or `CURRENT` directly. A ready projection is usable only when its canonical revision is
|
||||
equal to the current canonical authentication root. If the runtime projection is blocked, missing,
|
||||
tampered, or unequal, `start`, `update --check-only`, `auth check`, and `doctor` fail closed before
|
||||
admission or Compose lifecycle work.
|
||||
|
||||
The runtime directory must be an absolute canonical path, distinct from the canonical root, and
|
||||
must exactly equal `THT_AUTH_RUNTIME_ROOT` in the protected installation environment. The server
|
||||
profile and numeric UID/GID values are validated before any projected mutation or publication.
|
||||
|
||||
The descriptor loader adds `compose.auth-runtime-projection.yaml` automatically when
|
||||
`runtimeProjection` is present; do not list that file under `overrides`. The automatic override
|
||||
mounts the runtime projection **read-only and core-only** at `/run/thothii-auth`; the canonical
|
||||
authentication root is never mounted. No other service receives that mount or
|
||||
`THT_AUTH_RUNTIME_PROJECTION_ROOT`. The example descriptor uses
|
||||
`/srv/example/thothii/auth-runtime` only as a replaceable path and contains no credential value.
|
||||
|
||||
This source change is prepared and tested only: Project A has not been started. It does not
|
||||
authorize a raw Compose lifecycle launch, an Nginx change, legacy-stack change, or mutation of
|
||||
`/srv`. A later manual gate needs separate explicit authorization before applying any descriptor
|
||||
or runtime root to a server.
|
||||
|
||||
### Status, repair, and safe evidence
|
||||
|
||||
Use the root-operated installation command; retain only its small redacted JSON result:
|
||||
|
||||
```sh
|
||||
sudo tht --installation "$INSTALLATION" auth status --json
|
||||
```
|
||||
|
||||
`state: "ready"` and `equal: true` are required before a projected server can start. `state:
|
||||
"blocked"`, `equal: false`, or a command refusal means that the runtime projection is blocked or
|
||||
cannot be validated. Do not start the stack, inspect YAML, print an environment, or edit `CURRENT`
|
||||
or a generation. Confirm the protected canonical root is available, then republish it with:
|
||||
|
||||
```sh
|
||||
sudo tht --installation "$INSTALLATION" auth publish
|
||||
sudo tht --installation "$INSTALLATION" auth status --json
|
||||
```
|
||||
|
||||
`auth publish` reconstructs the selected immutable generation from the canonical root; it never
|
||||
uses an older runtime generation as authority. If publish fails, leave the projection blocked and
|
||||
escalate using the sanitized command result plus descriptor path and timestamp only. Do not attach
|
||||
passwords, hashes, YAML, raw environment output, `nginx -T`, or a secret-bearing diff to evidence.
|
||||
|
||||
### Authentication restore
|
||||
|
||||
An authentication-bearing restore first publishes a blocked selector, restores canonical
|
||||
authentication, and publishes a verified candidate generation before any restart. If candidate or
|
||||
recovery verification fails, the verified recovery checkpoint is republished when possible; an
|
||||
unverified result remains blocked and prevents start. A restore without authentication entries
|
||||
does not touch the runtime projection. This is in addition to the normal restore requirement that
|
||||
browser sessions and pending OIDC state are cleared.
|
||||
|
||||
## Firewall and network boundaries
|
||||
|
||||
Set `THOTH_SERVER_BIND=127.0.0.1`. Permit inbound TCP 80/443 only to the TLS proxy; port 80 should
|
||||
|
||||
@@ -251,6 +251,14 @@ Use `profile: server`, the exact new source root/env/auth root, workspace remote
|
||||
access, Project A override, and exactly one Git transport override. Do not include the public
|
||||
session-server overlay in Project A.
|
||||
|
||||
For the projected local-auth descriptor, keep `authentication.configDirectory` as the canonical
|
||||
root and add `runtimeProjection` with a distinct absolute runtime directory plus numeric `uid: 10001`
|
||||
and `gid: 10001`. The descriptor loader includes the automatic runtime-projection override; do
|
||||
not list it manually under `overrides`. The canonical root stays `root:root 0700/0600`; the
|
||||
publisher owns the projection numerically as `10001:10001 0700/0600`. Only the projection is
|
||||
mounted read-only into core. Do not create a host user/group, edit `CURRENT` or `generations`, or
|
||||
apply these paths before the separately authorized start gate.
|
||||
|
||||
**Step 4: Validate permissions and render**
|
||||
|
||||
```bash
|
||||
@@ -274,6 +282,11 @@ Create a temporary mode-0600 password file using an echo-free prompt, then run:
|
||||
Remove the temporary input file after success and record that removal. Do not delete generated
|
||||
`auth.yaml` or `users.yaml`.
|
||||
|
||||
Before the later start gate, run the redacted projected status command and require `ready` plus
|
||||
`equal: true`. A blocked result prevents start. `auth publish` is the only repair path: it rebuilds
|
||||
from canonical authentication, including after a candidate or recovery restore outcome; it never
|
||||
promotes a retained runtime generation on its own.
|
||||
|
||||
### Task 6: Build and start the clean stack
|
||||
|
||||
**Files:**
|
||||
|
||||
@@ -35,6 +35,13 @@ than inferring a PASS.
|
||||
4. Confirm the exact direct `groups` claim for both identities and the mappings `TOT Users → user`
|
||||
and `TOT Admin → admin`. Confirm extra upstream groups are ignored without warning.
|
||||
|
||||
5. For a projected Linux server, before any start gate, collect only the redacted result of
|
||||
`sudo tht --installation "$INSTALLATION" auth status --json`. Record `state`, generation,
|
||||
canonical revision, and `equal`; do not retain authentication YAML, user records, hashes, or
|
||||
environment output. `ready` plus `equal: true` is required. A blocked or unequal result is a
|
||||
fail-closed condition: do not start, and use `sudo tht --installation "$INSTALLATION" auth
|
||||
publish` followed by the same status command only after the canonical root is available.
|
||||
|
||||
## Matrix
|
||||
|
||||
| Scenario | Expected result |
|
||||
@@ -56,6 +63,7 @@ than inferring a PASS.
|
||||
| Logout | Cookie expires and the server session is deleted. |
|
||||
| Provider outage | Live check reports `oidc_discovery_unreachable`; browser login fails closed without exposing credentials. |
|
||||
| Restore is completed | Sessions and OIDC state are absent; all users must reauthenticate. |
|
||||
| Projected authentication restore | Candidate generation and any recovery generation are published from the canonical root; a failed verification remains blocked and start is refused. |
|
||||
|
||||
## Status at Task 15
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@ verdi installazione, workspace, DWH, Qdrant, Ollama e preprocessing.
|
||||
|
||||
## 1. Stato generale
|
||||
|
||||
Prima del gate manuale di avvio, per una descriptor server con runtime projection eseguire solo il
|
||||
controllo redatto `sudo tht --installation "$INSTALLATION" auth status --json`. Il risultato deve
|
||||
dire `ready` ed `equal: true`. Se è `blocked`, mancante o diverso dal canonical root, non avviare:
|
||||
Sol può eseguire `sudo tht --installation "$INSTALLATION" auth publish` e ripetere il controllo,
|
||||
senza copiare YAML, hash, password, token o environment nel rapporto. Questo documento non
|
||||
autorizza l'avvio; Project A resta soggetto a un'esplicita autorizzazione separata.
|
||||
|
||||
Eseguire:
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user