fix(security): enforce audited account, network and resource boundaries
Implement B01-B06 with regression coverage and retained validation evidence. Preserve the production ingress preflight; F04 runtime verification remains open.
This commit is contained in:
+23
-8
@@ -77,17 +77,32 @@ PostgreSQL is not implemented. Do not configure or recommend it without first ad
|
||||
## Deployment flow
|
||||
|
||||
Production automation always selects `docker-compose.yml` explicitly. Local development must add
|
||||
`docker-compose.dev.yml`; never add that file to a production command. The base configuration has no
|
||||
host bindings for frontend, backend, ai-service, or bundled Ollama.
|
||||
`docker-compose.dev.yml`; never add that file to a production command. The effective base configuration
|
||||
publishes **frontend 3000 → 80** on all host interfaces for the recorded Traefik host-port dependency.
|
||||
Backend, ai-service and bundled Ollama have no host-port bindings. CORS and Docker service names are
|
||||
not network isolation. The backend also joins the operator-managed `jobtracker_shared` network for
|
||||
existing service dependencies; its membership and other host services need operator inspection.
|
||||
|
||||
The external Traefik configuration is operator-owned and is not stored here. Before deployment it
|
||||
must route only the exact host from `APP_PUBLIC_BASE_URL` to frontend port 80 on
|
||||
`jobtracker_shared`, terminate TLS, replace `X-Forwarded-For` and `X-Forwarded-Proto=https`, and
|
||||
expose no direct application or Ollama host ports.
|
||||
must route only the exact host from `APP_PUBLIC_BASE_URL` to the recorded frontend host port 3000,
|
||||
terminate TLS, and replace `X-Forwarded-For` with one client IP and `X-Forwarded-Proto=https`.
|
||||
Do not migrate to container routing or bind port 3000 to loopback without verifying where Traefik runs.
|
||||
Host firewall/Docker forwarding rules must restrict ingress appropriately; their existence is unproven.
|
||||
|
||||
Nginx independently rejects non-canonical Hosts except `/health`, forwards Traefik's sanitized
|
||||
single-hop values, and reaches the backend only over `WEB_PROXY_SUBNET`. The backend fails startup
|
||||
if forwarded-header trust is enabled without a valid known CIDR.
|
||||
Nginx requires `INGRESS_PROXY_CIDRS` (space-separated observed Traefik peer CIDRs, preferably /32 or
|
||||
/128), rejects other peers before serving application routes, rejects missing scheme/IP and forwarding
|
||||
chains, and emits normalized forwarding metadata. It rejects non-canonical Hosts except the default
|
||||
server's liveness-only `/health`. The backend trusts only `WEB_PROXY_SUBNET` and one hop. Never trust a
|
||||
NAT/gateway address shared by both Traefik and untrusted callers. If peer identity cannot distinguish
|
||||
them, stop rollout and establish a verified host binding/firewall or dedicated proxy route first.
|
||||
|
||||
Deployment requires Python 3 (standard library) and Docker Compose's JSON config support. The new
|
||||
`scripts/validate-ingress.py` preflight checks the **rendered** production configuration before normal
|
||||
deployment backup/build/replacement; backup-only runs remain independent of the new ingress setting.
|
||||
CI runs `python3 scripts/test-ingress.py` without needing a Docker engine. Empty/missing peer values
|
||||
fail safely; do not copy synthetic addresses from tests into production. Runtime/container verification
|
||||
is still pending locally due to Docker Desktop failure. See the [B06 report and operator checks](../docs/audits/2026-09-07/validation/b06-completion.md)
|
||||
before deploying this change. No production verification is implied by configuration tests.
|
||||
1. push to `main`
|
||||
2. Gitea Actions runs tests
|
||||
3. if green, workflow uploads repo to server
|
||||
|
||||
Reference in New Issue
Block a user