Files
felhom.eu/documentation/audits/permanent-gate-2026-10-01/EXIT-TEST.md
T
2026-10-01 21:13:27 +02:00

53 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Permanent household gate with family accounts — EXIT TEST (written before the spike ran)
Written 2026-10-01 ~19:30 UTC, before anything below was built or measured. Model: `audits/login-gate-2026-09-29/B/B-VERDICT.md`.
Operator ruling `09` §3 decision 63: option A (extend the box's own gate), measured before any build; the build waits for the
operator's go.
## What is tested
A gate that stands IN FRONT OF an app permanently (not only until its first setup), letting in only members of the
household's family list, each with their OWN login. Apps: **Grimmory** (e-book library; e-readers sync over OPDS / Kobo /
KOReader) and **MeTube** (yt-dlp web UI with NO login of its own — its fit verdict R-767 was "stop: no login at all").
## Venue and method (fences: the spike ships nothing)
- Scratch guest **9202** only, through its traefik (`https://192.168.0.114` + Host). Grimmory and MeTube are started BY HAND
with `docker compose` from throwaway files in `/root/spike/` on 9202 (Grimmory from the held template in
`audits/new-apps-2026-10-01/wip/grimmory/`, MeTube from upstream's image) — never the live catalog, never a release.
- The gate is a **throwaway auth service** on 9202 (a small Go program in a container on `traefik-public`) answering traefik
`forwardAuth`, with a family list of two members, a sign-in page, a session cookie, logout, and a per-visitor lock that
reads the visitor by the SAME rule as controller v0.286 (`clientaddr.go`). Its source is kept in this folder as evidence.
- The tunnel hop is simulated as in Part A (a container at `172.16.253.2`); one outside address on the real tunnel is not
needed for the gate's logic, which is the same code.
- Everything is removed afterwards (containers, files, traefik labels, images).
## Exit items — each PASS or FAIL, measured
1. **A stranger reaches nothing** of Grimmory or MeTube: every path tried (the front page, the API, static files, an unknown
path, MeTube's socket.io websocket upgrade and its download/add API) answers the gate (302 to the sign-in for a browser
GET, 401 otherwise) and never the app. Pass = 0 app answers.
2. **A family member with their OWN login** (not the dashboard password) gets in; the session lasts **days** (cookie
lifetime ≥ 7 days, survives a gate restart); **logout** works (the old cookie is refused afterwards).
3. **A stranger's wrong guesses lock only the stranger**: after N wrong sign-ins from one visitor (through the simulated
tunnel, rotating a forged leftmost address), that visitor is refused; a family member from another address signs in at
once. Pass = both.
4. **Grimmory's e-reader paths** (OPDS, Kobo sync, KOReader sync) work for a faithful `curl` of the client through a per-app
PATH EXCEPTION — and on those paths **the app's own authentication stays in force**: a stranger there meets the app's
own 401 (not the app's data). Pass = the client answers 200 with its own credentials, the stranger 401.
5. **The family login cannot reach the box dashboard**: the gate cookie is host-only to the app host; the dashboard does not
accept it; the family password does not work at the dashboard login.
6. **Cost**, measured: the added time per gated request (ms, gated vs ungated, same request, median of ≥ 50); what happens
while the gate's answerer is DOWN (stop it: the gated app must be refused — closed, not open); the build's cost in
sessions (estimated from the spike's code size and what the controller already has).
## Also answered (in the verdict)
Where family accounts live and who manages them; one sign-in for all gated apps on the domain or per app; how
Radicale/Dawarich-style API clients are excepted; whether MeTube becomes publishable behind it.
## Verdict rule
The spike PASSES only if items 1–5 all pass. Item 6 is a cost, reported, not a pass/fail. A failed item is reported as
measured, with what a build would have to do about it.