docs: document /data/setup-token and close phase 14
14.C needed no code: the setup link is already mirrored to /data/setup-token at 0600 and removed once setup completes. What was missing is the reason to prefer it — a deployment whose container logs ship to a central aggregator otherwise leaves a live bearer token in that pipeline for ten minutes, and in whatever retains it afterwards. The reverse-proxy section gains the one requirement 14.A introduces: pass the original Host header through. Everything else about security stays the proxy's non-problem, which is the point of emitting the headers from the panel. Phase 14 leaves the plan (the file describes only unfinished work), but its section A keeps what was deliberately left open: the accepted risk for clients sending neither Sec-Fetch-Site nor Origin, the decision not to add session-bound CSRF tokens and what would justify revisiting it, and the fact that XSS inside the panel's own origin is answered by html/template and the CSP rather than by either of those. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,17 @@ open it to create the admin account. That username and password can be changed
|
||||
later from the panel's *Account* page (changing the password signs out every
|
||||
other session).
|
||||
|
||||
The same link is also written to `/data/setup-token` inside the container —
|
||||
`./data/setup-token` on the host, mode `0600` — and deleted the moment setup
|
||||
completes. If this host ships its container logs to a central aggregator,
|
||||
prefer the file: the link is a bearer token valid for ten minutes, and reading
|
||||
it this way keeps it out of the log pipeline (and out of whatever retains it
|
||||
afterwards) entirely.
|
||||
|
||||
```sh
|
||||
docker compose exec selfpost cat /data/setup-token
|
||||
```
|
||||
|
||||
## Reverse proxy (mandatory)
|
||||
|
||||
SelfPost's panel speaks plain HTTP and never terminates TLS itself — a reverse
|
||||
@@ -66,6 +77,17 @@ Apache is the recommended default because the certbot Apache plugin already
|
||||
writes plain `fullchain.pem`/`privkey.pem` files to a predictable path with no
|
||||
extra moving parts between "certificate issued" and "Postfix can read it."
|
||||
|
||||
**The proxy needs no security configuration of its own.** The panel emits its
|
||||
own `Content-Security-Policy`, `Strict-Transport-Security`, `X-Frame-Options`,
|
||||
`X-Content-Type-Options` and `Referrer-Policy` — deliberately, so the part
|
||||
that's easy to get wrong lives in the service rather than in a config file
|
||||
somebody edits under pressure. There is exactly one thing the proxy must do:
|
||||
**pass the original `Host` header through**. All four fragments above already
|
||||
do (Apache `ProxyPreserveHost On`, nginx `proxy_set_header Host $host`, Caddy
|
||||
and Traefik by default). A proxy that rewrites `Host` instead makes the panel
|
||||
reject every form submission as cross-origin — the log says so explicitly,
|
||||
printing the `Origin` and `Host` it compared.
|
||||
|
||||
## DNS setup
|
||||
|
||||
Two different scopes — don't confuse them:
|
||||
|
||||
Reference in New Issue
Block a user