Add ADR-029/030, implementation tasks, and spec updates for admin socket removal
Security review #005 identified critical vulnerabilities in the Unix domain socket admin API (C1 symlink race, C2 no auth, C3 info leak, W1-W7, S1-S6). ADR-028 (already accepted) replaces the socket with an authenticated HTTP admin API on the health check port. This commit adds the remaining spec work: - ADR-029: Config file TOCTOU mitigation (mtime check on reload) - ADR-030: Store cli_allow_wildcard_bind in ConfigReloadHandle for consistent reload validation - Implementation tasks for the admin HTTP migration (fix/admin-http-api), TOCTOU fix (fix/config-reload-toctou), and wildcard flag fix (fix/wildcard-flag-reload) - Updated review #005 status to resolved with per-finding disposition - Resolved OQ-16: POST for state-changing admin endpoints, GET for read-only - Updated all architecture docs to reference new ADRs, use admin_key_path instead of admin_socket_path, and reflect POST method for /admin/reload
This commit is contained in:
1 parent
9096ec5873
commit
161049a17d
21 files changed
+1210
-119
No files matched your search
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-06-12
|
||||
last_updated: 2026-06-14
|
||||
---
|
||||
|
||||
# Open Questions
|
||||
@@ -51,8 +51,8 @@ last_updated: 2026-06-12
|
||||
- **Resolution**: Add a configurable local health check port (default: 9900)
|
||||
bound to `127.0.0.1` only. Health checks work even when TLS is misconfigured.
|
||||
There is no `/health` route on the main HTTPS listener — health checking is
|
||||
handled exclusively by the local port and admin socket. See ADR-013 and
|
||||
ADR-022.
|
||||
handled exclusively by the local port and admin HTTP endpoint. See ADR-013,
|
||||
ADR-022, and ADR-028.
|
||||
- **Cross-references**: ADR-013, ADR-022
|
||||
|
||||
## Configuration
|
||||
@@ -62,10 +62,13 @@ last_updated: 2026-06-12
|
||||
- **Origin**: [config.md](config.md)
|
||||
- **Status**: resolved
|
||||
- **Priority**: low
|
||||
- **Resolution**: Yes. Add a Unix domain socket admin API alongside SIGHUP.
|
||||
The socket accepts a `reload` command and returns structured success/failure
|
||||
responses. SIGHUP is retained as a fallback. See ADR-014.
|
||||
- **Cross-references**: ADR-014
|
||||
- **Resolution**: Yes, via ADR-014 (Unix domain socket). The socket has since
|
||||
been replaced by an authenticated HTTP admin API (ADR-028) due to security
|
||||
vulnerabilities identified in review #005. SIGHUP is retained as a fallback.
|
||||
Admin HTTP endpoints (`/admin/reload`, `/admin/status`, `/admin/rotate-key`)
|
||||
are served on the health check listener at `127.0.0.1:9900` behind Bearer
|
||||
token authentication.
|
||||
- **Cross-references**: ADR-014 (superseded), ADR-028
|
||||
|
||||
## Deployment
|
||||
|
||||
@@ -100,14 +103,14 @@ last_updated: 2026-06-12
|
||||
- **Priority**: medium
|
||||
- **Resolution**: The `/health` route does not belong on the main listener at
|
||||
all. Health checking is an operational concern served by the dedicated local
|
||||
port (9900) and the admin socket's `status` command — not by intercepting
|
||||
port (9900) and the admin HTTP endpoint's `/admin/status` — not by intercepting
|
||||
traffic on the public-facing proxy. Serving `/health` on the main listener
|
||||
creates collision with upstream applications, requires special-case routing
|
||||
logic before host-based matching, and is architecturally wrong: the main
|
||||
listener's job is to proxy requests, not to serve operational endpoints. The
|
||||
local health check port (bound to `127.0.0.1:9900`) and the admin socket are
|
||||
the sole health/status mechanisms. See ADR-022.
|
||||
- **Cross-references**: ADR-013, ADR-022
|
||||
local health check port (bound to `127.0.0.1:9900`) and the admin HTTP endpoint
|
||||
are the sole health/status mechanisms. See ADR-022 and ADR-028.
|
||||
- **Cross-references**: ADR-013, ADR-022, ADR-028
|
||||
|
||||
### ~~OQ-09: How should `upstream_connect_timeout_secs` be enforced?~~
|
||||
|
||||
@@ -200,4 +203,30 @@ last_updated: 2026-06-12
|
||||
longer max age might be desirable. These would be dynamic config fields
|
||||
(hot-reloadable via ArcSwap) if added. For Phase 1, the hardcoded values
|
||||
are reasonable defaults.
|
||||
- **Cross-references**: ADR-006
|
||||
- **Cross-references**: ADR-006
|
||||
|
||||
## Security
|
||||
|
||||
### OQ-15: Should admin key rotation persist across restarts?
|
||||
|
||||
- **Origin**: [operations.md](operations.md), ADR-028
|
||||
- **Status**: open
|
||||
- **Priority**: medium
|
||||
- **Details**: The `/admin/rotate-key` endpoint generates a new random key and
|
||||
replaces the stored hash in memory, but this change does not persist across
|
||||
restarts. On restart, the proxy re-reads the admin key file. To make rotation
|
||||
permanent, the operator must also update the key file on disk separately.
|
||||
Options for persisting rotation: (1) write the new hash to the key file on
|
||||
rotation (breaks the "read-only key file" model), (2) write a separate state
|
||||
file with the rotated hash, (3) document the current behavior and accept it
|
||||
(operator updates the file manually after rotation). Option 3 is simplest
|
||||
and maintains the read-only semantics of the key file mount.
|
||||
- **Cross-references**: ADR-028
|
||||
|
||||
### ~~OQ-16: Should the admin HTTP API use POST for /admin/reload instead of GET?~~
|
||||
|
||||
- **Origin**: ADR-28 specifies GET for all admin endpoints, but HTTP semantics suggest POST for state-changing operations (reload).
|
||||
- **Status**: resolved
|
||||
- **Priority**: low
|
||||
- **Resolution**: State-changing admin endpoints (`/admin/reload`, `/admin/rotate-key`) use POST. Read-only endpoints (`/admin/status`, `/health`) use GET. This follows standard HTTP semantics — GET requests should be safe and idempotent, and triggering a config reload is neither. The convenience argument (shorter curl command) does not justify violating HTTP method semantics. See ADR-028.
|
||||
- **Cross-references**: ADR-028
|
||||
Reference in new issue
Block a user