gates / gates (push) Successful in 8m49s
Closed R-971, R-954, R-1124, R-1012 (174 -> 175 rows); opened R-1139..R-1143; R-895 READY with the design and hub slice 1; R-972 waits on the vouch. [DESIGN] "The catalog allow-list" in 02; the catalog trust line in 01; FELHOM_THINCHECK and unit-forget in 03. Evidence audits/agent-allowlist-rotation-2026-10-17/. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
37 lines
2.5 KiB
Markdown
37 lines
2.5 KiB
Markdown
# R-971 survey — every container right the catalog asks for (2026-10-17)
|
|
|
|
Catalog `app-catalog-felhom.eu` at `1af6ea7` (the survey) and `d5a443d` (the gate). **123 files: 65 `templates/<app>/docker-compose.yml`
|
|
and 58 ladder `steps/*.yml`.** Read with PyYAML (`survey-raw.txt`, the raw scan) and again with the controller's own
|
|
check (`privpolicy.Check` on the placeholder env, the test `TestAllowList_TheWholeCatalogPasses`).
|
|
|
|
Classes looked for: `privileged`, `cap_add`, `devices`, `device_cgroup_rules`, `network_mode`, `pid`, `ipc`, `uts`,
|
|
`userns_mode`, `cgroup`, `security_opt`, `sysctls`, `volumes_from`, `build`, `include`, `extends`, `env_file`, top-level
|
|
volumes with `driver`/`driver_opts`/`external`/`name`, `configs`/`secrets` with `file:`, and every bind source.
|
|
|
|
## The allow-list (what the catalog needs)
|
|
|
|
| app | service | setting | why the app needs it | upstream doc |
|
|
|---|---|---|---|---|
|
|
| homepage | homepage | `bind /var/run/docker.sock -> /var/run/docker.sock ro` | the Docker widget and Docker service discovery list the household's containers and their state | https://gethomepage.dev/configs/docker/ |
|
|
|
|
That is the whole list. **No template or step asks for any other class member.** Note (security review C5-5, R-782): a
|
|
read-only socket mount does not limit the Docker API; the entry keeps today's behaviour, it does not bless it — a
|
|
read-only socket proxy for homepage stays a separate catalog change.
|
|
|
|
## Seen and NOT a class member (no entry needed)
|
|
|
|
| app | setting | why it passes |
|
|
|---|---|---|
|
|
| audiobookshelf, komga (final + step) | `security_opt: [no-new-privileges:true]` | a hardening, not a relaxation |
|
|
| every bind (35 distinct) | `${HDD_PATH}/…`, `${USERDATA_PATH}/…`, `${IMPORT_PATH}/…` | inside the data roots the box gives |
|
|
| crafty-controller | `ports: 25565-25575` | not in the brief's classes: a published port is LAN reach of the guest, not a right on the host (documented in `01-topology-and-trust.md`) |
|
|
| vikunja | `user: 0:0` | root INSIDE the container; not a host right |
|
|
| karakeep-chrome | `init: true` | a tini init, no privilege |
|
|
| 94 compose files | `networks: traefik-public: external: true` | a network, not a volume; not a class |
|
|
|
|
## The controller's infra stacks (out of scope, stated)
|
|
|
|
traefik (holds the Docker socket at the internet edge), cloudflared, filebrowser and samba (`network_mode: host` for LAN
|
|
discovery) are rendered by the controller from its own code, not the catalog. Since v0.328.0 the sync also refuses to
|
|
copy a catalog template named like one of them into its directory.
|