ModuleAuthenticationInterceptor Fail-Closed Rollout
Scope
This document defines the separate follow-up pass to harden
ModuleAuthenticationInterceptor so unmapped /rest/** and /Provider/**
routes do not default to authenticated allow.
This is intentionally split from the immediate controller @PreAuthorize
remediation because it has higher regression risk.
Current Risk
ModuleAuthenticationInterceptor.hasPermissionForUrl(...)currently returnstruefor unmapped REST and provider URLs when the user is authenticated.- Any missing
SystemModuleUrlmapping behaves as fail-open, which can bypass module-based URL restrictions if method security is absent.
Rollout Strategy
Phase 1: Inventory and Impact Analysis
- Enumerate active request mappings under
/rest/**and/Provider/**. - Enumerate current
SystemModuleUrlmappings in the target environment. - Produce a diff:
- mapped endpoints
- unmapped endpoints currently relying on fallback allow
- Classify unmapped endpoints:
- intentionally public/open
- authenticated but role-gated by
@PreAuthorize - unaudited/high-risk
Phase 2: Controlled Fail-Closed Toggle
- Introduce a configuration flag for interceptor behavior:
security.moduleUrl.failOpen(defaulttruefor compatibility)- When disabled (
false), unmapped REST/provider routes return deny unless explicitly allowlisted. - Keep a narrow allowlist for known public routes already expected by
SecurityConfig.
Phase 3: Staging Validation
- Enable fail-closed in staging only.
- Run focused smoke tests for:
- login/session flows
- known public endpoints
- Tier 1 admin endpoints now protected with
@PreAuthorize - analyzer bridge/runtime paths that were carve-outs in Phase 1
- Resolve missing
SystemModuleUrlrows or explicit allowlist entries before production rollout.
Phase 4: Production Rollout
- Enable fail-closed with rollback switch kept available.
- Monitor authorization denials and endpoint error rates.
- Remove temporary allowlist entries once DB mappings and method security are complete.
Required Test Coverage
- Unit tests for
hasPermissionForUrl(...): - mapped allow
- mapped deny
- unmapped allow when
failOpen=true - unmapped deny when
failOpen=false - Integration-level smoke tests proving:
- open endpoints remain reachable
- authenticated users cannot reach unmapped protected routes
- mapped admin routes remain accessible with correct roles
Exit Criteria
- Fail-closed mode runs in staging and production without breaking known valid routes.
- No Tier 1 admin endpoint depends on fallback allow behavior.
- Remaining unmapped endpoints are either intentionally open (documented) or formally mapped.