I've been working on an internal Pulp deployment for a while now, and one of the challenges is keeping Pulp's authentication and authorization for the REST API up to date with respect to the authoritative records in LDAP. I really don't want to be creating user records in every Pulp instance in advance just in case people want in, but nor do I want to have a manual process for requesting access if it turns out someone *does* need to connect directly to the back end.
I've finally decided to bite the bullet and just patch Pulp to implement the behaviour I want. However, since I want to submit the patch upstream when it's done, I figure it makes sense to run the draft design by the list. 1. Web server pre-authentication (Bugzilla RFE: https://bugzilla.redhat.com/show_bug.cgi?id=831937) I don't intend to implement Kerberos authentication in Pulp per se. Instead, I intend to update Pulp to check for a HTTP_REMOTE_USER entry before checking for HTTP_AUTHORIZATION and rely on mod_auth_kerb for the actual authentication part. If HTTP_REMOTE_USER is set, the username (up to the first @ character, if any) is assumed to have been pre-authenticated by Apache. If they already exist as a user, then their existing record will be used, otherwise a new record will be created according to the external authorization rules below. This selective pre-authentication can then be configured in Apache 2.2 by using SetEnvIf to filter on the Authorization field, and Specify Any to allow users that fail pre-authentication through to Pulp's internal authentication mechanisms. Example config changes for Pulp's REST API web service: <Files webservices.wsgi> # This allows everything except Kerberos auth through to Pulp SetEnvIfNoCase ^Authorization$ "Negotiate.*" USE_APACHE_AUTH=1 Order allow,deny Allow from env=!USE_APACHE_AUTH Satisfy Any # Installation specific Kerberos config details go here # Standard Pulp REST API web service config details go here </Files> If desired, the Apache level filters can be tightened up to only allow pass through authentication options that Pulp is known to understand (which would have the added bonus of interacting properly with clients like web browsers that try unauthenticated access first, and only try to pass a Kerberos ticket after receiving the relevant headers in a 401 error response) The advantage of this general approach is that it isn't Kerberos (or even Apache) specific - it should work for *any* web server level authentication method that can be set up to pass HTTP_REMOTE_USER through to the application. 2. External authorization (Bugzilla RFE: https://bugzilla.redhat.com/show_bug.cgi?id=828072) The current LDAP authorization support is rather limited - consisting solely of the "filter" option in the [ldap] config settings, along with the "default-role" setting in that section. This is limited in three ways: - it doesn't handle web server level preauthentication in the absence of LDAP - it only allows LDAP filters against users (not LDAP groups), which is a problem if the LDAP server doesn't provide "memberOf" attributes on user records - it doesn't allow for per-role LDAP filters To deal with the first limitation, I plan to add a "default-role" option to the [security] section of the config file that is automatically granted to *all* users when first created. LDAP authenticated users would then get both the security default role *and* the ldap default role (if any) when they first logged in. Both default-role entries become optional. For the latter two limitations, I plan to implement a couple of new configuration sections: "ldap-user-roles" and "ldap-group-roles" The format of these new sections are currently going to be: [ldap-user-roles] role-name: <LDAP user filter> [ldap-group-roles] role-name: <LDAP group filter> The role names are only checked against the database when a user logs in via web server preauthentication. If the role name doesn't exist, that results in a warning in the Pulp log file but is otherwise ignored. When a user is created implicitly (either via LDAP authentication or web server preauthentication) the following automatic role assignment checks will be performed: If security.default-role is defined: the new user is granted that role If LDAP is configured and the username matches a uid in LDAP (taking ldap.filter into account): If ldap.default-role is defined: the new user is granted that role For each role:role-filter pair in ldap-user-roles: If (&(uid=<username>)<role-filter>) returns a non-empty list: the new user is granted that role For each role:role-filter pair in ldap-group-roles: If (&(uid=<username>)<role-filter>) returns a non-empty list: the new user is granted that role If, after all this, the user has no roles assigned: They are not authorized for any access, and the login attempt fails Otherwise, the user is created and more specific role-based authorization checks proceed as usual Writing automated tests for this new behaviour may prove to be a bit tricky, so any advice on that front would be appreciated. Regards, Nick. -- Nick Coghlan Red Hat Infrastructure Engineering & Development, Brisbane _______________________________________________ Pulp-list mailing list [email protected] https://www.redhat.com/mailman/listinfo/pulp-list
