codex-bais-final4-20260713-.../auth-migration/INVARIANTS.md

3.4 KiB

Authentication & Authorization Invariants — auth-migration

1. Authentication Rules

ID Rule Trigger Expected Behavior Error Code
AUTH-001 JWT must contain sub claim Any protected endpoint Reject with 401 if sub missing/empty AUTH_MISSING_SUB
AUTH-002 JWT exp must be in future Any protected endpoint Reject with 401 if expired AUTH_TOKEN_EXPIRED
AUTH-003 JWT signature must verify against secret Any protected endpoint Reject with 401 if signature invalid AUTH_INVALID_SIGNATURE
AUTH-004 Bearer token required in Authorization header Any protected endpoint Reject with 401 if header missing AUTH_MISSING_TOKEN
AUTH-005 Token format must be Bearer <token> Any protected endpoint Reject with 401 if malformed AUTH_MALFORMED_TOKEN

2. Authorization Rules

ID Rule Scope Expected Behavior Error Code
AUTH-010 ADMIN role required for user management /api/admin/** Reject with 403 if not ADMIN AUTH_FORBIDDEN_ADMIN
AUTH-011 Resource owner or ADMIN can modify /api/users/{id}/** Reject with 403 if neither AUTH_FORBIDDEN_RESOURCE
AUTH-012 Any authenticated user can read public profiles /api/users/public/** Allow 200 if authenticated
AUTH-013 Role hierarchy: ADMIN > MANAGER > USER All role-gated endpoints Higher role inherits lower permissions

3. Error Response Schema

HTTP Status Error Code Response Body Shape
401 AUTH_MISSING_TOKEN {"error":"AUTH_MISSING_TOKEN","message":"Authorization header required","timestamp":<epoch>}
401 AUTH_MALFORMED_TOKEN {"error":"AUTH_MALFORMED_TOKEN","message":"Bearer token format required","timestamp":<epoch>}
401 AUTH_TOKEN_EXPIRED {"error":"AUTH_TOKEN_EXPIRED","message":"Token has expired","timestamp":<epoch>}
401 AUTH_INVALID_SIGNATURE {"error":"AUTH_INVALID_SIGNATURE","message":"Token signature verification failed","timestamp":<epoch>}
401 AUTH_MISSING_SUB {"error":"AUTH_MISSING_SUB","message":"Token missing subject claim","timestamp":<epoch>}
403 AUTH_FORBIDDEN_ADMIN {"error":"AUTH_FORBIDDEN_ADMIN","message":"Admin role required","timestamp":<epoch>}
403 AUTH_FORBIDDEN_RESOURCE {"error":"AUTH_FORBIDDEN_RESOURCE","message":"Not authorized for this resource","timestamp":<epoch>}
ID Rule Behavior
SESS-001 Session cookie HttpOnly Must be true
SESS-002 Session cookie Secure Must be true in production
SESS-003 Session cookie SameSite Must be Lax or Strict
SESS-004 CSRF token required for state-changing ops POST/PUT/DELETE without CSRF → 403

5. Migration Checklist

  • Spring Security filter chain preserves order: JWT filter before session filter
  • @PreAuthorize annotations match existing role-gate logic
  • AuthenticationEntryPoint returns exact error schema (AUTH_* codes)
  • AccessDeniedHandler returns exact error schema (AUTH_FORBIDDEN_* codes)
  • Cookie attributes (HttpOnly, Secure, SameSite) set via CookieSecurityConfigurer
  • CSRF protection enabled for state-changing endpoints
  • Role hierarchy bean RoleHierarchyImpl wired with ADMIN > MANAGER > USER