diff --git a/docs/plans/current_spec.md b/docs/plans/current_spec.md index ef2a4694..d47c1e29 100644 --- a/docs/plans/current_spec.md +++ b/docs/plans/current_spec.md @@ -1,194 +1,523 @@ --- -post_title: "Current Spec: Resolve Proxy Host Hostname Validation Test Failures" +post_title: "Current Spec: Caddy 2.11.1 Compatibility, Security, and UX Impact Plan" categories: - actions - - testing + - security - backend + - frontend + - infrastructure tags: - - go - - proxyhost - - unit-tests - - validation -summary: "Focused plan to resolve failing TestProxyHostService_ValidateHostname malformed URL cases by aligning test expectations with intended validation behavior and validating via targeted service tests and coverage gate." -post_date: 2026-02-22 + - caddy + - xcaddy + - dependency-management + - vulnerability-management + - release-planning +summary: "Comprehensive, phased plan to evaluate and safely adopt Caddy v2.11.1 in Charon, covering plugin compatibility, CVE impact, xcaddy patch retirement decisions, UI/UX exposure opportunities, and PR slicing strategy with strict validation gates." +post_date: 2026-02-23 --- -## Active Plan: Resolve Failing Hostname Validation Tests +## Active Plan: Caddy 2.11.1 Deep Compatibility and Security Rollout -Date: 2026-02-22 +Date: 2026-02-23 Status: Active and authoritative -Scope Type: Backend test-failure remediation (service validation drift analysis) +Scope Type: Architecture/security/dependency research and implementation planning Authority: This is the only active authoritative plan section in this file. ## Introduction -This plan resolves backend run failures in `TestProxyHostService_ValidateHostname` -for malformed URL cases while preserving intended hostname validation behavior. +Charon’s control plane and data plane rely on Caddy as a core runtime backbone. +Because Caddy is embedded and rebuilt via `xcaddy`, upgrading from +`2.11.0-beta.2` to `2.11.1` is not a routine version bump: it impacts +runtime behavior, plugin compatibility, vulnerability posture, and potential UX +surface area. -Primary objective: +This plan defines a low-risk, high-observability rollout strategy that answers: -- Restore green test execution in `backend/internal/services` with a minimal, - low-risk change path. +1. Which Caddy 2.11.x features should be exposed in Charon UI/API? +2. Which existing Charon workarounds became redundant upstream? +3. Which `xcaddy` dependency patches remain necessary vs removable? +4. Which known vulnerabilities are fixed now and which should remain on watch? ## Research Findings -### Evidence Collected +### External release and security findings -- Failing command output confirms two failing subtests: - - `TestProxyHostService_ValidateHostname/malformed_https_URL` - - `TestProxyHostService_ValidateHostname/malformed_http_URL` -- Failure message for both cases: `invalid hostname format`. +1. Official release statement confirms `v2.11.1` has no runtime code delta from + `v2.11.0` except CI/release process correction. Practical implication: + compatibility/security validation should target **2.11.x** behavior, not + 2.11.1-specific runtime changes. +2. Caddy release lists six security patches (mapped to GitHub advisories): + - `CVE-2026-27590` → `GHSA-5r3v-vc8m-m96g` (FastCGI split_path confusion) + - `CVE-2026-27589` → `GHSA-879p-475x-rqh2` (admin API cross-origin no-cors) + - `CVE-2026-27588` → `GHSA-x76f-jf84-rqj8` (host matcher case bypass) + - `CVE-2026-27587` → `GHSA-g7pc-pc7g-h8jh` (path matcher escaped-case bypass) + - `CVE-2026-27586` → `GHSA-hffm-g8v7-wrv7` (mTLS client-auth fail-open) + - `CVE-2026-27585` → `GHSA-4xrr-hq4w-6vf4` (glob sanitization bypass) +3. NVD/CVE.org entries are currently reserved/not fully enriched. GitHub + advisories are the most actionable source right now. -### Exact Files Involved +### Charon architecture and integration findings -1. `backend/internal/services/proxyhost_service_validation_test.go` - - Test function: `TestProxyHostService_ValidateHostname` - - Failing cases currently expect `wantErr: false` for malformed URLs. -2. `backend/internal/services/proxyhost_service.go` - - Service function: `ValidateHostname(host string) error` - - Behavior: strips scheme, then validates hostname characters; malformed - residual values containing `:` are rejected with `invalid hostname format`. +1. Charon compiles custom Caddy in `Dockerfile` via `xcaddy` and injects: + - `github.com/greenpau/caddy-security` + - `github.com/corazawaf/coraza-caddy/v2` + - `github.com/hslatman/caddy-crowdsec-bouncer@v0.10.0` + - `github.com/zhangjiayin/caddy-geoip2` + - `github.com/mholt/caddy-ratelimit` +2. Charon applies explicit post-generation `go get` patching in `Dockerfile` for: + - `github.com/expr-lang/expr@v1.17.7` + - `github.com/hslatman/ipstore@v0.4.0` + - `github.com/slackhq/nebula@v1.9.7` (with comment indicating temporary pin) +3. Charon CI has explicit dependency inspection gate in + `.github/workflows/docker-build.yml` to verify patched `expr-lang/expr` + versions in built binaries. -### Root Cause Determination +### Plugin compatibility findings (highest risk area) -- Root cause is **test expectation drift**, not runtime service regression. -- `git blame` shows malformed URL test cases were added on 2026-02-22 with - permissive expectations, while validation behavior rejecting malformed host - strings predates those additions. -- Existing behavior aligns with stricter hostname validation and should remain - the default unless product requirements explicitly demand permissive handling - of malformed host inputs. +Current plugin module declarations (upstream `go.mod`) target older Caddy cores: -### Confidence Assessment +- `greenpau/caddy-security`: `caddy/v2 v2.10.2` +- `hslatman/caddy-crowdsec-bouncer`: `caddy/v2 v2.10.2` +- `corazawaf/coraza-caddy/v2`: `caddy/v2 v2.9.1` +- `zhangjiayin/caddy-geoip2`: `caddy/v2 v2.10.0` +- `mholt/caddy-ratelimit`: `caddy/v2 v2.8.0` -- Confidence score: **95% (High)** -- Rationale: direct reproduction, targeted file inspection, and blame history - converge on expectation drift. +Implication: compile success against 2.11.1 is plausible but not guaranteed. +The plan must include matrix build/provision tests before merge. + +### Charon UX and config-surface findings + +Current Caddy-related UI/API exposure is narrow: + +- `frontend/src/pages/SystemSettings.tsx` + - state: `caddyAdminAPI`, `sslProvider` + - saves keys: `caddy.admin_api`, `caddy.ssl_provider` +- `frontend/src/pages/ImportCaddy.tsx` and import components: + - Caddyfile parsing/import workflow, not runtime feature toggles +- `frontend/src/api/import.ts`, `frontend/src/api/settings.ts` +- Backend routes and handlers: + - `backend/internal/api/routes/routes.go` + - `backend/internal/api/handlers/settings_handler.go` + - `backend/internal/api/handlers/import_handler.go` + - `backend/internal/caddy/manager.go` + - `backend/internal/caddy/config.go` + - `backend/internal/caddy/types.go` + +No UI controls currently exist for new Caddy 2.11.x capabilities such as +`keepalive_idle`, `keepalive_count`, `trusted_proxies_unix`, +`renewal_window_ratio`, or `0-RTT` behavior. ## Requirements (EARS) -- WHEN malformed `http://` or `https://` host strings are passed to - `ValidateHostname`, THE SYSTEM SHALL return a validation error. -- WHEN service validation behavior is intentionally strict, THE TESTS SHALL - assert rejection for malformed URL residual host strings. -- IF product intent is permissive for malformed inputs, THEN THE SYSTEM SHALL - minimally relax parsing logic without weakening valid invalid-character checks. -- WHEN changes are completed, THE SYSTEM SHALL pass targeted service tests and - the backend coverage gate script. +1. WHEN evaluating Caddy `v2.11.1`, THE SYSTEM SHALL validate compatibility + against all currently enabled `xcaddy` plugins before changing production + defaults. +2. WHEN security advisories in Caddy 2.11.x affect modules Charon may use, + THE SYSTEM SHALL document exploitability for Charon’s deployment model and + prioritize remediation accordingly. +3. WHEN an `xcaddy` patch/workaround no longer provides value, + THE SYSTEM SHALL remove it only after reproducible build and runtime + validation gates pass. +4. IF a Caddy 2.11.x feature maps to an existing Charon concept, + THEN THE SYSTEM SHALL prefer extending existing UI/components over adding new + parallel controls. +5. WHEN no direct UX value exists, THE SYSTEM SHALL avoid adding UI for upstream + options and keep behavior backend-managed. +6. WHEN this rollout completes, THE SYSTEM SHALL provide explicit upstream watch + criteria for unresolved/reserved CVEs and plugin dependency lag. -## Technical Specification +## Technical Specifications -### Minimal Fix Path (Preferred) +### Compatibility scope map (code touch inventory) -Preferred path: **test-only correction**. +#### Build/packaging -1. Update malformed URL table entries in - `backend/internal/services/proxyhost_service_validation_test.go`: - - `malformed https URL` -> `wantErr: true` - - `malformed http URL` -> `wantErr: true` -2. Keep current service behavior in - `backend/internal/services/proxyhost_service.go` unchanged. -3. Optional test hardening (still test-only): assert error contains - `invalid hostname format` for those two cases. +- `Dockerfile` + - `ARG CADDY_VERSION` + - `ARG XCADDY_VERSION` + - `caddy-builder` stage (`xcaddy build`, plugin list, `go get` patches) +- `.github/workflows/docker-build.yml` + - binary dependency checks (`go version -m` extraction/gates) +- `.github/renovate.json` + - regex managers tracking `Dockerfile` patch dependencies -### Alternative Path (Only if Product Intent Differs) +#### Caddy runtime config generation -Use only if maintainers explicitly confirm malformed URL inputs should pass: +- `backend/internal/caddy/manager.go` + - `NewManager(...)` + - `ApplyConfig(ctx)` +- `backend/internal/caddy/config.go` + - `GenerateConfig(...)` +- `backend/internal/caddy/types.go` + - JSON struct model for Caddy config (`Server`, `TrustedProxies`, etc.) -1. Apply minimal service correction in `ValidateHostname` to normalize malformed - scheme inputs before character validation. -2. Add or update tests to preserve strict rejection for truly invalid hostnames - (e.g., `$`, `@`, `%`, `&`) so validation is not broadly weakened. +#### Settings and admin surface -Decision default for this plan: **Preferred path (test updates only)**. +- `backend/internal/api/handlers/settings_handler.go` + - `UpdateSetting(...)`, `PatchConfig(...)` +- `backend/internal/api/routes/routes.go` + - Caddy manager wiring + settings routes +- `frontend/src/pages/SystemSettings.tsx` + - current Caddy-related controls + +#### Caddyfile import behavior + +- `backend/internal/api/handlers/import_handler.go` + - `RegisterRoutes(...)`, `Upload(...)`, `GetPreview(...)` +- `backend/internal/caddy/importer.go` + - `NormalizeCaddyfile(...)`, `ParseCaddyfile(...)`, `ExtractHosts(...)` +- `frontend/src/pages/ImportCaddy.tsx` + - import UX and warning handling + +### Feature impact assessment (2.11.x) + +#### Candidate features for potential Charon exposure + +1. Keepalive server options (`keepalive_idle`, `keepalive_count`) + - Candidate mapping: advanced per-host connection tuning + - Likely files: `backend/internal/caddy/types.go`, + `backend/internal/caddy/config.go`, host settings API + UI +2. `trusted_proxies_unix` + - Candidate mapping: trusted local socket proxy chains + - Current `TrustedProxies` struct lacks explicit unix-socket trust fields +3. Certificate lifecycle tunables (`renewal_window_ratio`, maintenance interval) + - Candidate mapping: advanced TLS policy controls + - Potentially belongs under system-level TLS settings, not per-host UI + +#### Features likely backend-only / no new UI by default + +1. Reverse-proxy automatic `Host` rewrite for TLS upstreams +2. ECH key auto-rotation +3. `SIGUSR1` reload fallback behavior +4. Logging backend internals (`timberjack`, ordering fixes) + +Plan decision rule: expose only options that produce clear operator value and +can be represented without adding UX complexity. + +### Security patch relevance matrix + +#### Advisory exploitability rubric and ownership + +Use the following deterministic rubric for each advisory before any promotion: + +| Field | Required Values | Rule | +| --- | --- | --- | +| Exploitability | `Affected` / `Not affected` / `Mitigated` | `Affected` means a reachable vulnerable path exists in Charon runtime; `Not affected` means required feature/path is not present; `Mitigated` means vulnerable path exists upstream but Charon deployment/runtime controls prevent exploitation. | +| Evidence source | advisory + code/config/runtime proof | Must include at least one authoritative upstream source (GitHub advisory/Caddy release) and one Charon-local proof (config path, test, scan, or runtime verification). | +| Owner | named role | Security owner for final disposition (`QA_Security` lead or delegated maintainer). | +| Recheck cadence | `weekly` / `release-candidate` / `on-upstream-change` | Minimum cadence: weekly until CVE enrichment is complete and disposition is stable for two consecutive checks. | + +Promotion gate: every advisory must have all four fields populated and signed by +owner in the PR evidence bundle. + +#### High-priority for Charon context + +1. `GHSA-879p-475x-rqh2` (admin API cross-origin no-cors) + - Charon binds admin API internally but still uses `0.0.0.0:2019` in + generated config. Must verify actual network isolation and container + exposure assumptions. +2. `GHSA-hffm-g8v7-wrv7` (mTLS fail-open) + - Relevant if client-auth CA pools are configured anywhere in generated or + imported config paths. +3. matcher bypass advisories (`GHSA-x76f-jf84-rqj8`, `GHSA-g7pc-pc7g-h8jh`) + - Potentially relevant to host/path-based access control routing in Caddy. + +#### Contextual/conditional relevance + +- `GHSA-5r3v-vc8m-m96g` (FastCGI split_path) + - Relevant only if FastCGI transport is in active use. +- `GHSA-4xrr-hq4w-6vf4` (file matcher glob sanitization) + - Relevant when file matchers are used in route logic. + +### xcaddy patch retirement candidates + +#### Candidate to re-evaluate for removal + +- `go get github.com/slackhq/nebula@v1.9.7` + - Upstream Caddy has moved forward to `nebula v1.10.3` and references + security-related maintenance in the 2.11.x line. + - Existing Charon pin comment may be stale after upstream smallstep updates. + +#### Likely retain until proven redundant + +- `go get github.com/expr-lang/expr@v1.17.7` +- `go get github.com/hslatman/ipstore@v0.4.0` + +Retention/removal decision must be made using reproducible build + binary +inspection evidence, not assumption. + +#### Hard retirement gates (mandatory before removing any pin) + +Pin removal is blocked unless all gates pass: + +1. Binary module diff gate + - Produce before/after `go version -m` module diff for Caddy binary. + - No unexpected module major-version jumps outside approved advisory scope. +2. Security regression gate + - No new HIGH/CRITICAL findings in CodeQL/Trivy/Grype compared to baseline. +3. Reproducible build parity gate + - Two clean rebuilds produce equivalent module inventory and matching runtime + smoke results. +4. Rollback proof gate (mandatory, with explicit `nebula` focus) + - Demonstrate one-command rollback to previous pin set, with successful + compile + runtime smoke set after rollback. + +Retirement decision for `nebula` cannot proceed without explicit rollback proof +artifact attached to PR evidence. + +### Feature-to-control mapping (exposure decision matrix) + +| Feature | Control surface | Expose vs backend-only rationale | Persistence path | +| --- | --- | --- | --- | +| `keepalive_idle`, `keepalive_count` | Existing advanced system settings (if approved) | Expose only if operators need deterministic upstream connection control; otherwise keep backend defaults to avoid UX bloat. | `frontend/src/pages/SystemSettings.tsx` → `frontend/src/api/settings.ts` → `backend/internal/api/handlers/settings_handler.go` → DB settings → `backend/internal/caddy/config.go` (`GenerateConfig`) | +| `trusted_proxies_unix` | Backend-only default initially | Backend-only until proven demand for unix-socket trust tuning; avoid misconfiguration risk in general UI. | backend config model (`backend/internal/caddy/types.go`) + generated config path (`backend/internal/caddy/config.go`) | +| `renewal_window_ratio`, cert maintenance interval | Backend-only policy | Keep backend-only unless operations requires explicit lifecycle tuning controls. | settings store (if introduced) → `settings_handler.go` → `GenerateConfig` | +| Reverse-proxy Host rewrite / ECH rotation / reload fallback internals | Backend-only | Operational internals with low direct UI value; exposing would increase complexity without clear user benefit. | backend runtime defaults and generated Caddy config only | ## Implementation Plan -### Phase 1: Test-first Repro and Baseline +### Phase 1: Playwright and behavior baselining (mandatory first) -1. Confirm current failure (already reproduced). -2. Record failing subtests and error signatures as baseline evidence. +Objective: capture stable pre-upgrade behavior and ensure UI/UX parity checks. -### Phase 2: Minimal Remediation +1. Run targeted E2E suites covering Caddy-critical flows: + - `tests/tasks/import-caddyfile.spec.ts` + - `tests/security-enforcement/zzz-caddy-imports/*.spec.ts` + - system settings-related tests around Caddy admin API and SSL provider +2. Capture baseline artifacts: + - Caddy import warning behavior + - security settings save/reload behavior + - admin API connectivity assumptions from test fixtures +3. Produce a baseline report in `docs/reports/` for diffing in later phases. -1. Apply preferred test expectation update in - `backend/internal/services/proxyhost_service_validation_test.go`. -2. Keep service code unchanged unless product intent is clarified otherwise. +### Phase 2: Backend and build compatibility research implementation -### Phase 3: Targeted Validation +Objective: validate compile/runtime compatibility of Caddy 2.11.1 with current +plugin set and patch set. -Run in this order: +1. Bump candidate in `Dockerfile`: + - `ARG CADDY_VERSION=2.11.1` +2. Execute matrix builds with toggles: + - Scenario A: current patch set unchanged + - Scenario B: remove `nebula` pin only + - Scenario C: remove `nebula` + retain `expr/ipstore` +3. Execute explicit compatibility gate matrix (deterministic): -1. `go test ./backend/internal/services -run TestProxyHostService_ValidateHostname -v` -2. Related service package tests: - - `go test ./backend/internal/services -run TestProxyHostService -v` - - `go test ./backend/internal/services -v` -3. Final gate: - - `bash scripts/go-test-coverage.sh` + | Dimension | Values | + | --- | --- | + | Plugin set | `caddy-security`, `coraza-caddy`, `caddy-crowdsec-bouncer`, `caddy-geoip2`, `caddy-ratelimit` | + | Patch scenario | `A` current pins, `B` no `nebula` pin, `C` no `nebula` pin + retained `expr/ipstore` pins | + | Platform/arch | `linux/amd64`, `linux/arm64` | + | Runtime smoke set | boot Caddy, apply generated config, admin API health, import preview, one secured proxy request path | -## Risk Assessment + Deterministic pass/fail rule: + - **Pass**: all plugin modules compile/load for the matrix cell AND all smoke + tests pass. + - **Fail**: any compile/load error, missing module, or smoke failure. -### Key Risks + Promotion criteria: + - PR-1 promotion requires 100% pass for Scenario A on both architectures. + - Scenario B/C may progress only as candidate evidence; they cannot promote to + default unless all hard retirement gates pass. +4. Validate generated binary dependencies from CI/local: + - verify `expr`, `ipstore`, `nebula`, `smallstep/certificates` versions +5. Validate runtime config application path: + - `backend/internal/caddy/manager.go` → `ApplyConfig(ctx)` + - `backend/internal/caddy/config.go` → `GenerateConfig(...)` +6. Run Caddy package tests and relevant integration tests: + - `backend/internal/caddy/*` + - security middleware integration paths that rely on Caddy behavior -1. **Semantic risk (low):** updating tests could mask an intended behavior - change if malformed URL permissiveness was deliberate. -2. **Coverage risk (low):** test expectation changes may alter branch coverage - marginally but should not threaten gate based on current context. -3. **Regression risk (low):** service runtime behavior remains unchanged in the - preferred path. +### Phase 3: Security hardening and vulnerability posture updates -### Mitigations +Objective: translate upstream advisories into Charon policy and tests. -- Keep change surgical to two table entries. -- Preserve existing invalid-character rejection coverage. -- Require full service package run plus coverage script before merge. +1. Add/adjust regression tests for advisory-sensitive behavior in + `backend/internal/caddy` and integration test suites, especially: + - host matcher behavior with large host lists + - escaped path matcher handling + - admin API cross-origin assumptions +2. Update security documentation and operational guidance: + - identify which advisories are mitigated by upgrade alone + - identify deployment assumptions (e.g., local admin API exposure) +3. Introduce watchlist process for RESERVED CVEs pending NVD enrichment: + - monitor Caddy advisories and module-level disclosures weekly -## Rollback Plan +### Phase 4: Frontend and API exposure decisions (only if justified) -If maintainer/product decision confirms permissive malformed URL handling is -required: +Objective: decide whether 2.11.x features merit UI controls. -1. Revert the test expectation update commit. -2. Implement minimal service normalization change in - `backend/internal/services/proxyhost_service.go`. -3. Add explicit tests documenting the accepted malformed-input behavior and - retain strict negative tests for illegal hostname characters. -4. Re-run targeted validation commands and coverage gate. +1. Evaluate additions to existing `SystemSettings` UX only (no new page): + - optional advanced toggles for keepalive tuning and trusted proxy unix scope +2. Add backend settings keys and mapping only where persisted behavior is + needed: + - settings handler support in + `backend/internal/api/handlers/settings_handler.go` + - propagation to config generation in `GenerateConfig(...)` +3. If no high-value operator need is proven, keep features backend-default and + document rationale. + +### Phase 5: Validation, docs, and release readiness + +Objective: ensure secure, reversible, and auditable rollout. + +1. Re-run full DoD sequence (E2E, patch report, security scans, coverage). +2. Update architectural docs if behavior/config model changes. +3. Publish release decision memo: + - accepted changes + - rejected/deferred UX features + - retained/removed patches with evidence ## PR Slicing Strategy -Decision: **Single PR**. +### Decision -Rationale: +Use **multiple PRs (PR-1/PR-2/PR-3)**. -- Scope is tightly bounded to one service test suite and one failure cluster. -- Preferred remediation is test-only with low rollback complexity. -- Review surface is small and dependency-free. +Reasoning: -Contingency split trigger: +1. Work spans infra/build security + backend runtime + potential frontend UX. +2. Caddy is a blast-radius-critical dependency; rollback safety is mandatory. +3. Review quality and CI signal are stronger with isolated, testable slices. -- Only split if product intent forces service logic change, in which case: - - PR-1: test expectation alignment rollback + service behavior decision record - - PR-2: minimal service correction + adjusted tests +### PR-1: Compatibility and evidence foundation -## Config/Infra File Impact Review +Scope: -Reviewed for required updates: +- `Dockerfile` Caddy candidate bump (and temporary feature branch matrix toggles) +- CI/workflow compatibility instrumentation if needed +- compatibility report artifacts and plan-linked documentation -- `.gitignore` -- `.dockerignore` -- `codecov.yml` -- `Dockerfile` +Dependencies: -Planned changes: **None required** for this focused backend test-remediation -scope. +- None + +Acceptance criteria: + +1. Caddy 2.11.1 compiles with existing plugin set under at least one stable + patch scenario. +2. Compatibility gate matrix (plugin × patch scenario × platform/arch × runtime + smoke set) executed with deterministic pass/fail output and attached evidence. +3. Binary module inventory report generated and attached. +4. No production behavior changes merged beyond compatibility scaffolding. + +Release guard (mandatory for PR-1): + +- Candidate tag only (`*-rc`/`*-candidate`) is allowed. +- Release pipeline exclusion is required; PR-1 artifacts must not be eligible + for production release jobs. +- Promotion to releasable tag is blocked until PR-2 security/retirement gates + pass. + +Rollback notes: + +- Revert `Dockerfile` arg changes and instrumentation only. + +### PR-2: Security patch posture + patch retirement decision + +Scope: + +- finalize retained/removed `go get` patch lines in `Dockerfile` +- update security tests/docs tied to six Caddy advisories +- tighten/confirm admin API exposure assumptions + +Dependencies: + +- PR-1 evidence + +Acceptance criteria: + +1. Decision logged for each patch (`expr`, `ipstore`, `nebula`) with rationale. +2. Advisory coverage matrix completed with Charon applicability labels. +3. Security scans clean at required policy thresholds. + +Rollback notes: + +- Revert patch retirement lines and keep previous pinned patch model. + +### PR-3: Optional UX/API exposure and cleanup + +Scope: + +- only approved high-value settings exposed in existing settings surface +- backend mapping and frontend wiring using existing settings flows +- docs and translations updates if UI text changes + +Dependencies: + +- PR-2 must establish stable runtime baseline first + +Acceptance criteria: + +1. No net-new page; updates land in existing `SystemSettings` domain. +2. E2E and unit tests cover newly exposed controls and defaults. +3. Deferred features explicitly documented with rationale. + +Rollback notes: + +- Revert UI/API additions while retaining already landed security/runtime upgrades. + +## Config File Review and Proposed Updates + +### Dockerfile (required updates) + +1. Update `ARG CADDY_VERSION` target to `2.11.1` after PR-1 gating. +2. Reassess and potentially remove stale `nebula` pin in caddy-builder stage + if matrix build proves compatibility and security posture improves. +3. Keep `expr`/`ipstore` patch enforcement until binary inspection proves + upstream transitive versions are consistently non-vulnerable. + +### .gitignore (suggested updates) + +No mandatory update for rollout, but recommended if new evidence artifacts are +generated in temporary paths: + +- ensure transient compatibility artifacts are ignored (for example, + `test-results/caddy-compat/**` if used). + +### .dockerignore (suggested updates) + +No mandatory update; current file already excludes heavy test/docs/security +artifacts and keeps build context lean. Revisit only if new compatibility +fixture directories are introduced. + +### codecov.yml (suggested updates) + +No mandatory change for version upgrade itself. If new compatibility harness +tests are intentionally non-coverage-bearing, add explicit ignore patterns to +avoid noise in project and patch coverage reports. + +## Risk Register and Mitigations + +1. Plugin/API incompatibility with Caddy 2.11.1 + - Mitigation: matrix compile + targeted runtime tests before merge. +2. False confidence from scanner-only dependency policies + - Mitigation: combine advisory-context review with binary-level inspection. +3. Behavioral drift in reverse proxy/matcher semantics + - Mitigation: baseline E2E + focused security regression tests. +4. UI sprawl from exposing too many Caddy internals + - Mitigation: only extend existing settings surface when operator value is + clear and validated. ## Acceptance Criteria -1. `TestProxyHostService_ValidateHostname` passes, including malformed URL - subtests. -2. `go test ./backend/internal/services -run TestProxyHostService -v` passes. -3. `go test ./backend/internal/services -v` passes. -4. `bash scripts/go-test-coverage.sh` passes final gate. -5. Root cause is documented as expectation drift vs. service behavior drift, and - chosen path is explicitly recorded. +1. Charon builds and runs with Caddy 2.11.1 and current plugin set under + deterministic CI validation. +2. A patch disposition table exists for `expr`, `ipstore`, and `nebula` + (retain/remove/replace + evidence). +3. Caddy advisory applicability matrix is documented, including exploitability + notes for Charon deployment model. +4. Any added settings are mapped end-to-end: + frontend state → API payload → persisted setting → `GenerateConfig(...)`. +5. E2E, security scans, and coverage gates pass without regression. +6. PR-1/PR-2/PR-3 deliverables are independently reviewable and rollback-safe. + +## Handoff + +After approval of this plan: + +1. Delegate PR-1 execution to implementation workflow. +2. Require evidence artifacts before approving PR-2 scope reductions + (especially patch removals). +3. Treat PR-3 as optional and value-driven, not mandatory for the security + update itself.