Add MONITORING_PUBLIC env var to gate monitoring endpoints behind auth
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled

By default /api/v1/monitoring/stats and /api/v1/health-checks/status are
public (current behavior, dashboard needs them pre-login). Users deploying
DashCaddy on the open internet can now set:

  MONITORING_PUBLIC=false

...or add 'monitoring: { public: false }' to config.json to require auth.
This prevents anonymous disclosure of CPU/memory/disk data.

The check uses env var first, then config.json, then defaults to true
(preserves current behavior for existing users).
This commit is contained in:
Hermes
2026-06-10 20:13:53 -07:00
parent 7485772427
commit e40cb35011
+22
View File
@@ -277,6 +277,25 @@ module.exports = function configureMiddleware(app, {
} }
// ── Public routes (bypass TOTP and JWT auth) ── // ── Public routes (bypass TOTP and JWT auth) ──
// Routes here are accessible without authentication. By default the
// monitoring/health-check endpoints are public so the dashboard can
// render widgets before the user logs in. Set MONITORING_PUBLIC=false
// (env var) or `monitoring: { public: false }` (config.json) to require
// auth for these — useful for internet-exposed deployments where
// CPU/memory/disk data is sensitive.
const MONITORING_PUBLIC = (() => {
if (process.env.MONITORING_PUBLIC === 'false') return false;
if (process.env.MONITORING_PUBLIC === 'true') return true;
// Default: check config.json if loaded
try {
const cfg = require('./src/config/site').siteConfig;
if (cfg && cfg.monitoring && typeof cfg.monitoring.public === 'boolean') {
return cfg.monitoring.public;
}
} catch { /* config not loaded yet, use default */ }
return true; // default: public (current behavior, dashboard needs it)
})();
const PUBLIC_ROUTES = [ const PUBLIC_ROUTES = [
{ path: '/health', exact: true }, { path: '/health', exact: true },
{ path: '/api/v1/health', exact: true }, { path: '/api/v1/health', exact: true },
@@ -305,8 +324,11 @@ module.exports = function configureMiddleware(app, {
{ path: '/api/v1/config', exact: true, method: 'GET' }, { path: '/api/v1/config', exact: true, method: 'GET' },
{ path: '/api/v1/services/status', exact: true, method: 'GET' }, { path: '/api/v1/services/status', exact: true, method: 'GET' },
{ path: '/api/v1/system/update-notify', exact: true, method: 'POST' }, { path: '/api/v1/system/update-notify', exact: true, method: 'POST' },
// Monitoring endpoints — only public if MONITORING_PUBLIC is true
...(MONITORING_PUBLIC ? [
{ path: '/api/v1/monitoring/stats', exact: true, method: 'GET' }, { path: '/api/v1/monitoring/stats', exact: true, method: 'GET' },
{ path: '/api/v1/health-checks/status', exact: true, method: 'GET' }, { path: '/api/v1/health-checks/status', exact: true, method: 'GET' },
] : []),
{ path: '/api/v1/version', exact: true, method: 'GET' }, { path: '/api/v1/version', exact: true, method: 'GET' },
]; ];