diff --git a/packages/gateway/src/config/routing-rules.yaml b/packages/gateway/src/config/routing-rules.yaml index 7defb1e..c35cca2 100644 --- a/packages/gateway/src/config/routing-rules.yaml +++ b/packages/gateway/src/config/routing-rules.yaml @@ -1318,8 +1318,8 @@ routing_rules: output_format: json requires_fact_check: false validators: [schema, length] - callers: [ctx-health, internal] - fallback_chain: [ctxhealer:latest, qwen2.5:14b] + callers: [ctx-health, magatama-infra-health, infra-health, internal] + fallback_chain: [ctxhealer:latest, qwen2.5:14b, qwen2.5:3b] ctx_health_alert: model: qwen2.5:14b diff --git a/packages/gateway/src/security/tls-config.ts b/packages/gateway/src/security/tls-config.ts index caa73cd..354102c 100644 --- a/packages/gateway/src/security/tls-config.ts +++ b/packages/gateway/src/security/tls-config.ts @@ -107,6 +107,12 @@ export async function registerHTTPSRedirectMiddleware(server: FastifyInstance) { return; } + // Skip for localhost/loopback callers (infra-health, fix-engine, internal services) + const reqHost = String(request.headers['host'] ?? ''); + if (reqHost.startsWith('localhost') || reqHost.startsWith('127.0.0.1')) { + return; + } + // Check if connection is not secure // In production, X-Forwarded-Proto is set by reverse proxy (Cloudflare) const isSecure = @@ -126,11 +132,14 @@ export async function registerHTTPSRedirectMiddleware(server: FastifyInstance) { */ export async function registerSecurityHeadersMiddleware(server: FastifyInstance) { server.addHook('onSend', async (request, reply) => { - // Content Security Policy for the self-contained dashboard UI. - reply.header( - 'Content-Security-Policy', - "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" - ); + // Content Security Policy — route handlers may set a narrower CSP before this hook. + // Default allows 'unsafe-inline' for the dashboard UI. + if (!reply.getHeader('Content-Security-Policy')) { + reply.header( + 'Content-Security-Policy', + "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" + ); + } // Prevent clickjacking reply.header('X-Frame-Options', 'DENY');