# Self-hosted Subrouter authority S3 — authenticated tailnet edge

**Status:** DONE
**Base:** current landed S2 on `origin/main`

## Scope

Expose the existing singleton authority to one buildbox without changing its loopback listener or introducing provider credentials. The repository-owned edge binds the workstation Tailscale IPv4 address only, resolves approved peer identities from tailscaled state, returns 403 to every unapproved peer before forwarding, and raw-proxies approved streams to `127.0.0.1:31415`.

Initial approved peer: `debian1`. Negative peer: `debian2`. No `debian4` dependency exists.

## Security contract

- Subrouter remains exactly loopback-only on `127.0.0.1:31415`.
- Edge binds one Tailscale CGNAT IPv4 address, never wildcard/LAN/public.
- Tailscale/WireGuard supplies encrypted transport.
- Runtime machine allowlist is resolved from `tailscale status --json`; missing, duplicate, offline, or non-tailnet identities fail closed.
- `debian1` alone is approved for the S3 canary. Any other source receives HTTP 403 before its request reaches Subrouter.
- Exact-route proxy grant remains mandatory after machine admission.
- Edge never reads the authority store or any provider/native credential.
- Edge logs no request URL, Authorization/X-Api-Key value, route ID, grant ID, or provider material.
- Central Tailscale ACL policy is external defense in depth; this slice does not mutate owner tailnet policy.

## Acceptance

1. Buildbox tests cover tailnet identity resolution, fail-closed config, 403-before-upstream behavior, raw approved proxying, immutable install shape, and systemd hardening.
2. Candidate focused/static/module/full gates are green on registered buildboxes.
3. `install-tailnet-edge --allow-host debian1` installs an immutable edge and active hardened systemd unit.
4. Listener is exactly the workstation Tailscale IPv4 on port 31416; no `0.0.0.0`, `::`, LAN, or public bind exists.
5. Create one credentialless exact route and short-lived `audience=buildbox-run` grant through installed local admin CLI. No account credential is created.
6. `debian1`: exact route status with grant returns 200/migration-required; missing key returns 401; same grant against a different route returns 401; remote control-plane paths remain unavailable.
7. `debian2`: the same listener returns 403 before Subrouter route authentication.
8. Revoke/remove grant and route, delete every run-owned grant copy, and prove authority returns to 0 provider credentials/routes/grants/unresolved.
9. Restart edge and authority; both return healthy.

S4 remains blocked until this live credentialless tailnet proof is complete.
## Completion evidence — 2026-08-21

Implementation commit `9145449dd` added the machine-authenticated Tailscale edge and its installer/tests. The cleanup-capable authority patch adds local-only route/grant removal and route-scoped grant purge; canonical patch SHA-256 is `84931d77aaac78be59afd49ada8ddfbd5dcd34014ee505a9fb80e8dc5979970f`.

Buildbox verification on registered workers:

- focused candidate: PASS
- static candidate: PASS
- Python/module contract: 52/52 PASS
- full candidate: PASS
- full pinned upstream Go suite after cleanup CLI additions: PASS on `debian3`

Installed edge release: `6afdd2c43d3dab3eac4477ab036a517861bb09c817993630c2225d1715eff89d`. Live listener proof after restart:

```text
100.126.128.50:31416  overdeck-subrouter-edge
127.0.0.1:31415       overdeck-subrouter authority
```

Live tailnet assertions:

- `debian1`, correct short-lived `audience=buildbox-run` grant: HTTP 200, `state=migration-required`, provider `codex`, account availability `unavailable`.
- `debian1`, missing grant: HTTP 401.
- `debian1`, same grant against a different route: HTTP 401.
- `debian1`, remote `/_subrouter/authority-status`: HTTP 404; no remote admin/control plane exists.
- `debian2`, before Subrouter authentication: edge HTTP 403.
- revocation canary: same `debian1` request changed from HTTP 200 immediately before revoke to HTTP 401 immediately after revoke.

Cleanup used local-only route-scoped grant purge, then route removal. All run-owned workstation/buildbox files were deleted. Final restart proof:

```text
Provider credentials: 0
Authority routes: 0
Proxy grants: 0
Unresolved attempts: 0
Gateway: ready
overdeck-subrouter.service: active/running/success
overdeck-subrouter-edge.service: active/running/success
```

No provider/native credential was read, copied, migrated, repaired, or modified. `zync` remains native/test-only. S4 may proceed.
