[openstack-dev] [Keystone] LDAP support for groups

Adam Young ayoung at redhat.com
Wed Dec 19 13:55:18 UTC 2012


On 12/18/2012 05:30 PM, David Chadwick wrote:
> How you structure the LDAP tree should be orthogonal and independent 
> from the mapping function. So you can start with a simple group 
> structure first in which only OpenStack level groups are allowed, then 
> go more granular with groups per domain, then down to the org level. 
> You would only need to change the code for adding and retrieving the 
> groups values without changing the code for mapping to roles and tenants

I'm a big fan of the iterative approach.  This sounds good.

>
> regards
>
> David
>
>
> On 18/12/2012 21:03, Adam Young wrote:
>> On 12/18/2012 12:34 PM, David Chadwick wrote:
>>> Hi Adam
>>>
>>> considering the structuring of groups in LDAP one more time, I think
>>> you need something like the following
>>>
>>> 1. Each organisation that defines groups for its users should have an
>>> organisational entry
>> This makes sense, but it is likely a "next version" LDAP backend.
>>
>>
>>> 2. Beneath this Org entry there should be a set of gON entries, each
>>> with the name of the group it represents e.g. CN=managers,
>>> CN=engineers etc
>>
>> I could see an approach based on this general idea to pull multiple
>> identity providers together. Right now, I would be tempted to do it as
>> the domain level.
>>
>>> 3. The member attribute of each gON entry holds the group members.
>>>
>>> You then use the mapping function to map from the group attribute
>>> (Cn=managers) to the roles/projects you want this group to have
>>
>> Sounds logical.  I think for a first implementation we do the degenerate
>> case, which is one tree for groups, but with an eye to addingthe
>> "organization" piece, but ideally fitting into one of the abstractions
>> of the current Keystone design.
>>
>>>
>>> regards
>>>
>>> David
>>>
>>>
>>> On 16/12/2012 02:46, Adam Young wrote:
>>>> On 12/15/2012 03:34 AM, David Chadwick wrote:
>>>>> Hi Adam
>>>>>
>>>>> in order to conform to the existing X.521/LDAP schema we have to make
>>>>> the following change to your proposal
>>>>>
>>>>> On 15/12/2012 02:26, Adam Young wrote:
>>>>>> For the sake of argument, let say the we do the following:
>>>>>>
>>>>>> roles continue to be organizationalRoles underneath the projects 
>>>>>> (I am
>>>>>> working really hard to drop the term tenant)
>>>>>> groups are groupOfNames
>>>>>>
>>>>>> user assignment is done by adding the user dn to the roleOccupant
>>>>>> attribute of the organizationalRole object.
>>>>>>
>>>>>> Now we add the rule that group assignement is done in the same
>>>>>> attribute.
>>>>>
>>>>> No, we use the existing rule that group assignment is done via the
>>>>> existing member attribute (which is also of type DN). The 
>>>>> roleOccupant
>>>>> attribute does not exist in the gON object class so you cant use 
>>>>> this.
>>>>> The other thing to note is that you can have nested groups using gON
>>>>> since member can be the DN of a user or the DN of another gON object.
>>>>> (I dont know if you want this feature or not, but it is allowed in 
>>>>> the
>>>>> schema)
>>>>
>>>> I think you misunderstand what I was proposing.
>>>>
>>>>
>>>> Groups are implemented groupOfNames.  Group membership is done by
>>>> appending the users DN to membership attribute.  That is pretty much
>>>> what you just wrote, and I think it is the only way to do group
>>>> membership that makes sense.
>>>
>>> OK we are on the same songsheet
>>>
>>>>
>>>> roles are implemented as organizationalRole. They are collected under
>>>> the project object, which is implementated as a groupOfNames object.
>>>
>>> so the project is a gON object and it has multiple children which are
>>> the roles that can be used with this project. Is that correct?
>>>
>>>
>>>   A
>>>> user is assigned roll by being appended to the roleOccupant 
>>>> attribute of
>>>> the organizationalROle.  My guess is that this is a bit of abuse of 
>>>> the
>>>> organizationalRole object as all of the documentation I have seen 
>>>> shows
>>>> it to assume only one DN, the user filling the role, but we do it as a
>>>> list.
>>>
>>> No its not abuse. Its the standard use of the roleOccupant attribute
>>> which is multi-valued. Its quite common to have multiple people with
>>> the same roles e.g. Manager, team leader, professor etc. are all roles
>>> usually held by many people.
>>>
>>>
>>>>
>>>> So to add groups to the role, we append the DN of the group to the
>>>> roleOccupant field.  This is on the organizationalRole object, not the
>>>> groupOfNames.
>>>>
>>>
>>> Yes this sounds OK. YOu are effectively saying that a whole group of
>>> people have a particular role.
>>>
>>>>
>>>>
>>>>> organizationalRole
>>>>>
>>>>>>
>>>>>> Now, to determine the roles for a user/project, we need to:
>>>>>>
>>>>>> iterate through all of the users of the orgRole.roleOcc attribute.
>>>>>> If the user is there, they have that role.
>>>>>>
>>>>>> If there are any groups in there, we need to iterate through each
>>>>>> of the
>>>>>> groups to find out if the user is a member of that group. If they 
>>>>>> are,
>>>>>> they have that role.
>>>>>
>>>>> and you could recursively do this, if you find that another group is
>>>>> also a member of the group
>>>> Yeah, FreeIPA does this, but it is kindof non-standard for Unix/Posix
>>>> groups.
>>>>>
>>>>>>
>>>>>> Does this sound right?
>>>>>
>>>>> with the above changes yes. However you could also use attribute
>>>>> mapping instead since this code will be available for you by Tuesday
>>>>> :-)
>>>> I'll take a look, but I think mapping falls into "neither necessary 
>>>> nor
>>>> sufficient" for groups.
>>>
>>> agreed. YOu still have to say which groups people are in. So using
>>> Keystone's backend LDAP is the obvious place to do this.
>>>
>>> But once you add federation, this will no longer be via Keystone's
>>> backend LDAP, but rather in the IDP's own database.
>>>
>>> So the point I was trying to make (rather badly) is that how you map
>>> from group membership to role membership should be done in a way that
>>> is independent of whether Keystone is federated or not, ie. it should
>>> not depend upon how groups are actually stored. Thus you should not
>>> assume that group DNs are stored in roleOccupant attributes, because
>>> in the federated case they wont be. So any code you write that assumes
>>> this will be useless once you move to federation. Since you need to
>>> map from groups to roles in both cases, then have an independent
>>> mapping function that works equally well in both cases. I.e. given a
>>> group or groups that a user is a member of, have a function (API) that
>>> returns his projects and roles. Then you can use this API for both the
>>> federated and non-federated cases. In the federated case each
>>> organisational admin will add groups to his own local IDP-LDAP which
>>> is external to Keystone. In the non-federated case each organisational
>>> admin will need permissions to add groups and their memberships to
>>> Keystone's backend LDAP. In both cases the organisational admin will
>>> use the mapping API to do the mapping.
>>>
>>>
>>>   Yes, it could be implemented that way, but we
>>>> would still need a way to deal with storing group information in LDAP
>>>> that aligns with current LDAP deployments.
>>>
>>> Agreed.
>>>
>>>   With mapping Keystone would
>>>> be able to map to an existing Group structure and make that work.
>>>
>>> map from, not map to
>>>
>>>    But
>>>> in the cases where the is no group structure, we would need to 
>>>> provide a
>>>> baseline, and the entities to manipulate it.
>>>
>>> I dont follow you here, sorry.
>>>
>>>>
>>>> Put another way, I see Mapping as an Aspect, a way of implementing 
>>>> cross
>>>> cutting concerns.  I see Groups as part of the domain model, and
>>>> something we need to support as a first class object.  I think that,
>>>> even if we were to implement via mapping, we would still need a group
>>>> schema.
>>>
>>> Since I dont really fully appreciate the domain model yet I dont know
>>> how you think groups will fit into this. Do you have some blueprint
>>> that describes this?
>>>
>>> regards
>>>
>>> David
>>>
>>>>
>>>>>
>>>>> regards
>>>>>
>>>>> David
>>>>>
>>>>>
>>>>>>
>>>>>> It seems to me that this is a lot of across the Wire LDAP calls, I
>>>>>> suspect that there are LDAP controls to support it.
>>>>>>
>>>>>>
>>>>>> This would be the default approach.  I am not sure that it maps 
>>>>>> to how
>>>>>> people are setting up their LDAP servers.  If it is not, what 
>>>>>> kind of
>>>>>> flexibility do we need to build in?  Does this map at all to how AD
>>>>>> forces the LDAP schema to look?
>>>>>>
>>>>>>
>>>>>> On 12/14/2012 02:39 PM, David Chadwick wrote:
>>>>>>> Yes you can do this, but you still have to define the group
>>>>>>> membership
>>>>>>> somewhere. This was the point I was addressing. You have to have a
>>>>>>> group object analogous to existing role objects, and the OC of the
>>>>>>> group object should tell you it is a gON and not a role
>>>>>>>
>>>>>>> David
>>>>>>>
>>>>>>>
>>>>>>> On 14/12/2012 19:27, Yee, Guang wrote:
>>>>>>>> What I meant was you should be able to stash both user and 
>>>>>>>> group in
>>>>>>>> roleOccupant. During token creation, we still need to resolve the
>>>>>>>> groups to
>>>>>>>> find out the user roles anyway. Everything in LDAP is 
>>>>>>>> identified by
>>>>>>>> DN and
>>>>>>>> you should know what you are dealing with by looking at its
>>>>>>>> objectclasses.
>>>>>>>>
>>>>>>>>
>>>>>>>> Guang
>>>>>>>>
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: David Chadwick [mailto:d.w.chadwick at kent.ac.uk]
>>>>>>>> Sent: Friday, December 14, 2012 11:04 AM
>>>>>>>> To: OpenStack Development Mailing List
>>>>>>>> Cc: Yee, Guang
>>>>>>>> Subject: Re: [openstack-dev] [Keystone] LDAP support for groups
>>>>>>>>
>>>>>>>> You could create separate branches of the LDAP tree for groups and
>>>>>>>> roles, and then use the orgRole OC for entries in both branches,
>>>>>>>> providing the client has the built in intelligence to know which
>>>>>>>> branch
>>>>>>>> is the role branch and which branch is the group branch.
>>>>>>>> Otherwise you
>>>>>>>> can mix groups and roles in the same branch if you use different
>>>>>>>> OCs to
>>>>>>>> signify the two different types of entry ie. orgRole OC and gON 
>>>>>>>> OC.
>>>>>>>> But I dont see how you can mix groups and roles in the same
>>>>>>>> branch and
>>>>>>>> use the same OC for both, as nothing can tell the difference
>>>>>>>> between the
>>>>>>>> two.
>>>>>>>>
>>>>>>>> regards
>>>>>>>>
>>>>>>>> David
>>>>>>>>
>>>>>>>>
>>>>>>>> On 14/12/2012 18:43, Yee, Guang wrote:
>>>>>>>>> Having both in a single field should be fine. LDAP group members
>>>>>>>>> can be
>>>>>>>>> both users and groups (nested groups). At the end, you still
>>>>>>>>> need to
>>>>>>>>> walk the tree to resolve unique user membership anyway as token
>>>>>>>>> doesn't
>>>>>>>>> contain any group information.
>>>>>>>>>
>>>>>>>>> Guang
>>>>>>>>>
>>>>>>>>> *From:*Adam Young [mailto:ayoung at redhat.com]
>>>>>>>>> *Sent:* Friday, December 14, 2012 10:04 AM
>>>>>>>>> *To:* OpenStack Development Mailing List
>>>>>>>>> *Subject:* [openstack-dev] [Keystone] LDAP support for groups
>>>>>>>>>
>>>>>>>>> We are close to getting Groups done in the SQL back end, but we
>>>>>>>>> still
>>>>>>>>> need a schema for  LDAP, and it is not super apparent how to 
>>>>>>>>> close
>>>>>>>>> the
>>>>>>>>> gap on it.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The schema for role assignment is:
>>>>>>>>>
>>>>>>>>> 1.   #
>>>>>>>>>
>>>>>>>>> 2.   olcObjectClasses: ( 2.5.6.8 NAME 'organizationalRole'
>>>>>>>>>
>>>>>>>>> 3.      DESC 'RFC2256: an organizational role'
>>>>>>>>>
>>>>>>>>> 4.      SUP top STRUCTURAL
>>>>>>>>>
>>>>>>>>> 5.      MUST cn
>>>>>>>>>
>>>>>>>>> 6.      MAY ( x121Address $ registeredAddress $
>>>>>>>>> destinationIndicator $
>>>>>>>>>
>>>>>>>>> 7.      preferredDeliveryMethod $ telexNumber $
>>>>>>>>> teletexTerminalIdentifier
>>>>>>>> $
>>>>>>>>>
>>>>>>>>> 8.      telephoneNumber $ internationaliSDNNumber $
>>>>>>>> facsimileTelephoneNumber $
>>>>>>>>>
>>>>>>>>> 9.      !
>>>>>>>>>
>>>>>>>>> 10.  seeAlso $
>>>>>>>>>
>>>>>>>>> 11.
>>>>>>>>>
>>>>>>>>> 12.roleOccupant $ preferredDeliveryMethod $ street $
>>>>>>>>>
>>>>>>>>> 13.   postOfficeBox $ postalCode $ postalAddress $
>>>>>>>>>
>>>>>>>>> 14.   physicalDeliveryOfficeName $ ou $ st $ l $ description ) )
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> And the users are in the roleOccupant field.
>>>>>>>>>
>>>>>>>>> We want to be able to make the roleOccupant included members of
>>>>>>>>> groups.
>>>>>>>>> But I am not sure that having both in a single field is
>>>>>>>>> advisable.  I
>>>>>>>>> would rather have a deliberate fields for group members. This was
>>>>>>>>> what
>>>>>>>>> we did in FreeIPA, and I think it is the right approach.
>>>>>>>>>
>>>>>>>>> We could extend roleOccupant with an other object class, but 
>>>>>>>>> there
>>>>>>>>> is no
>>>>>>>>> obvious class to use.
>>>>>>>>>
>>>>>>>>> We could replace roleOccupant with a different object class. 
>>>>>>>>> While
>>>>>>>>> that
>>>>>>>>> would make a painful transition, it might be preferable. But 
>>>>>>>>> again,
>>>>>>>>> there is no obvious replacement.
>>>>>>>>>
>>>>>>>>> We could make groups a collection underneath organizationalRoles
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Feedback is welcome.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> OpenStack-dev mailing list
>>>>>>>>> OpenStack-dev at lists.openstack.org
>>>>>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> OpenStack-dev mailing list
>>>>>>> OpenStack-dev at lists.openstack.org
>>>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> OpenStack-dev mailing list
>>>>>> OpenStack-dev at lists.openstack.org
>>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>>
>>




More information about the OpenStack-dev mailing list