feat: add landscaping-assistant.app to Rails config.hosts (#224) #230

Merged
ldraney merged 2 commits from 224-add-custom-domain-host into main 2026-06-16 01:16:04 +00:00
Owner

Summary

  • Add landscaping-assistant.app to config.hosts in production.rb so Rails accepts requests arriving through the Hetzner edge proxy with the public domain Host header.

Changes

  • config/environments/production.rb: added config.hosts << "landscaping-assistant.app" following the same pattern used in development.rb for the Tailscale hostname

Test Plan

  • Deploy to production and verify curl -I https://landscaping-assistant.app returns 200 (not 403 Blocked Host)
  • Verify Tailscale hostname still works: curl -I https://landscaping-assistant.tail5b443a.ts.net
  • No regressions in development environment

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
  • Feature flag needed? No -- config.hosts is infrastructure plumbing, not a user-visible feature
  • Closes #224
  • Companion PR in ldraney/pal-e-services for Keycloak redirect URIs
## Summary - Add `landscaping-assistant.app` to `config.hosts` in production.rb so Rails accepts requests arriving through the Hetzner edge proxy with the public domain Host header. ## Changes - `config/environments/production.rb`: added `config.hosts << "landscaping-assistant.app"` following the same pattern used in development.rb for the Tailscale hostname ## Test Plan - [ ] Deploy to production and verify `curl -I https://landscaping-assistant.app` returns 200 (not 403 Blocked Host) - [ ] Verify Tailscale hostname still works: `curl -I https://landscaping-assistant.tail5b443a.ts.net` - [ ] No regressions in development environment ## Review Checklist - [ ] Passed automated review-fix loop - [ ] No secrets committed - [ ] No unnecessary file changes - [ ] Commit messages are descriptive - [ ] Feature flag needed? No -- config.hosts is infrastructure plumbing, not a user-visible feature ## Related Notes - Closes #224 - Companion PR in `ldraney/pal-e-services` for Keycloak redirect URIs
feat: add landscaping-assistant.app to Rails config.hosts
Some checks failed
CI / scan_ruby (pull_request) Waiting to run
CI / scan_js (pull_request) Waiting to run
CI / lint (pull_request) Waiting to run
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
96502f2d9a
Allow the public custom domain through Rails host authorization
so requests via the Hetzner edge proxy are not rejected with
a 403 Blocked Host error.

Refs #224

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #230 Review

DOMAIN REVIEW

Stack: Ruby on Rails (production config)

The change adds config.hosts << "landscaping-assistant.app" to config/environments/production.rb. This is the standard Rails 7+ host authorization mechanism for allowing requests with a specific Host header.

Correctness:

  • The << append syntax is correct. It adds to the default hosts allowlist rather than replacing it, so existing access via Tailscale hostname is preserved.
  • Placement after the commented-out hosts example block is clean and follows Rails convention.
  • The pattern matches the existing config.hosts << "landscaping-dev.tail5b443a.ts.net" in development.rb (line 76), consistent with the PR description.

Security:

  • config.hosts is a defensive mechanism -- adding a domain relaxes the allowlist. This is intentional and necessary for the Hetzner edge proxy to forward requests with the public domain Host header.
  • No wildcard or regex used, which is good -- only the exact bare domain is allowed.

One consideration (not a blocker): Only the bare domain landscaping-assistant.app is added. If traffic ever arrives with www.landscaping-assistant.app as the Host header, Rails will return 403 Blocked Host. This is likely fine since DNS and Caddy are presumably configured for the bare domain only, but worth noting for future awareness.

BLOCKERS

None.

This is infrastructure config plumbing, not application logic. No test coverage blocker applies -- the test plan correctly specifies post-deploy manual verification via curl -I. No secrets, no user input, no auth logic, no DRY concerns.

NITS

  • Consider adding a brief inline comment above the line (e.g., # Public domain via Hetzner edge proxy) for future readers who encounter the file cold. The commented-out example block above does not explain why a host is allowed. Minor -- the git log serves this purpose too.

SOP COMPLIANCE

  • PR body has Summary, Changes, Test Plan, Related sections
  • No secrets committed
  • No unnecessary file changes (1 file, 3 lines including blank lines)
  • Commit message is descriptive and references issue number
  • Closes #224 referenced in PR body
  • Companion PR for Keycloak redirect URIs mentioned (pal-e-services)

PROCESS OBSERVATIONS

  • Clean, minimal change with appropriate scope. No scope creep.
  • Test plan is deployment-gated (curl against production). This is the correct approach for host authorization config -- there is no meaningful way to unit test this without mocking the full Rails request pipeline.
  • The companion PR pattern (this PR for Rails, separate PR for Keycloak) correctly separates concerns across repos.
  • Low change-failure risk. Worst case is a misconfigured host name string causing continued 403s, which is immediately observable and easily reversible.

VERDICT: APPROVED

## PR #230 Review ### DOMAIN REVIEW **Stack:** Ruby on Rails (production config) The change adds `config.hosts << "landscaping-assistant.app"` to `config/environments/production.rb`. This is the standard Rails 7+ host authorization mechanism for allowing requests with a specific `Host` header. **Correctness:** - The `<<` append syntax is correct. It adds to the default hosts allowlist rather than replacing it, so existing access via Tailscale hostname is preserved. - Placement after the commented-out hosts example block is clean and follows Rails convention. - The pattern matches the existing `config.hosts << "landscaping-dev.tail5b443a.ts.net"` in `development.rb` (line 76), consistent with the PR description. **Security:** - `config.hosts` is a defensive mechanism -- adding a domain *relaxes* the allowlist. This is intentional and necessary for the Hetzner edge proxy to forward requests with the public domain Host header. - No wildcard or regex used, which is good -- only the exact bare domain is allowed. **One consideration (not a blocker):** Only the bare domain `landscaping-assistant.app` is added. If traffic ever arrives with `www.landscaping-assistant.app` as the Host header, Rails will return 403 Blocked Host. This is likely fine since DNS and Caddy are presumably configured for the bare domain only, but worth noting for future awareness. ### BLOCKERS None. This is infrastructure config plumbing, not application logic. No test coverage blocker applies -- the test plan correctly specifies post-deploy manual verification via `curl -I`. No secrets, no user input, no auth logic, no DRY concerns. ### NITS - Consider adding a brief inline comment above the line (e.g., `# Public domain via Hetzner edge proxy`) for future readers who encounter the file cold. The commented-out example block above does not explain *why* a host is allowed. Minor -- the git log serves this purpose too. ### SOP COMPLIANCE - [x] PR body has Summary, Changes, Test Plan, Related sections - [x] No secrets committed - [x] No unnecessary file changes (1 file, 3 lines including blank lines) - [x] Commit message is descriptive and references issue number - [x] Closes #224 referenced in PR body - [x] Companion PR for Keycloak redirect URIs mentioned (pal-e-services) ### PROCESS OBSERVATIONS - Clean, minimal change with appropriate scope. No scope creep. - Test plan is deployment-gated (curl against production). This is the correct approach for host authorization config -- there is no meaningful way to unit test this without mocking the full Rails request pipeline. - The companion PR pattern (this PR for Rails, separate PR for Keycloak) correctly separates concerns across repos. - Low change-failure risk. Worst case is a misconfigured host name string causing continued 403s, which is immediately observable and easily reversible. ### VERDICT: APPROVED
Author
Owner

PR #230 Review

DOMAIN REVIEW

Stack: Ruby on Rails (production environment configuration)

Rails Host Authorization Analysis:

  • The change appends "landscaping-assistant.app" to config.hosts in production.rb, which tells Rails to accept requests with that Host header arriving through the Hetzner edge proxy. This is the correct fix for the 403 Blocked Host error.
  • Uses << (append) rather than assignment, which preserves the default host list (including the Tailscale hostname). This matches the pattern already established in development.rb line 76: config.hosts << "landscaping-dev.tail5b443a.ts.net".
  • Placement is logical -- directly after the commented-out config.hosts example block, with clean blank-line spacing.
  • test.rb already calls config.hosts.clear, so existing specs are unaffected.
  • No wildcard or regex used -- only the exact domain is allowed. This is appropriately restrictive.

One consideration (non-blocking): No www.landscaping-assistant.app variant is included. This is fine if DNS/Caddy does not route www to this app, but worth confirming during the deployment test plan.

BLOCKERS

None.

  • This is a configuration-only change (no application logic), so the "new functionality must have tests" blocker does not apply. The test plan correctly relies on deployment verification.
  • No secrets or credentials committed.
  • No unvalidated user input.
  • No DRY violations.

NITS

None. The change is minimal, correctly scoped, and follows established patterns.

SOP COMPLIANCE

  • PR body has Summary, Changes, Test Plan, Related sections
  • Test plan includes both positive (custom domain returns 200) and regression (Tailscale hostname still works) checks
  • No secrets committed
  • No unnecessary file changes (1 file, 3 lines added -- all directly related to #224)
  • Commit message is descriptive and references the issue number
  • Review Checklist present with feature flag justification

PROCESS OBSERVATIONS

  • Clean, minimal change with well-defined deployment verification steps. Low change failure risk.
  • The PR body correctly identifies the companion PR in ldraney/pal-e-services for Keycloak redirect URIs -- good cross-repo coordination.
  • This is part of the three-wave custom domain chain (DNS -> Caddy -> app config). Deployment order matters: this PR should be deployed only after DNS and Caddy are configured, otherwise the host addition has no effect (but also causes no harm).

VERDICT: APPROVED

## PR #230 Review ### DOMAIN REVIEW **Stack:** Ruby on Rails (production environment configuration) **Rails Host Authorization Analysis:** - The change appends `"landscaping-assistant.app"` to `config.hosts` in production.rb, which tells Rails to accept requests with that Host header arriving through the Hetzner edge proxy. This is the correct fix for the 403 Blocked Host error. - Uses `<<` (append) rather than assignment, which preserves the default host list (including the Tailscale hostname). This matches the pattern already established in `development.rb` line 76: `config.hosts << "landscaping-dev.tail5b443a.ts.net"`. - Placement is logical -- directly after the commented-out `config.hosts` example block, with clean blank-line spacing. - `test.rb` already calls `config.hosts.clear`, so existing specs are unaffected. - No wildcard or regex used -- only the exact domain is allowed. This is appropriately restrictive. **One consideration (non-blocking):** No `www.landscaping-assistant.app` variant is included. This is fine if DNS/Caddy does not route `www` to this app, but worth confirming during the deployment test plan. ### BLOCKERS None. - This is a configuration-only change (no application logic), so the "new functionality must have tests" blocker does not apply. The test plan correctly relies on deployment verification. - No secrets or credentials committed. - No unvalidated user input. - No DRY violations. ### NITS None. The change is minimal, correctly scoped, and follows established patterns. ### SOP COMPLIANCE - [x] PR body has Summary, Changes, Test Plan, Related sections - [x] Test plan includes both positive (custom domain returns 200) and regression (Tailscale hostname still works) checks - [x] No secrets committed - [x] No unnecessary file changes (1 file, 3 lines added -- all directly related to #224) - [x] Commit message is descriptive and references the issue number - [x] Review Checklist present with feature flag justification ### PROCESS OBSERVATIONS - Clean, minimal change with well-defined deployment verification steps. Low change failure risk. - The PR body correctly identifies the companion PR in `ldraney/pal-e-services` for Keycloak redirect URIs -- good cross-repo coordination. - This is part of the three-wave custom domain chain (DNS -> Caddy -> app config). Deployment order matters: this PR should be deployed only after DNS and Caddy are configured, otherwise the host addition has no effect (but also causes no harm). ### VERDICT: APPROVED
Merge branch 'main' into 224-add-custom-domain-host
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
CI / scan_ruby (pull_request) Has been cancelled
CI / scan_js (pull_request) Has been cancelled
CI / lint (pull_request) Has been cancelled
8aa77334ad
ldraney deleted branch 224-add-custom-domain-host 2026-06-16 01:16:04 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/landscaping-assistant!230
No description provided.