Skip to content

feat: mount LiveDashboard under /admin in production - #305

Merged
zorn merged 4 commits into
mainfrom
zorn/issue-302-admin-live-dashboard
Oct 20, 2026
Merged

zorn merged 4 commits into
mainfrom
zorn/issue-302-admin-live-dashboard

Conversation

@zorn

@zorn zorn commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Closes #302

Phoenix LiveDashboard now runs in production at /admin/dashboard, behind the same basic auth as /admin/ballots. It joins observer_cli from #301 as the second way to inspect a live node, and the one that needs no Render Shell.

A request without the admin login gets a 401, so the dashboard is no more open than the admin ballot index. A revert removes the route and the new dependency, and nothing else depends on them. /dev/dashboard is gone, and /dev/mailbox still works. The suite passes with 193 tests, three of them new in live_dashboard_test.exs.

The dashboard needs two CSP changes to load cleanly

The dashboard's scripts get the per-request nonce through csp_nonce_assign_key: %{script: :csp_nonce} (router.ex:73). Only script-src carries a nonce, so styles do not get one. A test asserts that every <script> on the page carries the nonce from the response header. It failed when I removed the option.

The dashboard's CSS also embeds its font as a data: URL, which default-src 'self' blocked. The policy now allows font-src 'self' data: (router.ex:34). With both changes, Home and Processes load in headless Chromium with no console errors.

Ecto Stats works, and OS Data stays off

ecto_psql_extras backs the Ecto Stats page. It shows table and index sizes, index usage, bloat, locks, and long-running queries. Since #304 closed the database's allow list, a remote IEx shell was the only other way to see these. LiveDashboard hides the library's destructive kill_all, so the page only reads.

:os_mon stays out. Inside a container, memsup reports the host's memory rather than the 512 MB limit, so the OS Data page would mislead. Render's service charts already show CPU and memory.

Try it

Run mix phx.server, open http://localhost:4000/admin/dashboard, and sign in as flick-admin / unsafe-password. CLAUDE.md's Observability section now describes the route.

LiveDashboard Home page at /admin/dashboard in development

Worth a reviewer's attention

  • font-src 'self' data: applies to the whole app, not just /admin. A per-scope policy would be tighter, but fonts cannot run script, so the global rule is simpler and loses little.
  • Ecto Stats' "outliers" and "calls" tables need pg_stat_statements. I don't know whether flick_prod has it enabled. If it does not, those two tables show an error and the rest still work.
  • The dashboard does not show process state, so the issue's concern about ballot secrets does not arise. Its Processes page reads Process.info/2 for the dictionary, links, and stack trace, not :sys.get_state, and no page dumps ETS contents. CLAUDE.md still says to keep the dashboard in the /admin scope, because it exposes the node's internals.
  • I kept the router comment "Enable Swoosh mailbox preview in development". The prose review flagged it as restating the route. I kept it because the if checks :dev_routes, and the comment is what says that means development.
  • Production checks happen after deploy. Confirm that Home and Processes load at /admin/dashboard and that the console shows no CSP violations.

zorn added 3 commits October 20, 2026 11:58
Moves the dashboard from /dev/dashboard to /admin/dashboard, behind the
admin basic auth, and stamps its scripts with the CSP nonce. Adds
ecto_psql_extras so the Ecto Stats page works.

Closes #302
Copilot AI balanced review requested due to automatic review settings October 20, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Static review identified no blocking issues; production smoke checks remain a post-deployment step.

No open issues 🎉

What changed in this PR

Makes LiveDashboard available in production behind existing admin authentication, complementing remote-shell diagnostics.

Changes:

  • Moves LiveDashboard to /admin/dashboard, retaining /dev/mailbox.
  • Adds script nonce support, embedded-font permissions, and Ecto Stats dependencies.
  • Adds authentication and CSP tests and updates operational documentation.
File Description
test/​flick_web/​live_dashboard_test.exs Tests authentication, script nonces, and Ecto Stats availability.
mix.lock Locks Ecto Stats dependencies.
mix.exs Adds ecto_psql_extras.
lib/​flick_web/​telemetry.ex Updates the documented dashboard path.
lib/​flick_web/​router.ex Mounts the authenticated dashboard and adjusts CSP.
config/​dev.exs Clarifies the mailbox-only development route comment.
AGENTS.md Documents dashboard access and operational safeguards.

Review effort: Balanced

@zorn
zorn merged commit c9bf6c1 into main Oct 20, 2026
8 checks passed
@zorn
zorn deleted the zorn/issue-302-admin-live-dashboard branch October 20, 2026 16:18
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.

Mount LiveDashboard under /admin in production

2 participants