Phase 5 - Authentication & API Security
Backend Security Audit - Sprint 1
A full security audit of the backend code was performed on 04/05/2026. The following findings were identified and fixed.
Findings & Status
| # | File | Issue | Severity | Status |
|---|---|---|---|---|
| 1 | ProjectController.java |
GET /projects had no @PreAuthorize - any authenticated user could list all projects (IDOR) |
Critical | Fixed |
| 2 | ReagentController.java |
GET /reagents and GET /reagents/{id} had no @PreAuthorize |
Critical | Fixed |
| 3 | SecurityConfig.java |
Swagger UI exposed without auth in production | High | Fixed |
| 4 | application-prod.yaml |
JWT issuer-uri using HTTP and localhost in production config |
Critical | Fixed |
| 5 | SecurityConfig.java |
No CORS configuration defined | Medium | Fixed |
| 6 | application.yaml |
Actuator prometheus endpoint exposed without role restriction | Medium | Fixed |
Fixes Applied
Authorization on read endpoints:
// GET /projects - restricted to authenticated users
@PreAuthorize("@authz.isUser(authentication)")
public List<ProjectResponse> findAll() { ... }
// GET /reagents - restricted to authenticated users
@PreAuthorize("@authz.isUser(authentication)")
public List<ReagentResponse> findAll() { ... }
CORS configuration with allowlist:
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(allowedOrigins); // injected from env
config.setAllowedMethods(List.of("GET", "POST", "PATCH", "DELETE", "OPTIONS"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
config.setAllowCredentials(true);
...
}
Swagger disabled in production:
Actuator restricted to ADMIN:
JWT issuer-uri via environment variable:
Authentication Architecture
AliQuest uses a double RBAC approach:
- Keycloak SSO - Core organisation-level authentication and authorisation via JWT
- Internal Authorization Service - Project-level RBAC (VIEWER, RESEARCHER, MAINTAINER roles)
Hardware vending machines authenticate as Keycloak clients via client ID and secret, bound to azp claim in the JWT.
Frontend Auth Guards
The frontend uses ProtectedRoute components to block unauthorised access:
- Researchers are blocked from:
/users,/settings,/reagent/edit,/reagent/add,/project/edit,/project/add - Security logging on every blocked attempt
- Unauthorized page shown when access is denied
- Mock auth in
auth.ts- ready to wire to KC JWT
Pending
- Wire frontend
auth.tsto real Keycloak JWT once KC config is finalised - Input validation with
zodon all frontend forms - IDOR fix on user listing endpoint in backend (flagged by Jabbar, to be fixed)
- Rate limiting on auth endpoints - to be implemented at Traefik level