Resolve 5 open questions, add 7 ADRs for previously undocumented decisions

Resolve open questions:
- OQ-01: Restrict cipher suites to match nginx scope (4 ECDHE-AES-GCM
  suites for TLS 1.2 + all TLS 1.3 suites) — ADR-012
- OQ-03: Health check on separate local port (default 9900, localhost
  only) — ADR-013
- OQ-04: Add Unix domain socket admin API for config reload alongside
  SIGHUP, with structured success/failure responses — ADR-014
- OQ-06: Per-site upstream timeouts with defaults (5s connect, 60s
  request), overridable in SiteConfig — ADR-015

Document previously undocumented decisions flagged by architecture review:
- ADR-016: Explicit bind address requirement (reject 0.0.0.0)
- ADR-017: Upstream connection defaults (HTTP/1.1, no redirects, pooling)
- ADR-018: 100 MB body size limit (matches nginx, Gitea compatibility)

OQ-07 (per-site TLS overrides) remains open for future consideration.

Spec updates:
- config.md: add health_check_port, admin_socket_path, per-site timeout
  fields, update TOML example and validation rules
- proxy.md: reference ADR-015/017/018 for timeouts, connection defaults,
  and body limit decisions
- tls.md: replace OQ-01 cipher suite section with ADR-012 decision
- operations.md: add local health check port section, admin socket reload
- overview.md: update Phase 1 scope with new features, add ADR references
- open-questions.md: resolve OQ-01/03/04/06, keep OQ-07 open
This commit is contained in:
2026-06-11 09:07:36 +00:00
parent 7efc142406
commit 9a2352e61c
14 changed files with 613 additions and 89 deletions

View File

@@ -0,0 +1,53 @@
# ADR-016: Explicit Bind Address Requirement
## Status
Accepted
## Context
The proxy's `bind_addr` configuration field specifies the IP address to bind
to. The default for most network services is `0.0.0.0` (bind all interfaces),
which means the service is accessible on every network interface, including
public-facing ones.
For a reverse proxy that terminates TLS and handles security-sensitive traffic,
binding to all interfaces is risky. The proxy should only listen on the
intended interface(s) — typically a specific public IP for a single-server
deployment.
## Decision
The `bind_addr` field must be an explicit IP address. `0.0.0.0` is rejected
during config validation. The proxy will not start if `bind_addr` is `0.0.0.0`.
## Rationale
- A reverse proxy terminating TLS is a security boundary — it should not be
accidentally exposed on unintended interfaces
- Single-server deployments have a specific public IP; binding to it
deliberately is the correct operational practice
- `0.0.0.0` is often a default in example configurations and can be deployed
without the operator realizing the service is accessible on all interfaces
- Rejecting it at validation time prevents this common mistake
- If a deployment genuinely needs to bind all interfaces, `0.0.0.0` can be
overridden with an explicit flag, but this should be a deliberate choice
- This matches the principle of explicit over implicit for security-sensitive
configuration
## Consequences
**Positive:**
- Prevents accidental exposure on unintended network interfaces
- Forces operators to be deliberate about which interface the proxy serves
- Config validation catches the mistake before deployment
**Negative:**
- Not suitable for deployments that genuinely need to bind all interfaces
(mitigated by explicit override if needed in the future)
- Slightly more configuration required (operator must know their public IP)
## References
- [config.md](../config.md)
- [overview.md](../overview.md)