Below is a complete, enterprise-grade roadmap for implementing Role-Based Access Control (RBAC) in a Spring Boot microservices system (Auth service + Gateway + downstream services). It’s practical, scalable, and production-ready.


🚀 Enterprise RBAC Roadmap (Spring Boot)

🧭 Phase 0 — Define Your Authorization Model

Decide early:

✔ Core concepts

  • User → system identity
  • Role → group of permissions (ADMIN, USER, MANAGER)
  • Permission (Authority) → fine-grained action (READ_USER, CREATE_ORDER, etc.)
  • Tenant (optional) → for multi-tenant systems

✔ Naming convention (very important)

ROLE_ADMIN
ROLE_MANAGER
ROLE_USER

PERM_USER_READ
PERM_USER_WRITE
PERM_REPORT_VIEW
PERM_REPORT_EXPORT

🏗 Phase 1 — Database Design (JPA Entities)

🧩 Tables

users
roles
permissions
user_roles
role_permissions

📦 Entity Model

User

@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;

    private String username;
    private String password;
    private String tenantId;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_roles")
    private Set<Role> roles;
}

Role

@Entity
@Table(name = "roles")
public class Role {
    @Id
    private Long id;

    private String name; // ROLE_ADMIN

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "role_permissions")
    private Set<Permission> permissions;
}

Permission

@Entity
@Table(name = "permissions")
public class Permission {
    @Id
    private Long id;

    private String name; // PERM_USER_READ
}

🔐 Phase 2 — JWT Design (Auth Service)

Token should contain:

{
  "sub": "akshay",
  "tenantId": "T1",
  "roles": ["ADMIN"],
  "permissions": ["PERM_USER_READ","PERM_USER_WRITE"]
}

Token creation

Jwts.builder()
    .setSubject(username)
    .claim("tenantId", tenantId)
    .claim("roles", roles)
    .claim("permissions", permissions)
    .signWith(key)
    .compact();

🔎 Phase 3 — JWT Parsing (Resource Services)

Inside your JWT filter:

Claims claims = jwtUtil.extractClaims(token);

String username = claims.getSubject();
String tenantId = claims.get("tenantId", String.class);

List<String> roles = claims.get("roles", List.class);
List<String> permissions = claims.get("permissions", List.class);

List<GrantedAuthority> authorities = new ArrayList<>();

roles.forEach(r -> authorities.add(new SimpleGrantedAuthority("ROLE_" + r)));
permissions.forEach(p -> authorities.add(new SimpleGrantedAuthority(p)));

UsernamePasswordAuthenticationToken auth =
        new UsernamePasswordAuthenticationToken(username, null, authorities);

auth.setDetails(tenantId);

SecurityContextHolder.getContext().setAuthentication(auth);

🛡 Phase 4 — Security Configuration

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http.csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth

            .requestMatchers("/auth/**").permitAll()

            .requestMatchers("/api/admin/**").hasRole("ADMIN")

            .requestMatchers("/api/users/**")
                .hasAnyRole("USER","ADMIN")

            .requestMatchers("/api/reports/**")
                .hasAuthority("PERM_REPORT_VIEW")

            .anyRequest().authenticated()
        )
        .sessionManagement(s -> 
            s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );

    return http.build();
}

🧠 Phase 5 — Method-Level Authorization

Enable:

@EnableMethodSecurity

Use in service/controller:

@PreAuthorize("hasRole('ADMIN')")
public void deleteUser() {}

@PreAuthorize("hasAuthority('PERM_USER_WRITE')")
public void updateUser() {}

@PreAuthorize("#tenantId == authentication.details")
public void accessTenantData(String tenantId) {}

🧩 Phase 6 — Multi-Tenant RBAC

Store tenantId in:

  • JWT claim
  • Database user table

Then validate:

@PreAuthorize("#tenantId == authentication.details")

OR create TenantContext (ThreadLocal)


🌐 Phase 7 — API Gateway Security (Recommended)

In gateway:

✔ Validate JWT
✔ Extract roles
✔ Forward headers:

X-User
X-Roles
X-Tenant

Downstream services:

  • trust gateway
  • no need to parse JWT again (optional optimization)

🔄 Phase 8 — Role Management APIs

Create admin APIs:

POST /roles
POST /permissions
POST /roles/{id}/permissions
POST /users/{id}/roles

🧪 Phase 9 — Testing Strategy

✔ Unit tests

  • JWT parsing
  • permission mapping

✔ Integration tests

  • endpoint access with roles

✔ Security tests

  • invalid token
  • missing roles
  • tenant mismatch

📊 Phase 10 — Auditing & Logging

Store logs:

userId
role
action
endpoint
timestamp
tenantId

Use tools like:

  • ELK stack
  • Grafana Loki

🧯 Phase 11 — Production Hardening

✔ Use RSA instead of shared secret

  • Auth service signs with private key
  • services verify using public key

✔ Token expiry

access token15 min
refresh token7 days

✔ Rate limiting

At Gateway level


📦 Phase 12 — Folder Structure

security/
  JwtUtil
  JwtAuthenticationFilter
  SecurityConfig
  CustomUserDetails

auth/
  AuthController
  TokenService

rbac/
  RoleService
  PermissionService

🏆 Final Enterprise Architecture

Client

API Gateway (JWT validation, rate limit)

User Service (RBAC enforcement)

Database

🎯 Enterprise Best Practices Checklist

✔ Use roles + permissions together
✔ Store authorities in JWT
✔ Use @PreAuthorize for business logic
✔ Use stateless authentication
✔ Use RSA keys (no shared secrets)
✔ Implement multi-tenant isolation
✔ Log every sensitive action
✔ Centralize auth in Auth Service


Read other awesome articles in Medium.com or in akcoding’s posts.

OR

Join us on YouTube Channel

OR Scan the QR Code to Directly open the Channel 👉

AK Coding YouTube Channel

Share with