← Back to team overview

openstack team mailing list archive

Re: Capture of the Keystone/LDAP Role discussion

 

On 02/02/2012 11:50 AM, Ryan Lane wrote:
Based on discussions with numerous people,  It seems that the subtree
approach (as done by nova deprecated)  is the norm.

It's a normal approach taken by a number of applications, yes. It's
not a bad way to handle this, and we are already doing it in nova. The
plus of doing it this way, rather than key-value pairs on users, is
that when a tenant is deleted, all of the roles are deleted with it.
Also, referential integrity plugins can remove userdns from tenants
and roles when a user is deleted.

It'll still be necessary for admins to remove users from roles when
removed from tenants, and we can't depend on that, so we should handle
that case.

I'll make sure that gets in.


What seems to vary the most amongst LDAP servers is not the schema,  but the
method used to query for membership in nested groups.   In OpenLDAP,  the
syntax involves sets

http://www.openldap.org/faq/data/cache/1133.html
http://www.openldap.org/faq/data/cache/1134.html

Whereas in Active directory,  it involves  using LDAP_MATCHING_RULE_IN_CHAIN
rule OID.

In the 389 (Fedora) Directory Server as well as OpenLDAP it is also possible
to use   the deference control in conjunction with the  memberof plugin.


However,  we might not need to query for nested group membership.  For
example, lets assume a tenant has 3 administrative roles:  user management,
network management, VM management. In addition,  users that do not have an
explicit admin role get read only access to the resources of that tenant.
So a user that has the right to manage networks for that tenant would have
to appear in both the members list of that tenant as well as in the
networkMgmt role.  The first is provided for read only access, and the
second for the ability to modify the network.  It is a little redundant.  We
could perhaps put a constraint on the roles that they will only allow users
that are listed in the general membership for that tenancy.

It shouldn't be necessary to do nested searching. When searching for
tenant roles for a user, it should be enough to search for the user as
a member of roles using the tenant as a base.

Even if nested group searching is necessary, it's possible to do
nested searching without support for it on the LDAP server side. A
recursive search works here. memberOf is also a possibility, but it
needs to be supported on the server side; also, some servers use
memberOf, and some use isMemberOf, so we'd have to make that
configurable.


It's likely best to assume some server in use won't support plugins or
extensions. We can discover capabilities from the server and use a
more efficient method if it's available, while falling back to the
less efficient method. Short-lived caches of the results can also
alleviate performance problems due to inefficient queries.

Right. First step is getting something to function, and then we can performance tune.

There was some talk about nesting tenancies for resellers.  This is somewhat
different from nested group member ship, as entry in the lower level tenant
should *not* provide access to all resources of the containing tenancy.
Permissions go the other way around:  if I am an admin of the container,  I
can manage elements of the contained.  It does mean that the Keystone server
needs to be smart enough to check all of the levels of nesting from lowest
to highest to see if a user has the appropriate role for the requested
operation.

So,  to summarize:  Roles will be entites under tenants,  with a member
field that indicates the users that have that role.


We still need some way to differentiate between roles and tenants,
otherwise subtree searches will cause problems.

In nova we handled this by assigning the owner attribute on tenants,
but no owner on roles. This allowed tenants to be found via a search
like this:

   (&(objectclass=groupofnames)(owner=*))

Roles are then discovered by a search like this, using the tenant as a base:

   (objectclass=groupofnames)

Alternatively, we could add schema for roles and projects. It seems a
little overkill to add schema just to differentiate these for subtree
searches, though.

I don't love this solution, as it is not really very self documenting, and it would be easy enough for someone to mess it up.

  objectClasses: ( 2.5.6.9 NAME 'groupOfNames'
  SUP top
  STRUCTURAL
  MUST ( cn )
  MAY ( member $
        businessCategory $
        seeAlso $
        owner $
        ou $
        o $
        description )

Seems like what we really want is organizationalRole from http://www.ietf.org/rfc/rfc4519.txt

3.10.  'organizationalRole'

   The 'organizationalRole' object class is the basis of an entry that
   represents a job, function, or position in an organization.
   (Source: X.521 [X.521])

      ( 2.5.6.8 NAME 'organizationalRole'
         SUP top
         STRUCTURAL
         MUST cn
         MAY ( x121Address $ registeredAddress $ destinationIndicator $
               preferredDeliveryMethod $ telexNumber $
               teletexTerminalIdentifier $ telephoneNumber $
               internationalISDNNumber $ facsimileTelephoneNumber $
               seeAlso $ roleOccupant $ preferredDeliveryMethod $
               street $ postOfficeBox $ postalCode $ postalAddress $
               physicalDeliveryOfficeName $ ou $ st $ l $
               description ) )


With the users going in the roleOccupant field. This is in core.ldif in the schema



- Ryan



Follow ups

References