[openstack-dev] [Keystone] Groups, mappings, and tokens

David Chadwick d.w.chadwick at kent.ac.uk
Tue Dec 18 22:26:30 UTC 2012

Hi Adam

On 18/12/2012 21:26, Adam Young wrote:
> One thing became clear to me during the meeting is that none of the
> mechanisms we have been talking about are going to be useful without
> extending the token mechanism.  Let me give you a brief overview, and
> you can tell me what you plan on doing.
> With recent refactoring, the token generation moved into
> https://github.com/openstack/keystone/blob/master/keystone/token/controllers.py#L34
> This code process auth via: userid/password, tokens, or REMOTE_USER.
> Unfortunately, the identity API authenticate method does too much: it
> authenticates the user and also returns the roles etc:  This makes it
> hard to reuse this code in conjunction with the token generation.  We
> probably need to first and foremost split the identity.authenticate
> method into two pieces, authN and authZ, and then we can make the authZ
> step common to both.

I agree. But I also think you need a separate function that generates a 
token with a complementary function that validates a token (if you dont 
have these already). Then the code for token creation and validation is 
completely removed from the rest of the logic and can be changed at 
will, since none of the other code will be effected by it. I would 
suggest methods such as

a) CreateToken: Given a set of tenants and roles (collectively known as 
OpenStack attributes, which come out of the attribute mapping function) 
return a token. The caller does not care if it is a scoped token or 
unscoped token or any other type of token as it is simply a binary blob 
to be carried around. Note that the set of input attributes should be 
able to grow as OpenStack grows e.g. domains should be able to be input 
as well as unique user IDs etc. If the token needs to be constrained, 
then other attributes could be input as well with the OpenStack 
attributes, such as service endpoints or other constraining attributes.

b) ValidateToken: Given a token, return the set of tenants and roles 
(i.e. OpenStack attributes) that are associated with it.

Note however that the token that is created is known as a bearer token 
ie. whoever has it, effectively has the OpenStack attributes associated 
with it. In order to move to a personalised token one can use Holder of 
Key, in which the public key of the token owner is also associated with 
the token. So you would need to add the public key of the owner as 
another input parameter to CreateToken, and it would return the token 
and a random challenge. The challenge is sent to the owner, he signs the 
challenge and token, and the signed challenge and token are given to 
ValidateToken which checks the signature against the public key to 
ensure that it is the token owner who is presenting it, and that it is 
not a replay (if you only want tokens to be used once. Otherwise the 
challenge could be a timestamp allowing it to be used multiple times 
until the time expires).

> Mapping comes in at the authZ step.


  The current logic for a scoped
> token is to enumerate the roles for a given user/tenant pairing.

I am suggesting that this logic will be a wrapper for the token 
generation and validation mechanism. This logic might wish to
a) generate an unscoped token when a set of tenants is input
b) generate a scoped token when a single tenant is input
c) call the mapper when a set of organisational attributes are input
etc. as you wish

> What needs to happen is we need to use mapping and groups to generate
> the list of roles.


> Since the mapping code is so close to implemented, I am OK if we try to
> push through and do groups on top of roles.  I think we still want to
> have a "group" web API, but I can see the argument that with mapping, we
> will be much more capable of mapping to complex LDAP structures.

Mapping is independent of the LDAP structure. The code for handling 
groups is responsible for both storing and retrieving the groups from 
LDAP before the mapping function is called.

> However, I am not sure if the mapping mechanism as specified will work
> if there is no implementation that the org_attributes can point to.

The groups ARE the org attributes. They replace them for a centralised 
Keystone. The org attributes come from IDPs in a federated Keystone. I 
have just updated the role mapping blueprint to clarify this.

> Am I correct in understanding that  the difference between the current
> group review request (https://review.openstack.org/#/c/18138/) and the
> Kent approach is how to assign groups to roles?

Yes this is the main difference. In the Kent approach there would be no 
assigning of groups to roles, but rather mappings would be set up 
between groups and roles/tenants/projects/domains

> It is my understanding that, if we were to use  the Kent approach in
> conjunction with LDAP, we would still use groupOfNames for groups, and
> assign users to groups using the members attribute, but then the role
> assignments would be done via mapping.

this is correct

   In the case, the org_attribute
> would be the group, and the os_attribute would be the role for the tenant?

I think the os_attributes would be both the role and the tenant, because 
after the user has authenticated, the only thing Keystone needs to pick 
up for him is his groups from the gON in LDAP (or SQL db). then it calls 
the mapping functionality to pick up the tenant and role

> I think we need to lay out the python code necessary to:
> 1. assign the groups to a role for a tenant
> 2. create a scoped token where the user gets their roles from the group.
> we can call the group "superadmins"  and the role "admin"   the tenant
> "default_tenant".

So you could create the superadmin group in LDAP as a gON.
Then assign user "cn=....." as a member.
Then you create a mapping from group=superadmin to role=admin and 
tenant=default_tenant in the attribute mapper

Now user cn=.... logs in, is authenticated, his groups are picked up by 
scanning the member attributes of each gON for his DN, then you call the 
mapper passing the group=superadmin and receiving the output role=admin 
and tenant=default_tenant

What you do next with tokens is surely as now isnt it?



> _______________________________________________
> 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