64 lines
3.4 KiB
Markdown
64 lines
3.4 KiB
Markdown
|
|
# Verify — netbird_coordinator (NetBird control plane)
|
|||
|
|
|
|||
|
|
> **Authored now, executed later.** This is the acceptance spec for `/verify-service
|
|||
|
|
> netbird_coordinator`. It cannot run yet: it needs the Playwright UI harness (ADR-017)
|
|||
|
|
> **and** a live deploy of this role behind the M4a Caddy on askari. Until both exist,
|
|||
|
|
> treat this as the spec to drive once they do — verification is deferred, not skipped.
|
|||
|
|
|
|||
|
|
NetBird's coordinator does have a real web UI (the dashboard), so this is a genuine
|
|||
|
|
Level-4 UI spec, not just an HTTP/TLS check.
|
|||
|
|
|
|||
|
|
## Critical user journeys
|
|||
|
|
|
|||
|
|
The acceptance criteria — what "working" means. Numbered; action → expected result.
|
|||
|
|
|
|||
|
|
1. **Dashboard loads over a valid LE cert** — request
|
|||
|
|
`https://netbird.askari.wingu.me` → the dashboard SPA renders; the browser shows a
|
|||
|
|
valid Let's Encrypt certificate (trusted chain, SAN matches the host, not expired).
|
|||
|
|
2. **First-boot `/setup` creates the first admin** — on a fresh deploy (zero users),
|
|||
|
|
`https://netbird.askari.wingu.me/setup` is reachable and creating the first admin
|
|||
|
|
account succeeds; re-visiting `/setup` afterwards no longer offers admin creation
|
|||
|
|
(the window self-closes once a user exists).
|
|||
|
|
3. **Login via the embedded Dex IdP succeeds** — logging in with the just-created admin
|
|||
|
|
(OIDC redirect through `/oauth2`, public PKCE client, no client secret) lands on the
|
|||
|
|
dashboard's authenticated home / peers view.
|
|||
|
|
4. **The management API responds behind auth** — an authenticated dashboard session can
|
|||
|
|
list peers / setup keys (the dashboard calls the management REST API at `/api`); an
|
|||
|
|
**unauthenticated** request to `/api/...` is rejected (401/403), confirming the API
|
|||
|
|
is not open.
|
|||
|
|
5. **STUN answers on 3478/udp** — out of band (not browser): a STUN binding request to
|
|||
|
|
`askari:3478/udp` returns a binding response (confirms the host-published UDP port is
|
|||
|
|
live).
|
|||
|
|
|
|||
|
|
## What good looks like
|
|||
|
|
|
|||
|
|
Key states/screens to confirm (and screenshot):
|
|||
|
|
|
|||
|
|
- The browser padlock shows a valid Let's Encrypt cert for `netbird.askari.wingu.me`.
|
|||
|
|
- The `/setup` page renders the admin-creation form on a fresh deploy, and the dashboard
|
|||
|
|
reports an authenticated session after first login.
|
|||
|
|
- The dashboard's peers/setup-keys view loads its data from the management API (no error
|
|||
|
|
toast, no infinite spinner) — proving the `/api` + gRPC routing through Caddy works.
|
|||
|
|
- An anonymous `/api` request returns 401/403, not data.
|
|||
|
|
|
|||
|
|
## Not browser-verifiable
|
|||
|
|
|
|||
|
|
Route these to the manual-test handoff:
|
|||
|
|
|
|||
|
|
- **STUN on 3478/udp** (journey 5) — UDP, not HTTP; verify with a STUN client, not a
|
|||
|
|
browser.
|
|||
|
|
- **gRPC over h2c** (management + signal exchange) and the **relay WebSocket** — exercised
|
|||
|
|
end-to-end only by a real peer enrolling (M5), not by a headless dashboard session.
|
|||
|
|
- **Peer enrolment via setup keys** — depends on the M5 client work; out of scope here.
|
|||
|
|
- **Datastore encryption / restore** — proven by the `BACKUP.md` restore drill, not the UI.
|
|||
|
|
|
|||
|
|
## Test data
|
|||
|
|
|
|||
|
|
This service runs **only on production askari** — there is no staging Authentik group and
|
|||
|
|
no SSO in front of it (it ships its own embedded IdP). The journeys provision their own:
|
|||
|
|
|
|||
|
|
- A **fresh deploy with zero users** so journey 2 (`/setup`) is reachable; journey 2
|
|||
|
|
itself creates the single admin account used by journeys 3–4. No pre-seeded peers.
|
|||
|
|
- Public DNS A-record for `netbird.askari.wingu.me` pointing at askari (so Caddy's
|
|||
|
|
HTTP-01 cert can issue) — already provisioned with the M4a Caddy.
|