Commit 366d775
Implement KeycloakAttributeSyncScheduler and bidirectional user synchronization with protocol mapper support and UI-driven custom attribute mapping access control (#36)
* Initial plan
* Fully implement KeycloakAttributeSyncScheduler and user synchronization
- Implemented full sync of all users from Keycloak with pagination support
- Implemented sync of specific user from Keycloak
- Added attribute filtering to exclude internal Keycloak attributes
- Enhanced KeycloakService with methods for listing users, getting users, creating users, and updating attributes
- Modified UserService to sync attributes from Keycloak when new users are created
- Added method to create users in Keycloak when they are created in Sentrius
- Added comprehensive tests for KeycloakAttributeSyncScheduler
- Added comprehensive tests for KeycloakService
- All tests passing
Co-authored-by: phrocker <[email protected]>
* update
* Add password support for Keycloak user creation in UserApiController
- Enhanced KeycloakService.createUser() with password parameter support
- Added setUserPassword() method to set/reset user passwords in Keycloak
- Updated UserApiController.addUser() to create users in Keycloak with passwords
- Users created through UI now automatically get created in Keycloak with their password
- Password is not temporary, allowing immediate login
- Added 4 new tests for password functionality
- All 17 tests passing in KeycloakServiceTest
Co-authored-by: phrocker <[email protected]>
* uipdate
* Fix attribute handling for Keycloak 22+ user profile compatibility
- Modified createUser() to set attributes AFTER user creation (Keycloak 22+ best practice)
- Attributes are no longer set directly during UserRepresentation.create()
- Instead, attributes are set via updateUserAttributes() after user creation
- This ensures compatibility with Keycloak 22+ User Profile validation
- Enhanced updateUserAttributes() with better error handling and logging
- Updated test to reflect new attribute handling behavior
- All 17 tests passing
Co-authored-by: phrocker <[email protected]>
* Remove attribute writing to Keycloak - attributes must be managed in User Profile
- Removed automatic attribute setting during user creation
- Added deprecation warning to updateUserAttributes() method
- Clarified that custom attributes must be defined in Keycloak User Profile (Admin Console)
- Attributes are READ-ONLY from Sentrius perspective - managed in Keycloak, synced to Sentrius
- Enhanced documentation explaining Keycloak 22+ User Profile workflow
- Updated test to verify attributes are NOT set during user creation
- All 17 tests passing
For Keycloak 22+ User Profile:
1. Define attributes in Keycloak Admin Console > Realm Settings > User Profile
2. Fill in attribute values for users through Keycloak UI
3. Sentrius sync scheduler reads attributes from Keycloak
4. Attributes are stored in Sentrius ABAC system for policy evaluation
Co-authored-by: phrocker <[email protected]>
* Enable bidirectional attribute sync with protocol mappers
- Re-enabled attribute writing to Keycloak (reverted read-only approach)
- Added protocol mappers for common ABAC attributes to realm template:
- department, team_role, clearance_level, location, cost_center, project
- Protocol mappers ensure attributes appear in OIDC tokens
- Updated KeycloakService to set attributes after user creation
- Added syncUserAttributesToKeycloak() method in AttributeManagementService
- Attributes set in Sentrius can now be synced to Keycloak
- Bidirectional sync: Sentrius ↔ Keycloak
- Updated tests to match new behavior
- All tests passing (17 KeycloakService tests, full test suite)
Co-authored-by: phrocker <[email protected]>
* Fix updates
* update
* Fix custom attribute check to pass endpoint parameter
- Fixed checkCustomAttribute() call in AccessControlAspect to include endpoint parameter
- This enables ABAC PolicyEvaluator to properly evaluate custom attributes from database
- Custom attributes defined via ABAC page can now be evaluated within the aspect
- All custom attribute checks now work correctly with both PolicyEvaluator and UserAttributeService
Co-authored-by: phrocker <[email protected]>
* Add database endpoint attribute checking to AccessControlAspect
- Added AttributeAssignmentRepository injection to AccessControlAspect
- Implemented checkDatabaseEndpointAttributes() method to check attributes from database
- Retrieves attributes assigned to endpoints via ABAC page (TargetType.ENDPOINT)
- Validates that users have required attribute values for the endpoint
- Integrates with existing checkCustomAttribute() for consistency
- Now checks BOTH annotation-defined AND database-defined custom attributes
- Attributes defined via ABAC page are now properly evaluated for access control
Co-authored-by: phrocker <[email protected]>
* Fix database endpoint attribute checking to use ABAC policies
- Replaced AttributeAssignment lookup with PolicyEvaluator
- Now properly uses AccessPolicy and PolicyRule to determine endpoint requirements
- PolicyEvaluator evaluates user attributes against policy rules
- Supports complex policy logic (AND/OR combinations, various operators)
- Correctly implements the ABAC workflow:
1. Attribute Definitions - define available attributes
2. User Assignments - assign attribute values to users
3. Access Mappings (Policies) - define rules for endpoint access
- Removed AttributeAssignmentRepository injection (not needed)
- Access Mappings from ABAC page now properly enforced
Co-authored-by: phrocker <[email protected]>
* Fix database endpoint attribute checking to use CustomAttributeMapping
- Replaced PolicyEvaluator with CustomAttributeMappingService
- Now properly queries custom_attribute_mappings table from UI
- CustomAttributeMapping stores endpoint requirements (e.g., /api/v1/chat/** requires department=engineering)
- Integrates with existing checkCustomAttribute() method for validation
- Properly implements UI-driven access control workflow:
1. Admin creates mapping via CustomAttributeMappingController
2. Mapping stored in custom_attribute_mappings table
3. AccessControlAspect retrieves and enforces mappings
- Custom mappings defined via ABAC UI are now properly enforced
Co-authored-by: phrocker <[email protected]>
* Fix custom attribute checking to verify user actually has required attributes
- Fixed checkCustomAttribute() to properly check if user has the required attribute value
- Previously was incorrectly adding the required value to user's context, making all checks pass
- Now correctly:
1. Builds context which loads user's AttributeAssignments from database
2. Checks if user's attribute value matches the required value
3. Returns true only if user actually has the attribute with the required value
- Fixed test file compilation errors (duplicate class definitions)
- Addresses issue where mappings like "clearance_level=low" were found but not validated against user's actual attributes
- All tests passing
Co-authored-by: phrocker <[email protected]>
* commit
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: phrocker <[email protected]>
Co-authored-by: Marc Parisi <[email protected]>1 parent 3fc3b23 commit 366d775
File tree
24 files changed
+2178
-213
lines changed- api/src
- main
- java/io/sentrius/sso/controllers
- api
- abac
- users
- view
- resources
- static/js
- templates
- fragments
- sso
- test/java/io/sentrius/sso/controllers/api/users
- core/src
- main/java/io/sentrius/sso/core
- dto/abac
- services/security
- test/java/io/sentrius/sso/core/services/security
- dataplane/src
- main/java/io/sentrius/sso/core
- model/security
- services
- abac
- test/java/io/sentrius/sso/core
- model/security
- services/abac
- docker/keycloak/realms
- sentrius-chart/templates
24 files changed
+2178
-213
lines changedLines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | | - | |
| 92 | + | |
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| |||
244 | 244 | | |
245 | 245 | | |
246 | 246 | | |
| 247 | + | |
247 | 248 | | |
248 | 249 | | |
249 | 250 | | |
| |||
Lines changed: 48 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| |||
76 | 77 | | |
77 | 78 | | |
78 | 79 | | |
| 80 | + | |
79 | 81 | | |
80 | 82 | | |
81 | 83 | | |
| |||
100 | 102 | | |
101 | 103 | | |
102 | 104 | | |
103 | | - | |
| 105 | + | |
104 | 106 | | |
105 | 107 | | |
106 | 108 | | |
| |||
113 | 115 | | |
114 | 116 | | |
115 | 117 | | |
| 118 | + | |
116 | 119 | | |
117 | 120 | | |
118 | 121 | | |
| |||
171 | 174 | | |
172 | 175 | | |
173 | 176 | | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
178 | 215 | | |
179 | 216 | | |
180 | | - | |
| 217 | + | |
| 218 | + | |
181 | 219 | | |
182 | 220 | | |
183 | 221 | | |
| |||
231 | 269 | | |
232 | 270 | | |
233 | 271 | | |
| 272 | + | |
234 | 273 | | |
235 | 274 | | |
236 | 275 | | |
| |||
239 | 278 | | |
240 | 279 | | |
241 | 280 | | |
| 281 | + | |
| 282 | + | |
242 | 283 | | |
| 284 | + | |
243 | 285 | | |
244 | 286 | | |
245 | 287 | | |
| |||
Lines changed: 0 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | 82 | | |
84 | 83 | | |
85 | 84 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
30 | 35 | | |
31 | 36 | | |
32 | 37 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | 22 | | |
28 | 23 | | |
29 | 24 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
714 | 714 | | |
715 | 715 | | |
716 | 716 | | |
717 | | - | |
| 717 | + | |
718 | 718 | | |
719 | 719 | | |
720 | 720 | | |
| |||
1229 | 1229 | | |
1230 | 1230 | | |
1231 | 1231 | | |
1232 | | - | |
| 1232 | + | |
1233 | 1233 | | |
1234 | 1234 | | |
1235 | 1235 | | |
| |||
Lines changed: 6 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
85 | 89 | | |
86 | 90 | | |
87 | 91 | | |
| |||
99 | 103 | | |
100 | 104 | | |
101 | 105 | | |
102 | | - | |
| 106 | + | |
| 107 | + | |
103 | 108 | | |
104 | 109 | | |
105 | 110 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
0 commit comments