TLS & Edge Security

Certificate management, reverse proxy configuration, hardening headers

Chapter 5 — TLS & Edge Security

5.1 Edge Model

Every public surface is fronted by an nginx reverse proxy terminating TLS on the droplet that serves it. No CDN or external proxy layer is in scope at this fleet size; origin concealment (TLS-04) is addressed in §5.6 within that constraint.

Surface Droplet Proxy → Upstream State
monitor.sbsdash.com monitor-servers nginx 1.28.3 → Grafana 127.0.0.1:3000 (websockets on /api/live/) Live, verified 2026-07-17
wiki.sbsdash.com sbs-wiki nginx → BookStack (localhost) Live; re-verified at NYC2 rebuild
sbsdash.com, www sbsdash-server-prod nginx → Compartment frontend containers (Docker Compose, Chapter 6) Pending — gates the apex repoint (§4.3)
admin.sbsdash.com sbsdash-server-prod nginx → admin console container Pending
clients.sbsdash.com sbsdash-server-prod nginx → client surface container Pending

Host-header routing on sbsdash-server-prod separates the three tenant surfaces behind one IP. A default server block returns 444 (connection close, no response) for any request whose Host/SNI matches no configured surface — direct-to-IP scans and unrecognized hostnames get nothing, including no certificate hint (see §5.2 default cert note).

5.2 Certificate Management (TLS-02)
5.3 Protocol Floor (TLS-01)

Fleet-standard nginx TLS parameters, IaC-templated (Chapter 10), identical on every surface:

5.4 HSTS (TLS-03)
5.5 Security Headers (APP-02) and Frontend Exposure Controls (FE-01…FE-06)

Fleet-standard header set, applied at nginx (add_header ... always;), IaC-templated; per-surface CSP tightening happens at the application layer:

Header Value (baseline) Control
Strict-Transport-Security per §5.4 TLS-03
X-Frame-Options DENY APP-02 (clickjacking)
X-Content-Type-Options nosniff APP-02
Referrer-Policy no-referrer FE-04 — no sbsdash.com URL ever appears in an outbound Referer
Content-Security-Policy default-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self' — tightened per app APP-02 / FE-05 ('self'-only enforces first-party assets: no CDN fonts, no third-party scripts, no analytics beacons)
X-Robots-Tag noindex, nofollow, noarchive, nosnippet FE-01 — anti-indexing at the header layer, covers non-HTML responses too
Permissions-Policy camera=(), microphone=(), geolocation=(), interest-cohort=() APP-02
Cross-Origin-Opener-Policy same-origin APP-02
5.6 Origin Concealment (TLS-04)

Scoped honestly for a no-CDN architecture: the A records necessarily disclose droplet IPs, so concealment here means the origin exposes nothing but the intended service:

5.7 Admin Surface Isolation (APP-03, edge layer)

admin.sbsdash.com receives edge-layer restrictions beyond the tenant surfaces, ahead of the application-layer controls in Chapter 9:

5.8 Verification

Per-surface gate set (LH-SBS-INST-001): testssl.sh clean, protocol floor confirmed (no 1.0/1.1 handshake accepted); cert issued/renewing with expiry probe green; HTTP→HTTPS 301 with ACME path excluded; full header set present (curl -sI diff against template); robots.txt served; direct-IP request returns 444; no OG/Twitter tags in HTML; server_tokens absent; admin surface unreachable from a non-allowlisted IP; upstream ports absent from public ss -tlnp. The monitor surface — already live — is retro-fitted to the full template and re-verified as the reference implementation before the prod surfaces build against it.