diff --git a/src/web-server/routes/codex-routes.ts b/src/web-server/routes/codex-routes.ts index e7abaf84..26d26815 100644 --- a/src/web-server/routes/codex-routes.ts +++ b/src/web-server/routes/codex-routes.ts @@ -1,5 +1,6 @@ import type { Request, Response } from 'express'; import { Router } from 'express'; +import { requireLocalAccessWhenAuthDisabled } from '../middleware/auth-middleware'; import { CodexRawConfigConflictError, CodexRawConfigValidationError, @@ -10,6 +11,14 @@ import { } from '../services/codex-dashboard-service'; const router = Router(); +const CODEX_CONFIG_ACCESS_ERROR = + 'Codex configuration endpoints require localhost access when dashboard auth is disabled.'; + +router.use('/config', (req: Request, res: Response, next) => { + if (requireLocalAccessWhenAuthDisabled(req, res, CODEX_CONFIG_ACCESS_ERROR)) { + next(); + } +}); router.get('/diagnostics', async (_req: Request, res: Response): Promise => { try { diff --git a/tests/unit/web-server/api-routes-remote-write-guard.test.ts b/tests/unit/web-server/api-routes-remote-write-guard.test.ts index 730c8a62..e1cbe9d9 100644 --- a/tests/unit/web-server/api-routes-remote-write-guard.test.ts +++ b/tests/unit/web-server/api-routes-remote-write-guard.test.ts @@ -84,6 +84,21 @@ describe('api-routes remote write guard', () => { expect(response.status).toBe(200); }); + it('blocks remote Codex raw config reads when dashboard auth is disabled', async () => { + const response = await fetch(`${baseUrl}/api/codex/config/raw`); + + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ + error: 'Codex configuration endpoints require localhost access when dashboard auth is disabled.', + }); + }); + + it('allows remote Codex diagnostics when dashboard auth is disabled', async () => { + const response = await fetch(`${baseUrl}/api/codex/diagnostics`); + + expect(response.status).toBe(200); + }); + it('blocks remote profile creation when dashboard auth is disabled', async () => { const response = await fetch(`${baseUrl}/api/profiles`, { method: 'POST',