RBAC & Roles
OpenGate IAM implements Role-Based Access Control (RBAC) via opengate-rbac-service (port 8084). Roles are scoped per realm and embedded in JWT access tokens.
On this page
- Concepts
- Role Hierarchy
- Creating Roles
- Assigning Roles to Users
- Composite Roles
- Groups
- Enforcing Roles in Spring Boot
Concepts
| Concept | Description |
|---|---|
| Realm Role | A named permission scoped to a realm (e.g. ROLE_ADMIN) |
| Composite Role | A role that inherits permissions from other roles |
| Group | A collection of users that share roles |
| User-Role Mapping | Associates a user with one or more roles |
Role Hierarchy
┌─────────────────────────────────────────────┐
│ Realm: acme-corp │
│ │
│ ROLE_ADMIN (composite) │
│ ├── ROLE_MANAGER (composite) │
│ │ ├── ROLE_EDITOR │
│ │ └── ROLE_VIEWER │
│ └── ROLE_DEVELOPER │
│ │
│ ROLE_BILLING │
│ ROLE_READ_ONLY │
└─────────────────────────────────────────────┘
Creating Roles
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "ROLE_EDITOR", "description": "Can create and edit content" }' \
http://localhost:8080/api/rbac/roles?realm=acme-corpAssigning Roles to Users
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "userId": "usr_abc123", "roleIds": ["role-uuid-1", "role-uuid-2"] }' \
http://localhost:8080/api/rbac/user-role-mappingsRoles are automatically embedded in the user's JWT on next login:
{
"sub": "usr_abc123",
"realm": "acme-corp",
"roles": ["ROLE_EDITOR", "ROLE_VIEWER"],
"email": "alice@acme.com"
}Composite Roles
A composite role automatically grants all roles it contains.
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "ROLE_MANAGER",
"description": "Inherits editor and viewer permissions",
"composite": true
}' \
http://localhost:8080/api/rbac/roles?realm=acme-corpGroups
Groups let you assign roles to many users at once.
# Create a group
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "editors-team", "realmName": "acme-corp" }' \
http://localhost:8080/api/rbac/groups
# Add user to group
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "userId": "usr_abc123" }' \
"http://localhost:8080/api/rbac/groups/{groupId}/members"Enforcing Roles in Spring Boot
ContentController.javajava
@RestController
@RequestMapping("/api/content")
public class ContentController {
@GetMapping
@PreAuthorize("hasRole('ROLE_VIEWER')")
public List<Content> list() { ... }
@PostMapping
@PreAuthorize("hasRole('ROLE_EDITOR')")
public Content create(@RequestBody ContentDto dto) { ... }
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void delete(@PathVariable String id) { ... }
}Enable method-level security in your config:
SecurityConfig.javajava
@Configuration
@EnableMethodSecurity // enables @PreAuthorize, @PostAuthorize
public class SecurityConfig { }Role claim extraction
Spring Security expects roles in the roles JWT claim by default. If your JWT uses a different claim name, configure a custom JwtAuthenticationConverter.