Skip to content

fix(deploy): keycloak admin paths on their own port, nas ingress without allow-lists (#178) - #182

Merged
mpcs2013 merged 1 commit into
mainfrom
issue/178-nas-ingress-admin-port
Oct 21, 2026
Merged

mpcs2013 merged 1 commit into
mainfrom
issue/178-nas-ingress-admin-port

Conversation

@mpcs2013

Copy link
Copy Markdown
Owner

Keycloak's admin paths move to their own published port (8444), and the published ingress drops the Caddy source-address allow-lists that cannot work behind the NAS runtime's userland proxy. The NAS per-interface firewall becomes the documented control (ADR-0016 R9.6/R9.8 amendment), and #132's runbook carries the firewall rules, the source-address measurement and the refusal checks.

  • Caddy: a second site on the id host, port 8444, admits only the admin console paths; the 8443 id site returns 403 for them before any admitting route, and refuses paths still holding an encoded dot, slash or backslash after one decode. Every route reachable from outside keeps a not remote_ip over the internal networks; back-channel routes are unchanged.
  • Compose: a required DECISYA_ADMIN_PORT (8444); both ports are published on the bind address only and fail closed. DECISYA_LAN_SUBNET and DECISYA_WORKSTATION_ADDRESS are retired and refused by check. Keycloak gets KC_HOSTNAME_ADMIN on the admin port (AppHost model, regenerated docker-compose.yaml).
  • Guards: two listeners; a PUBLISHED_ROUTES table naming the NAS firewall rule per published route; no admin path reachable on 8443 (case and encoding variants); refused risky path patterns and matchers; a static runbook check; red cases for each rule.
  • Master realm: brute-force detection (no permanent lockout) is a new identity-check row, checked by verify once the bootstrap secret is retired. An Integration test exercises the runbook's own kcadm.sh command.

Rollback: revert this PR. The merge deploys nothing. On a stack already brought up with this change, restore the two retired keys and drop DECISYA_ADMIN_PORT in the stack's environment file, remove the NAS firewall rule for the admin port, and redeploy. Master-realm brute-force detection may stay on.

Verification (local | CI)

Check Local (host, 2026-10-21) CI
dotnet build -warnaserror 0 warnings, 0 errors build-test
Unit tests (CI filters) 1798 passed build-test
AppHost tests 40 passed, 1 skipped (#70) apphost-tests
Identity Integration (real Keycloak) 149 passed build-test
Deploy guards (deploy/tests) 315 run, OK, 14 skipped deploy-guards
.claude suite and lint 437 run, OK; lint OK claude-config
Compose drift (fresh publish equals committed file) regenerated with the CI form deploy-guards
deploy/tests/stack_smoke.py (live Caddy probes) not run (needs a Linux Docker host) not in CI; owed before #132's first up (G6)

Decisions: the ADR-0016 amendment was accepted by Marco on 2026-10-21. G6 finding F-178-01 (Low: no CI test sends live requests to Caddy) is on #83. G6's condition (run stack_smoke.py green on a Linux Docker host before the first up on the NAS) is on #132.

Packages: none added.

Closes #178

Docs: docs/adr/0016-phase-0-hosting.md, docs/adr/README.md, docs/architecture/nas-ingress-admin-port.md, docs/architecture/deployable-stack.md, docs/architecture/phase-0-hosting.md, docs/runbooks/deployable-stack.md, docs/runbooks/go-live-gate.md, docs/security/threat-models/nas-ingress-admin-port.md, docs/security/reviews/178.md, docs/requirements/phase-0/nas-ingress-admin-port.md, docs/ai/pipeline/178.md

🤖 Generated with Claude Code

…out allow-lists (#178)

Keycloak admin paths get their own published port (8444); 8443 refuses them.
The published ingress drops Caddy source-address allow-lists that cannot work
behind the NAS userland proxy; the NAS per-interface firewall is the control
(ADR-0016 R9.6/R9.8 amendment, accepted). Guard tests, smoke probes, the
master-realm brute-force identity check and the #132 runbook steps follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mpcs2013
mpcs2013 merged commit ceac939 into main Oct 21, 2026
11 checks passed
@mpcs2013
mpcs2013 deleted the issue/178-nas-ingress-admin-port branch October 21, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(deploy): nas ingress without source-address allow-lists; keycloak admin paths on their own port

1 participant