-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
None
A Super User (detected by LDAP_SUPERUSER_FILTER), that is not part of LDAP_RESTRICTED_USER_FILTER result set is rejected from creating organization, when he is not explicitly set in SUPER_USERS lists. Super user is corrently identified in UI and logs as super user.
Defining static users in SUPER_USERS makes management of Quay cumbersome, that's why the LDAP filters were introduced. In this case it is ignored.
Prerequisites:
- Enable debug log possitibilities (DEBUGLOG + USERS_DEBUG) for analysis
- LDAP super user is matching LDAP_USER_FILTER + LDAP_SUPERUSER_FILTER (jdoe)
- config-bundle configuration
- AUTHENTICATION_TYPE is LDAP
- FEATURE_RESTRICTED_USERS is true
- FEATURE_SUPER_USERS is true
- LDAP_USER_FILTER contains jdoe (super user) in resultset (checks for super user + restricted group memberships)
(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted))
-
- LDAP_SUPERUSER_FILTER contains jdoe in resultset (checks for super user group memberships)
(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted))
- LDAP_SUPERUSER_FILTER contains jdoe in resultset (checks for super user group memberships)
-
- LDAP_RESTRICTED_USER_FILTER does not contain jdoe in resultset (checks for restricted group memberships)
(|(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted))
- LDAP_RESTRICTED_USER_FILTER does not contain jdoe in resultset (checks for restricted group memberships)
-
- SUPER_USERS is explicitly *NOT * used
Reproduction:
- Login with jdoe (super user) into UI
- Create new organization
- User is rejected with 403 response
{ "detail": "Unauthorized", "error_message": "Unauthorized", "error_type": "insufficient_scope", "title": "insufficient_scope", "type": "https://registry.apps.lab.acp.domain.redacted/api/v1/error/insufficient_scope", "status": 403 }
Log analysis (redacted logs attached):
- Organization request detected (735079e0-6d80-4c07-8c9a-e2fa4d3378d9)
gunicorn-web stdout | 2025-11-05 06:48:45,495 [258] [DEBUG] [app] Starting request: urn:request:735079e0-6d80-4c07-8c9a-e2fa4d3378d9 (/api/v1/organization/) {'X-Forwarded-For': 'y.y.y.1, x.x.x.2'} ... gunicorn-web stdout | 2025-11-05 06:48:45,517 [258] [DEBUG] [auth.permissions] Identity loaded: <QuayDeferredPermissionUser id="f35b563d-9bb2-4d3d-919f-158e2d10ed02" auth_type="user_uuid" provides=set()> gunicorn-web stdout | 2025-11-05 06:48:45,517 [258] [DEBUG] [auth.permissions] Deferring permissions for user with uuid: f35b563d-9bb2-4d3d-919f-158e2d10ed02 ...
- Check for restricted user does not provide resultset (as it does not match LDAP_RESTRICTED_USER_FILTER) > OK
gunicorn-web stdout | 2025-11-05 06:48:45,535 [258] [DEBUG] [data.users.externalldap] Looking up LDAP restricted user username or email jdoe gunicorn-web stdout | 2025-11-05 06:48:45,647 [258] [DEBUG] [data.users.externalldap] Incoming username or email param: 'jdoe' gunicorn-web stdout | 2025-11-05 06:48:45,648 [258] [DEBUG] [data.users.externalldap] Conducting user search: (&(&(|(sAMAccountName=jdoe)(mail=jdoe))(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted)))(|(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted))) under OU=Users,OU=Lab,DC=domain,DC=redacted gunicorn-web stdout | 2025-11-05 06:48:45,650 [258] [DEBUG] [data.users.externalldap] Found matching DNs: [] gunicorn-web stdout | 2025-11-05 06:48:45,652 [258] [DEBUG] [data.users.externalldap] LDAP user jdoe not found: Invalid username or password. gunicorn-web stdout | 2025-11-05 06:48:45,654 [258] [DEBUG] [auth.permissions] Loading user permissions after deferring for: f35b563d-9bb2-4d3d-919f-158e2d10ed02 gunicorn-web stdout | 2025-11-05 06:48:45,654 [258] [DEBUG] [auth.permissions] User permission: _UserTypeNeed(type='user', username='jdoe', role='admin') gunicorn-web stdout | 2025-11-05 06:48:45,654 [258] [DEBUG] [auth.permissions] User namespace permission: _NamespaceWideNeed(type='organization', namespace='jdoe', role='admin') gunicorn-web stdout | 2025-11-05 06:48:45,654 [258] [DEBUG] [auth.permissions] User namespace repo permission: _NamespaceWideNeed(type='organizationrepo', namespace='jdoe', role='admin')
- Check for super provides logged in user (as it matches LDAP_SUPERUSER_FILTER) > OK
gunicorn-web stdout | 2025-11-05 06:48:45,664 [258] [DEBUG] [data.users.externalldap] Looking up LDAP superuser username or email jdoe gunicorn-web stdout | 2025-11-05 06:48:45,757 [258] [DEBUG] [data.users.externalldap] Incoming username or email param: 'jdoe' gunicorn-web stdout | 2025-11-05 06:48:45,757 [258] [DEBUG] [data.users.externalldap] Conducting user search: (&(&(|(sAMAccountName=jdoe)(mail=jdoe))(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted)))(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted))) under OU=Users,OU=Lab,DC=domain,DC=redacted gunicorn-web stdout | 2025-11-05 06:48:45,763 [258] [DEBUG] [data.users.externalldap] Found matching DNs: ['CN=john doe,OU=Operations,OU=People,OU=Users,OU=Lab,DC=domain,DC=redacted'] gunicorn-web stdout | 2025-11-05 06:48:45,766 [258] [DEBUG] [data.users.externalldap] Found superuser for LDAP username or email jdoe gunicorn-web stdout | 2025-11-05 06:48:45,767 [258] [DEBUG] [auth.permissions] Adding superuser to user: jdoe
- Check for global read only super user provides empty resultset (LDAP_GLOBAL_READONLY_SUPERUSER_FILTER is unconfigured) > OK
gunicorn-web stdout | 2025-11-05 06:48:45,780 [258] [DEBUG] [data.users.externalldap] Looking up LDAP global readonly superuser username or email jdoe gunicorn-web stdout | 2025-11-05 06:48:45,860 [258] [DEBUG] [data.users.externalldap] Incoming username or email param: 'jdoe' gunicorn-web stdout | 2025-11-05 06:48:45,862 [258] [DEBUG] [data.users.externalldap] LDAP global readonly superuser jdoe not found: Global readonly superuser username not found gunicorn-web stdout | 2025-11-05 06:48:45,863 [258] [DEBUG] [endpoints.api] Checking permission <class 'auth.permissions.UserAdminPermission'> for user jdoe gunicorn-web stdout | 2025-11-05 06:48:45,863 [258] [DEBUG] [auth.permissions] Loading user permissions after deferring for: f35b563d-9bb2-4d3d-919f-158e2d10ed02
- Another check for restricted user does not provide resultset (as it does not match LDAP_RESTRICTED_USER_FILTER) > OK
gunicorn-web stdout | 2025-11-05 06:48:45,871 [258] [DEBUG] [data.users.externalldap] Looking up LDAP restricted user username or email jdoe gunicorn-web stdout | 2025-11-05 06:48:45,949 [258] [DEBUG] [data.users.externalldap] Incoming username or email param: 'jdoe' gunicorn-web stdout | 2025-11-05 06:48:45,949 [258] [DEBUG] [data.users.externalldap] Conducting user search: (&(&(|(sAMAccountName=jdoe)(mail=jdoe))(|(memberOf=CN=System-Admins,OU=Users,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Admins-Quay,OU=Administrators,OU=Groups,OU=Lab,DC=domain,DC=redacted)(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted)))(|(memberOf=CN=Openshift-ReadOnly,OU=Services,OU=Groups,OU=Lab,DC=domain,DC=redacted))) under OU=Users,OU=Lab,DC=domain,DC=redacted gunicorn-web stdout | 2025-11-05 06:48:45,951 [258] [DEBUG] [data.users.externalldap] Found matching DNs: [] gunicorn-web stdout | 2025-11-05 06:48:45,954 [258] [DEBUG] [data.users.externalldap] LDAP user jdoe not found: Invalid username or password.
- Directly after the last restricted user check is performed the request is rejected with 403 and missing permissions > NOK
gunicorn-web stdout | 2025-11-05 06:48:45,955 [258] [DEBUG] [app] Ending request: urn:request:735079e0-6d80-4c07-8c9a-e2fa4d3378d9 (/api/v1/organization/) {'endpoint': 'api.organizationlist', 'request_id': 'urn:request:735079e0-6d80-4c07-8c9a-e2fa4d3378d9', 'remote_addr': 'x.x.x.2', 'http_method': 'POST', 'original_url': 'https://registry.apps.lab.acp.domain.redacted/api/v1/organization/', 'path': '/api/v1/organization/', 'parameters': {}, 'json_body': {'name': 'new_org'}, 'confsha': 'b3cb3175', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'}
Files: