M4 parity: read-only effective-configuration page (/admin/config) (#245)#263
Conversation
Adds an admin-only view of the resolved runtime configuration — parity with the sibling apps' effective-config page. - services/effective_config.snapshot(session): introspects the pydantic Settings AND the six admin-editable DB settings rows (Audit/Proxy/MISP/Webhook/AI/OIDC), emitting one row per operationally-meaningful field with a provenance: database (a settings row is authoritative) / environment (model_fields_set) / built-in default. - Secrets never cross the boundary: an explicit secret set is coerced to a plain set/not-set string server-side — no value or prefix is serialised. - Validation block re-runs the prod boot-guards (config._guard_production checks) non-fatally to list every issue; advisories surface the startup warnings (no-login-path, console-email-in-prod, in-memory-rate-limit-in-prod); feature tiles show environment/AI backend/enabled SSO providers/dev-login/rate-limit/ email/RSS/MISP/webhook/Typst-available. - Read-only /admin/config route (no model, no save) + template + rail/jump/icon. CSP-safe Alpine text filter (configFilter in tags.js; rows carry data-search) — passes the frontend-assets invariants. Tests: provenance layering (db/env/default), secret redaction (no value leaks), validation reflects the prod guards, admin-only gating (analyst 403), and the page renders a status pill not the secret. Docs updated. Closes #245 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
IcebergAutoReview
Verdict: request_changes
The admin route and secret redaction are sound, but the effective-configuration snapshot is materially incomplete and reports incorrect provenance for some environment-only settings.
Findings
- Blocking — src/iceberg/services/effective_config.py:87-150 hard-codes only a small subset of the effective configuration despite README.md:430-433 promising “every value.” Security-relevant settings omitted include rate_limit_enabled/fail_open and all thresholds, AuditSettings.http_verify_tls/min_severity, MISPSettings.verify_tls and distribution defaults, ProxySettings.no_proxy, plus webhook format/timeout and OIDC client IDs, locators, claims, and role maps. An operator can therefore receive an apparently valid snapshot while important protections such as TLS verification or rate limiting differ from expectations. Include the operational fields from Settings and all six resolved DB rows, with a regression test that detects future omissions.
- Blocking — provenance is incorrect in src/iceberg/services/effective_config.py:94-103. OIDC client secrets are explicitly environment-only but are added through db(), so every one is labeled “database.” Additionally, FORWARDED_ALLOW_IPS at line 91 reads Settings.forwarded_allow_ips and model_fields_set, while the real production guard and Uvicorn consume the unprefixed FORWARDED_ALLOW_IPS environment variable; deployments using the documented Docker/Kubernetes setting will display the built-in value and provenance instead of the effective value. Resolve each through its actual source and add focused provenance tests.
Validation
- Inspected the complete main...HEAD diff and affected Settings, DB settings models, resolvers, production guards, route authorization, template, and tests.
timeout 120s uv run pytest -n0 -q tests/test_effective_config.pycould not start because uv attempted to create.venvin the read-only review checkout. No test code executed; current-head GitHub CI is reported green.
Residual risks / optional notes
- Local runtime validation was unavailable due to the read-only checkout; findings are established directly from the source paths and documented deployment configuration.
Automated review by Codex 266b0775e2c7 using IcebergAutoReview.
…(review) Addresses the two blocking findings on #245. - Comprehensive coverage: the snapshot now emits one row for EVERY Settings field AND every field on all six DB settings rows (Audit/Proxy/MISP/Webhook/ AI/OIDC) — no more hand-curated subset. Previously-missing security-relevant settings (rate-limit thresholds/fail-open, audit http_verify_tls/min_severity, MISP verify_tls + event defaults, proxy no_proxy, webhook format/timeout, and the full OIDC per-provider client-id/locator/claim/role-map set) are included. A new regression test asserts every Settings field + every DB column appears. - Correct provenance: * OIDC client secrets are env-only, so they resolve through the Settings layer (environment / built-in default) — no longer mislabeled "database". * FORWARDED_ALLOW_IPS now reflects the UNPREFIXED env var that the prod guard and uvicorn actually consume (not the ICEBERG_-prefixed Settings field). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
IcebergAutoReview
Verdict: approve
Both prior blockers are resolved. The snapshot now covers every Settings field and all operational fields from the six database settings models, correctly handles unprefixed FORWARDED_ALLOW_IPS, and labels environment-only OIDC secrets with environment/default provenance. No regressions were identified in the follow-up delta.
Findings
- No blocking findings.
Validation
- Inspected git diff 266b077..HEAD and affected settings models/resolvers.
- Verified SECRET_FIELDS covers all current Settings-held credentials and tokens.
- Ran git diff --check successfully.
- Attempted timeout 120s uv run pytest -n0 -q tests/test_effective_config.py; no tests executed because the read-only checkout prevented creation of .venv.
Residual risks / optional notes
- Local runtime validation remained unavailable due to the read-only checkout; current-head GitHub CI is reported fully green and is the authoritative broad validation baseline.
Automated review by Codex a341a38903fd using IcebergAutoReview.
Fourth PR of milestone M4. Adds an admin-only view of the resolved runtime configuration — parity with the sibling apps' effective-config page. Read-only: no model, no save path.
What it shows
Settingsand the six admin-editable DB settings rows (Audit/Proxy/MISP/Webhook/AI/OIDC), each with a provenance pill:database(a settings row is authoritative) /environment(model_fields_set) /built-in default.set/not setstatus server-side; no value or prefix is ever serialised.config._guard_production's checks) non-fatally to list every issue (insecure key, SQLite-in-prod, wildcardFORWARDED_ALLOW_IPS), plus advisories for the startup warnings (no-login-path, console-email-in-prod, in-memory-rate-limit-in-prod).configFilterintags.js; rows carry adata-searchattribute — no JSON island needed). Admin-only rail link.Tests / gates
tests/test_effective_config.py: provenance layering (db/env/default), secret redaction (asserts no secret value/prefix leaks), validation reflects the prod guards, admin-only gating (analyst 403), page renders a status pill not the secret.ruff/bandit/vulture/mypy/djlint/biomeall clean.Closes #245
🤖 Generated with Claude Code