Files
felhom.eu/REPORT-hub-tokens.md
T

67 lines
3.9 KiB
Markdown

# REPORT — hub v0.153.0: no token sends, mints or reveals a household credential or link (2026-10-15)
`09` §3 decision 252 (operator 13:20) and R-1059 „A" (same day). Design: `05` §17 (read first).
The previous report (hub v0.152.0, access tokens, deploy and CC's switch to its token):
`git show 5d78569b:REPORT-hub-tokens.md`.
## For the operator — plain words
**What I did.** Your ruling (13:20, R-1055 = A) is built. No token can now:
- resend a claim code,
- create a customer,
- edit a customer (the edit can change the household's e-mail),
- create a config from a box's report.
These need you, signed in with the browser. Three were already password-only and stay so: the self-bind link, a new
passphrase, binding an appliance. „Customers: write" keeps only block, unblock and geo disable.
**Did it work?** Yes. A new test gives a token with every permission to all seven routes. Each answers 403. The
household's e-mail and passphrase stay the same, and no customer is created. I broke the rule on purpose twice; the
test failed both times. All hub tests pass.
**Off-site (R-1059 = A, same day).** No token can re-issue a household's off-site password or PBS-DR token either.
„Off-site: write" keeps the windows and freeze.
**Is it live?** Yes, since 13:39. With CC's token, for a customer that does not exist, all six routes answered
„403 session only" (the off-site re-issue too, although the token holds „Off-site: write").
**What you do now.**
Nothing for this. Still open from before: change the hub password and delete the `HUB_PW` line.
## The Customers-write routes, checked one by one (`hub/internal/web/routes.go`)
| route | now | reason |
|---|---|---|
| `POST /configs/{id}/claim-resend` | session only | sends a fresh claim code to the household's e-mail |
| `POST /configs/{id}/edit` | session only | can change the household's e-mail; a new e-mail auto-mails the self-bind link |
| `POST /configs/new` | session only | mints the owner passphrase and controller API key; takes the e-mail; mails the self-bind link |
| `POST /customers/{id}/create-config` | session only | mints the owner passphrase and controller API key |
| `POST /customers/{id}/selfbind-link` | session only (since v0.152.0) | mints and mails a self-bind capability link |
| `POST /configs/{id}/regen-password` | session only (since v0.152.0) | mints a new owner passphrase |
| `POST /appliances/{id}/bind` | session only (since v0.152.0) | delivers the household's passphrase to the box that asks |
| `POST /configs/{id}/offsite-reissue` | session only (R-1059) | resets the household's off-site password, stages a fresh one-time secret for the box |
| `POST /configs/{id}/pbsdr-reissue` | session only (R-1059) | re-keys the household's PBS-DR token, stages a fresh one-time secret for the box |
| `POST /customers/{id}/block`, `/unblock`, `/geo/disable` | `customers:write` | no credential, link or e-mail |
The GET forms (`/configs/new`, `/configs/{id}/edit`) stay `customers:read`: they show no passphrase or key (checked in
the templates).
## Proof
- Test `TestToken_CredentialAndLinkRoutesAreSessionOnly` (`hub/internal/web/tokens_test.go`).
- Red-proofs: claim-resend put back in the group → the handler was reached (502, no claim engine in the test);
edit put back → 200; offsite-reissue put back → the handler was reached (502). Files:
`documentation/audits/hub-tokens-2026-10-15/red-proof/13-claim-resend.txt`, `14-config-edit.txt`, `15-offsite-reissue.txt`.
- `go build ./... && go vet ./... && go test ./...` in `hub/` → rc 0.
## Records
`09` §3 decision 252; `05` §17.2, §17.3, §17.5; hub CHANGELOG v0.153.0; STATUS.
Register: before 157 · after 156 · opened 1 (R-1059, off-site re-issue) · closed 2 (R-1055, R-1059).
## Teardown
Machine and host: nothing provisioned. Hub: v0.153.0 deployed (manifest `1dc1a08`); live probes used a customer id
that does not exist, so a broken guard could change nothing real. Evidence: `audits/hub-tokens-2026-10-15/C153-live.txt`.