RANGER-5627: Support configuration-based super users and super groups in Ranger Admin#1000
RANGER-5627: Support configuration-based super users and super groups in Ranger Admin#1000ramackri wants to merge 2 commits into
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
Rename configSuperUser to superUser, simplify role getters via OR with superUser flag, refactor hasKMSPermissions, and update config descriptions per PR #1000 review feedback. Co-authored-by: Cursor <cursoragent@cursor.com>
| List<String> permissionList; | ||
|
|
||
| if (userSession.isUserAdmin() || userSession.isKeyAdmin()) { | ||
| List<XXModuleDef> allModules = |
There was a problem hiding this comment.
Instead of retrieving list of XXModuleDef objects, retrieving only attribute module (which is referenced in line 233 below) will be more efficient. Consider adding method XXModuleDefDao.getAllModuleNames() to return only the attribute needed here.
| applyConfigSuperUserSessionFlags(userSession); | ||
|
|
||
| if (userSession.isSuperUser()) { | ||
| strRoleList = RangerSuperUserConfig.mergeConfigSuperUserRoles( |
There was a problem hiding this comment.
For readability, please unnecessary line splits like this - long gone are the days code was printed in paper, which limited line length to 80 or 132. Please review other updates in this PR.
| return; | ||
| } | ||
|
|
||
| Set<String> userGroups = xUserMgr.getSyncedGroupsForUser(loginId); |
There was a problem hiding this comment.
Consider calling getSyncedGroupsForUser() only when necessary.
final boolean isSuperUser;
if (RangerSuperUserConfig.isSuperGroupsConfigured()) {
isSuperUser = RangerSuperUserConfig.isSuperUser(loginId, xUserMgr.getSyncedGroupsForUser(loginId));
} else {
isSuperUser = RangerSuperUserConfig.isSuperUser(loginId);
}
if (isSuperUser) {
userSession.setSuperUser(true);
logger.info("Granted full admin privileges via config for user {}", loginId);
} else {
userSession.setSuperUser(false);
}
| * entry | ||
| */ | ||
| public static boolean isEnabled() { | ||
| return hasNonEmptyEntry( |
There was a problem hiding this comment.
Consider initializing in the constructor and return the value from isEnabled(); this will help avoid unnecessary overheads in each call.
public final class RangerSuperUserConfig {
private final boolean isEnabled;
private final boolean isSuperUsersConfigured;
private final boolean isSuperGroupsConfigured;
private RangerSuperUserConfig() {
isSuperUsersConfigured = hasNonEmptyEntry(PropertiesUtil.getPropertyStringList(RangerConstants.RANGER_ADMIN_SUPER_USERS));
isSuperGroupsConfigured = hasNonEmptyEntry(PropertiesUtil.getPropertyStringList(RangerConstants.RANGER_ADMIN_SUPER_GROUPS));
isEnabled = isSuperUsersConfigured || isSuperGroupsConfigured;
}
...
}
What changes were proposed in this pull request?
Implements RANGER-5627: configuration-based
Ranger Admin super users and super groups via
ranger.admin.super.usersandranger.admin.super.groupsinranger-admin-site.xml.Problem addressed: Externally authenticated users (LDAP/Kerberos/OIDC/SAML) could
not be designated as Ranger administrators without Ranger managed DB roles. Deployments
relied on shared local
adminaccounts, limiting enterprise IdM integration, SSO/K8smodels, and per-user auditability.
Solution: Matching users receive full admin session flags, Spring Security roles,
module permissions, and REST authorization at login without changing
x_portal_user_role. Authentication provider remains independent of the elevationdecision. Backward compatible when both config properties are empty. Re-login
required after config or UserSync group membership changes.
Key changes:
RangerSuperUserConfig; session elevation inSessionMgr/UserSessionBaseUserMgr.getAuthenticationRolesByLoginId()and profile overrides;XUserMgr.getSyncedGroupsForUser()forsuper.groupsisSingleRoleUserSession()andRangerBizUtil.isUserRangerAdmin()XAUtils.jsmulti-role check; OpenAPI/Swagger alias fixes for local API testingdev-support/ranger-docker/scripts/admin/; design docsWhat changes were proposed in this pull request?
Implements RANGER-5627.
Configuration & template
ranger.admin.super.usersandranger.admin.super.groupstosecurity-admin/src/main/resources/conf.dist/ranger-admin-site.xmlandsecurity-admin/scripts/ranger-admin-site-template.xml.New core class
RangerSuperUserConfig— reads config,isEnabled(),isSuperUser(loginId, groups),case-insensitive user match, group membership check, helpers to merge config super-user
roles into authentication and profile role lists.
Session & authentication
SessionMgr—applyConfigSuperUserSessionFlags()at login; setsuserAdmin,keyAdmin,configSuperUser; grants all UI modules viaresetUserModulePermission()whenisEffectiveRangerAdmin()or key admin.UserSessionBase—configSuperUserflag;isEffectiveRangerAdmin()=userAdmin || configSuperUser;isSingleRoleUserSession()bypasses ROLE_USER-onlyrestrictions for config super-users.
UserMgr—getAuthenticationRolesByLoginId()for Spring Security;applyConfigSuperUserProfileOverrides()on/user/profile.RangerAuthenticationProvider— usegetAuthenticationRolesByLoginId()instead of DB-only role lookup.Authorization & REST
RangerBizUtil—isUserRangerAdmin(),isConfigSuperUser(),checkUserAccessible()honor session/config elevation.XUserMgr—getSyncedGroupsForUser()for login-time group resolution (DAO,no API masking);
getGroupsForUser()restored for API paths;isSingleRoleUserSession()bypass in group search.
RoleDBStore,RoleREST,ServiceREST,XUserREST,AssetREST— skip ROLE_USER-only masking when
isSingleRoleUserSession()or config super-userchecks apply.
UI (minimal)
react-webapp/src/utils/XAUtils.js—LoginUser()usesroles.includes(role)instead ofuserRoleList[0]only.Not changed:
RoleForm.jsx,EditPermission.jsx,UserForm.jsx— stockAdd-then-Save UX retained.
Unit tests
TestRangerSuperUserConfigTestSessionMgr,TestUserMgr,TestXUserMgr,TestRangerBizUtil,TestRoleDBStore,TestAssetREST,TestServiceREST,TestXUserREST,TestRangerHeaderPreAuthFilterOpenAPI / Swagger UI Fix
distro/src/main/assembly/admin-web.xml— shipswagger.jsonas an alias ofopenapi.jsonin the admin tarball (backward-compatible Swagger UI load path).docs/src/site/resources/index.js— Swagger UI loadsopenapi.jsoninsteadof
swagger.json(supports OpenAPI parity scripts and local API docs testing).How was this patch tested?
Prerequisites — minimal Docker stack
Only three components are required to validate config super-users (no Hive, HDFS,
Kafka, or audit tier needed):
ranger-postgres)ranger)http://localhost:6080ranger-usersync)x_user,x_group,x_group_usersOne-time setup (from repo root):
Start minimal stack:
Super-user config (must be present before testing; included in this PR’s
ranger-admin-site.xmltemplate):After changing config or rebuilding the admin image, recreate the
rangercontainer and re-login test users.
Default credentials:
admin/rangerR0cks!·testuser_*/rangerR0cks!Dev user/group CSV (
ugsync-file-source.csv)Path:
dev-support/ranger-docker/scripts/usersync/ugsync-file-source.csvThis file drives both first-boot bootstrap and ongoing UserSync membership.
It is mounted into the UserSync container and also read by
create-ranger-services.pywhen therangercontainer starts.Format: one row per user; first column = login id; remaining columns = group names
(comma-separated, no header row).
testuser_N)testgroup_*)testgroup_3Aranger.admin.super.groupsin config — required forsuper.groupsE2ErangerR0cks!bycreate-ranger-services.pybootstrapWhy UserSync matters for
super.groups: Config does not query LDAP/files atlogin. It reads group names already stored in Ranger DB (
x_group_users) byUserSync. Without UserSync (or bootstrap),
testuser_7would have notestgroup_3Amembership and would not elevate viasuper.groups.Ranger UserSync — start and verify
UserSync runs as container
ranger-usersyncwithENABLE_FILE_SYNC_SOURCE=true(see
dev-support/ranger-docker/.env). The CSV is bind-mounted fromscripts/usersync/ugsync-file-source.csv.Start (if not already up with the stack):
export ENABLE_FILE_SYNC_SOURCE=true docker compose -f docker-compose.ranger-db.yml -f docker-compose.ranger.yml \ -f docker-compose.ranger-usersync.yml up -d ranger-usersyncWait for first sync cycle (~60–90 seconds), then check logs:
Verify membership in DB (prerequisite for
testuser_7/super.groups):Verify in Admin UI (as
admin): Settings → Users/Groups → Users → opentestuser_7→ Groups tab → confirmtestgroup_3A. User roles shouldstill show
ROLE_USERonly (config elevation does not change DB roles).After CSV edits: restart
ranger-usersync, wait for sync, confirm membershipin UI/DB, then logout and login as the affected user.
1. Unit tests
Run from repo root:
mvn test -pl security-admin \ -Dtest=TestRangerSuperUserConfig,TestSessionMgr,TestUserMgr,TestXUserMgr,TestRangerBizUtil,TestRoleDBStore \ -Dfrontend.skip=trueResult: All targeted unit tests pass.
TestRangerSuperUserConfigTestSessionMgrTestUserMgrTestXUserMgrgetSyncedGroupsForUservsgetGroupsForUserTestRangerBizUtilisUserRangerAdmin, access checksTestRoleDBStore2. Manual UI smoke (required for reviewers)
Use form login at
http://localhost:6080/login.jsp(JDBC auth — username +password, not SSO/Kerberos for
testuser_*).Important: Elevation is applied at login. After any config or UserSync
change, log out completely and log in again before checking the UI.
3a. Baseline — confirm UserSync data (as
admin)admin/rangerR0cks!.testuser_2andtestuser_7exist.testuser_7→ Groups → confirmtestgroup_3Ais listed.testuser_2/testuser_7→ Roles → confirm DB role isROLE_USERonly (not SYS admin). Config super-user does not mutate DB roles.3b.
super.userspath —testuser_2testuser_2/rangerR0cks!.ROLE_SYS_ADMINandROLE_KEY_ADMIN.ROLE_USERshown, or profile page error banner.for read/list operations).
3c.
super.groupspath —testuser_7testuser_7/rangerR0cks!.getSyncedGroupsForUserfix: elevation via group membership synced by UserSync, not via
super.users.testuser_7fails buttestuser_2passes, check UserSync first(DB query / Groups tab) before assuming an auth bug.
3d. Create / edit smoke (stock Add-then-Save UX)
Still logged in as
testuser_2ortestuser_7:The permission editor is client-side: selecting a user/group in the dropdown
without clicking Add before Save will show a validation error — that is
expected stock behavior, not a super-user regression.
3e. Negative control — no elevation
ranger.admin.super.usersand not a member of anygroup listed in
ranger.admin.super.groups(edit CSV to removetestgroup_3Afrom one user, re-sync UserSync, or verify in UI).
ROLE_USERonly; Users/Groups, Roles,and admin-only modules are restricted or hidden; no SYS/KEY admin roles on profile.
admin(DB admin) to confirm configsuper-user matches admin capability without DB role change.
3f. Optional DevTools check
After login as
testuser_2ortestuser_7, open Network →GET /service/users/profile:userRoleListshould containROLE_SYS_ADMINandROLE_KEY_ADMIN.userPermListshould includeUsers/Groups,Key Manager,Audit, etc.