Validation: #69 Configure config.hosts (DNS rebinding protection)

validation-69-2026-07-17 Doc

validation fail

Verdict: FAIL

Ticket

#69 Configure config.hosts (DNS rebinding protection) — Enable Rails host authorization in production, allowing only intelligentstaffingsystems.ai and iss.tail5b443a.ts.net, while excluding health checks and k8s IP-based probes.
Merged PR: #70 (commit a8e460a)
Board item: #1866 on board-iss

Environment

Prod cluster: archbox (k3s), namespace intelligentstaffingsystems
Running pod: intelligentstaffingsystems-6d6896dd95-ls9k4 — Running, 0 restarts, 11h uptime
Crash-looping pod: intelligentstaffingsystems-8474c67bc8-nxphp — Init:CrashLoopBackOff, 13 restarts, 44m — PLACEHOLDER_POSTGRES_HOST
ArgoCD: Synced / Degraded
Running image: harbor.tail5b443a.ts.net/intelligentstaffingsystems/app:93b9a79b (commit 93b9a79 — 3 commits BEFORE PR #70 merge)

Tiers Executed

Tier 1 (local): Skipped — Docker tests hang per known gap (#65).
Tier 3 (production): Executed — change not deployed, cannot validate acceptance criteria in production.

Checks

# Criterion How Verified Result Evidence
1 Woodpecker pipeline green for merge commit Woodpecker pipeline list (all main branch pipelines) FAIL All pipelines since image <code>93b9a79</code> are failing. Latest pipeline #90 fails at <code>test</code> step: <code>cannot load such file -- minitest/mock (LoadError)</code>. <code>build-and-push</code> step skipped. Previous validation saw messaging test failures; now the failure is a missing gem dependency.
2 New image deployed to prod pod <code>kubectl get pods -n intelligentstaffingsystems -o jsonpath=image</code> FAIL Running image tag <code>93b9a79b</code> is 3 commits behind merge commit <code>a8e460a</code>. No image was pushed because CI test step failed.
3 Pod running and ready <code>kubectl get pods -n intelligentstaffingsystems</code> PARTIAL One pod running (0 restarts). Second pod in <code>Init:CrashLoopBackOff</code> (13 restarts) with <code>ActiveRecord::DatabaseConnectionError: PLACEHOLDER_POSTGRES_HOST</code>. ArgoCD: Synced / Degraded.
4 Code correct at HEAD: config.hosts includes intelligentstaffingsystems.ai <code>grep config.hosts config/environments/production.rb</code> PASS <code>config.hosts &lt;&lt; "intelligentstaffingsystems.ai"</code> present at line 87
5 Code correct at HEAD: config.hosts includes iss.tail5b443a.ts.net <code>grep config.hosts config/environments/production.rb</code> PASS <code>config.hosts &lt;&lt; "iss.tail5b443a.ts.net"</code> present at line 88
6 Code correct at HEAD: health check /up excluded from host auth Read production.rb lines 90-94 PASS <code>request.path == "/up"</code> in host_authorization exclude lambda
7 Code correct at HEAD: IP-based probes excluded Read production.rb lines 90-94 PASS Proper 0-255 octet IPv4 regex in host_authorization exclude lambda
8 Route smoke: / returns 200 <code>curl https://intelligentstaffingsystems.ai/</code> PASS HTTP 200, HTML with correct title "Intelligence Staffing Systems"
9 Route smoke: /up returns 200 <code>curl https://intelligentstaffingsystems.ai/up</code> PASS HTTP 200
10 DNS rebinding protection active in production <code>curl -H "Host: evil.example.com" https://intelligentstaffingsystems.ai/</code> FAIL Returns HTTP 200 instead of expected 403. Expected: running image does not include config.hosts changes (confirms check #2).

Regression Check

Current production deployment (pre-PR #70 image) is healthy. Root page loads correctly. Health endpoint responds. No regressions from the running deployment. The config.hosts change cannot cause regressions since it is not yet deployed.

Discovered Issues

  • BLOCKER: CI test step broken — minitest/mock LoadError. All Woodpecker pipelines fail at the test step with cannot load such file -- minitest/mock (LoadError). The build-and-push step is skipped, so no new images are being built. This blocks deployment of PR #70 and all subsequent merges. The failure cause has evolved since the first validation attempt (was messaging test failures, now a gem dependency issue).
  • Crash-looping pod with PLACEHOLDER_POSTGRES_HOST. Pod intelligentstaffingsystems-8474c67bc8-nxphp is in Init:CrashLoopBackOff with ActiveRecord::DatabaseConnectionError: PLACEHOLDER_POSTGRES_HOST. A deployment revision was created without proper database environment variables. This causes ArgoCD to report Degraded health.
  • Tailscale URL not responding. https://iss.tail5b443a.ts.net/up returns connection failure (curl exit code 6, HTTP 000). The Tailscale hostname may not be routed or funneled.

Validation History

2026-07-17 (rev 1): PARTIAL — CI blocked by messaging test failures. Code correct at HEAD. Image not deployed.
2026-07-17 (rev 2): FAIL — CI failure evolved to minitest/mock LoadError. New crash-looping pod discovered. ArgoCD now Degraded (was Healthy). Upgraded to FAIL because the deployment situation has worsened with no path to resolution without CI fix.