Access Request and Provisioning System
Spring Boot backend for submitting, approving, provisioning, revoking, expiring, and auditing access to internal resources, with role-based authorization, JWT authentication, Flyway-managed PostgreSQL schema migrations, and automated test coverage.
Problem
Internal access management usually involves ad hoc approval steps, weak audit trails, and inconsistent lifecycle handling. The goal was to build a backend that models access requests more realistically, including approval workflows, provisioning state changes, expiry handling, and role-based visibility rules.
Constraints
- The project needed to demonstrate real Spring Boot backend work instead of generic CRUD.
- Authorization rules had to differ for admins, managers, and employees.
- Schema changes needed to be versioned from the start with Flyway.
- The project needed meaningful unit and integration tests against PostgreSQL.
Architecture
- Layered Spring Boot architecture with controllers, services, repositories, DTOs, mappers, security, scheduler, and exception handling.
- Spring Security and JWT authenticate users and enforce role-based access rules across endpoints.
- Spring Data JPA manages persistence for users, resources, access requests, approvals, provisioning events, and audit logs.
- Flyway migrations define and evolve the PostgreSQL schema instead of relying on Hibernate schema generation.
- A scheduled expiry service transitions overdue provisioned access requests to expired state and records lifecycle events.
- Integration tests use Testcontainers PostgreSQL to validate persistence, security, and request lifecycle behavior against a real database.
Key decisions
Modeled the workflow as explicit state transitions
Used submitted, approved, rejected, provisioned, revoked, and expired states so the backend reflects a believable access lifecycle instead of a flat CRUD model.
Separated approval and provisioning history from the main request record
Stored approvals and provisioning events as dedicated entities so auditability and lifecycle history remain clearer than packing everything into one table.
Used JWT with role-aware request visibility rules
Employees can only view their own requests, managers can view their own and direct reports’ requests, and admins can view and manage the full system.
Used Flyway and PostgreSQL from the start
Kept schema evolution explicit and production-leaning instead of relying on in-memory database shortcuts or ad hoc table creation.
Risks and mitigations
Access control bugs could expose requests to the wrong users
Authorization was enforced in the application layer and verified with integration tests covering role-based visibility and action restrictions.
Workflow code can become fragile when state transitions are not tightly controlled
Service-layer rules reject invalid transitions such as provisioning before approval or revoking before provisioning.
Next steps
- Add refresh-token support or session hardening if the project is expanded further
- Polish API response pagination structure if a stable DTO-based page format is needed
- Add more search and filtering options for audit logs and request history
- Prepare a deployed demo or example Postman collection for easier portfolio review