Commit 57b76e0
committed
docs(container): close out ADR-T-009 with Phase 9 audit & docs (ADR-T-009 Phase 9)
Land Phase 9 of ADR-T-009 by wiring the documentation,
audit-trail, and CI guards that turn the preceding eight
phases into a defended baseline. With this commit the ADR
flips from "Proposed" to "Implemented (Phases 1–9 complete)"
and the implementation-plan tracker marks every phase as
Done. There are no behavioural changes to the running
application; everything here is enforcement scaffolding,
operator-facing prose, and the matching test/sample-file
fallout.
CI guards (`.github/workflows/container.yaml`):
- New `lints` job (Container infra) gating the existing
`test` matrix via `needs: lints`. Three independent
audits run before any image is built:
- `compose-baseline-no-mailcatcher` strips `# …` comments
from `compose.yaml` (preserving line numbers via `awk`
so error annotations point at the real source line)
and greps the result for
`mailcatcher|MAILER|SMTP|smtp_`. The override file is
deliberately excluded — it is *expected* to mention
`mailcatcher` — and the comment-stripping prevents the
explanatory header in `compose.yaml` from tripping the
audit. Re-introducing the dev mail sidecar into the
production-shaped baseline now fails the build with a
`::error file=compose.yaml::…` annotation referencing
ADR-T-009 §8.1 / §9.1.3.
- `su-exec-audit` parses the most recent `SHA-256:` line
from the `## Audit Log` section of
`contrib/dev-tools/su-exec/AUDIT.md` and compares it
to `sha256sum contrib/dev-tools/su-exec/su-exec.c`.
Any drift (file changed without a matching audit
entry, or audit entry missing) fails the build with a
pointer to ADR-T-009 §9.2 and the exact append-required
SHA. Reviewer-discretionary drift is no longer
possible.
- `entry-env-docs` parses the
`# ENTRY_ENV_VARS:` … `# END_ENTRY_ENV_VARS` manifest
block in `share/container/entry_script_sh` and asserts
that every variable listed appears somewhere in
`docs/containers.md`. Also asserts that
`compose.override.yaml` is mentioned. Adding an env
var to the entry script without documenting it now
fails the build (ADR-T-009 §9 / Acceptance Criterion
#7).
Vendoring audit (`contrib/dev-tools/su-exec/AUDIT.md`, new):
- Records provenance (upstream `ncopa/su-exec`, MIT,
vendored 2023-10-14 in repo commit `1f5351db`),
initial SHA-256, and the choice rationale against
`gosu`/`setpriv`/`su`/`runuser` (binary size on
distroless, dependency footprint, and PID-1/signal
preservation respectively).
- Documents the two re-audit triggers — file-change
(automated, the CI guard above) and CVE (manual) —
and explicitly rejects a calendar trigger per
ADR-T-009 §D8: static frozen C with a finite review
surface does not decay with time.
- Opens the append-only `## Audit Log` with the
2026-04-21 initial-audit entry: full read-through
against upstream, byte-identical, no shell/network/
signal/env surprises, no findings. The entry ends
with the structured `SHA-256:` line the CI guard
parses.
Entry-script manifest
(`share/container/entry_script_sh`):
- New canonical `# ENTRY_ENV_VARS:` … `# END_ENTRY_ENV_VARS`
block at the top of the script enumerates every env
var the script consults — including the dynamically
constructed `AUTH__{PRIVATE,PUBLIC}_KEY_{PEM,PATH}`
names that a naive grep of `${...}` expansions would
miss. This is the single source of truth the CI lint
reads; the docs/env-table is the consumer.
Shipped-config consolidation
(`share/default/config/`):
- Drop the `.{mysql,sqlite3}.toml` suffix split for the
container-shipped defaults now that Phase 5 made
`database.connect_url` mandatory (the file no longer
encodes a driver choice). Two pairs collapse into
single files:
- `index.container.{mysql,sqlite3}.toml` →
`index.container.toml` (the `mysql` variant was
already the canonical content; the `sqlite3` variant
is removed).
- `index.public.e2e.container.{mysql,sqlite3}.toml` →
`index.public.e2e.container.toml` (kept the more
explicit `listed = false` / `private = false`
settings from the sqlite variant for clarity).
- `index.private.e2e.container.sqlite3.toml` and
`index.development.sqlite3.toml` lose their now-empty
`[auth]` stanza (auth keys are never seeded from the
shipped TOML — they come from the entry script's
defaults or operator overrides). The development
template additionally moves `[net.tls]` above
`[tracker]` to keep all top-level sections grouped.
- `packages/index-config/tests/shipped_samples.rs`
follows the rename in lockstep so the samples remain
exercised by the loader's parse + validate pipeline.
- All four e2e runner scripts under
`contrib/dev-tools/container/e2e/{mysql,sqlite/mode/public}/`
point at the unified file names.
Operator docs:
- `docs/containers.md` gains:
- a "Test-Stage Gate" section documenting the
Containerfile's `test` / `test_debug` build-time
test stages, the deliberate absence of a
`--skip-tests` escape hatch, and the supported
`#[ignore]`-then-fix escalation path. Backlinked
to ADR-T-009 §D9.
- a `TZ` row in the env-var table covering the
Containerfile's pass-through default of `Etc/UTC`.
- a pointer at the entry-script manifest block,
explaining the CI contract that keeps the table
and the manifest in sync.
- prose updates reflecting the single
`index.container.toml` default (no more
`{sqlite3,mysql}` split).
- `README.md`:
- Container quickstart blocks now show the two
mandatory overrides (`TRACKER__TOKEN`,
`DATABASE__CONNECT_URL`) so a copy-paste
`docker run` / `podman run` succeeds against the
Phase 5 schema. A leading note explains *why* a
bare invocation now fails, with a link to
ADR-T-009 §D2.
- New "Compose (development sandbox)" subsection
introducing `make up-dev` / `make up-prod` and
pointing at the Compose Split docs section.
- The ADR-T-009 entry in the "Architecture Decision
Records" list is rewritten to match the
actually-landed scope (runtime base split, three
helper crates, mandatory schema fields, Compose
split, vendored-`su-exec` audit) rather than the
earlier "hardening" framing.
- `CHANGELOG.md`:
- Expands the ADR-T-009 entry under `Added` to
summarise Phases 1–9 in operator-visible terms
(runtime image split with the
`0700`/`0500 root:root` posture on the lean
toolset, three extracted helper crates including
their renames from the old `health_check` /
`torrust-generate-auth-keypair` names, the
Compose split with the two `make` wrappers, and
the new vendoring audit + CI guard).
- Three new **BREAKING** entries under `Changed`
spelling out the operator-facing migrations:
mandatory `database.connect_url` /
`tracker.token` (with the precise override env-var
names), the PEM/PATH mutual-exclusion contract on
auth keys (D3), and the narrowed scope of
`TORRUST_INDEX_DATABASE_DRIVER` as a first-boot
TOML selector only (no longer a runtime database
dispatcher).
ADR & implementation plan:
- `adr/009-container-infrastructure-refactor.md`
status flips from "Proposed" to "Implemented
(Phases 1–9 complete)".
- `adr/009-implementation-plan.md` marks Phase 9 as
Done, and corrects the §9 changelog-prose template:
the `[net.tsl]` → `[net.tls]` wire-key rename was
already logged at Phase 3 (config-crate extraction)
and must not be re-stated under the Phase 9 summary
bullet. The plan now calls this out inline so a
future re-reader does not duplicate the entry.
Repo housekeeping:
- `AGENTS.md` reorders the helper-crate enumeration
(`index-cli-common` to the end of the list) so the
three Phase-2/6 helpers cluster together. No
behavioural meaning — the share-the-`T-`-prefix rule
is unchanged.
Refs: ADR-T-009 §D8, §D9, §9.1 parent d8b6ad2 commit 57b76e0
22 files changed
Lines changed: 421 additions & 105 deletions
File tree
- .github/workflows
- adr
- contrib/dev-tools
- container/e2e
- mysql
- sqlite
- mode/public
- su-exec
- docs
- packages/index-config/tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
18 | 99 | | |
19 | 100 | | |
| 101 | + | |
20 | 102 | | |
21 | 103 | | |
22 | 104 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
84 | | - | |
| 83 | + | |
| 84 | + | |
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
13 | 41 | | |
14 | 42 | | |
15 | 43 | | |
| |||
188 | 216 | | |
189 | 217 | | |
190 | 218 | | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
191 | 242 | | |
192 | 243 | | |
193 | 244 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
35 | 41 | | |
36 | 42 | | |
37 | 43 | | |
38 | 44 | | |
39 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
40 | 49 | | |
41 | 50 | | |
42 | 51 | | |
43 | 52 | | |
44 | 53 | | |
45 | 54 | | |
46 | 55 | | |
47 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
48 | 60 | | |
49 | 61 | | |
50 | 62 | | |
51 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
52 | 84 | | |
53 | 85 | | |
54 | 86 | | |
| |||
144 | 176 | | |
145 | 177 | | |
146 | 178 | | |
147 | | - | |
| 179 | + | |
148 | 180 | | |
149 | 181 | | |
150 | 182 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
| 25 | + | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| |||
2661 | 2661 | | |
2662 | 2662 | | |
2663 | 2663 | | |
2664 | | - | |
2665 | | - | |
2666 | | - | |
| 2664 | + | |
2667 | 2665 | | |
2668 | 2666 | | |
2669 | 2667 | | |
2670 | 2668 | | |
| 2669 | + | |
| 2670 | + | |
| 2671 | + | |
| 2672 | + | |
| 2673 | + | |
2671 | 2674 | | |
2672 | 2675 | | |
2673 | 2676 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
0 commit comments