On Mon, Sep 24, 2018 at 9:31 AM Colleen Murphy <coll...@gazlene.net> wrote:
> On Mon, Sep 24, 2018, at 4:16 PM, Lance Bragstad wrote: > > On Mon, Sep 24, 2018 at 7:00 AM Colleen Murphy <coll...@gazlene.net> > wrote: > > > > > This is in regard to https://launchpad.net/bugs/1641625 and the > proposed > > > patch https://review.openstack.org/588211 for it. Thanks Vishakha for > > > getting the ball rolling. > > > > > > tl;dr: Keystone as an IdP should support sending > > > non-strings/lists-of-strings as user attribute values, specifically > lists > > > of keystone groups, here's how that might happen. > > > > > > Problem statement: > > > > > > When keystone is set up as a service provider with an external > > > non-keystone identity provider, it is common to configure the mapping > rules > > > to accept a list of group names from the IdP and map them to some > property > > > of a local keystone user, usually also a keystone group name. When > keystone > > > acts as the IdP, it's not currently possible to send a group name as a > user > > > property in the assertion. There are a few problems: > > > > > > 1. We haven't added any openstack_groups key in the creation of the > > > SAML assertion ( > > > > http://git.openstack.org/cgit/openstack/keystone/tree/keystone/federation/idp.py?h=14.0.0#n164 > > > ). > > > 2. If we did, this would not be enough. Unlike other IdPs, in > keystone > > > there can be multiple groups with the same name, namespaced by domain. > So > > > it's not enough for the SAML AttributeStatement to contain a > > > semi-colon-separated list of group names, since a user could > theoretically > > > be a member of two or more groups with the same name. > > > * Why can't we just send group IDs, which are unique? Because two > > > different keystones are not going to have independent groups with the > same > > > UUID, so we cannot possibly map an ID of a group from keystone A to > the ID > > > of a different group in keystone B. We could map the ID of the group > in in > > > A to the name of a group in B but then operators need to create groups > with > > > UUIDs as names which is a little awkward for both the operator and the > user > > > who now is a member of groups with nondescriptive names. > > > 3. If we then were able to encode a complex type like a group dict > in > > > a SAML assertion, we'd have to deal with it on the service provider > side by > > > being able to parse such an environment variable from the Apache > headers. > > > 4. The current mapping rules engine uses basic python string > > > formatting to translate remote key-value pairs to local rules. We would > > > need to change the mapping API to work with values more complex than > > > strings and lists of strings. > > > > > > Possible solution: > > > > > > Vishakha's patch (https://review.openstack.org/588211) starts to solve > > > (1) but it doesn't go far enough to solve (2-4). What we talked about > at > > > the PTG was: > > > > > > 2. Encode the group+domain as a string, for example by using the > dict > > > string repr or a string representation of some custom XML and maybe > base64 > > > encoding it. > > > * It's not totally clear whether the AttributeValue class of > the > > > pysaml2 library supports any data types outside of the xmlns:xs > namespace > > > or whether nested XML is an option, so encoding the whole thing as an > > > xs:string seems like the simplest solution. > > > > > > > Encoding this makes sense. We can formally support different SAML data > > types in the future if a better solution comes along. We would have to > make > > the service provider deal with both types of encoding, but we could > > eventually consolidate, and users shouldn't know the difference. Right? > > The only way this would make a difference to the user is if they need to > debug a request by actually looking at the response to this request[1]. If > we were to base64-encode the string that immediately obfuscates what the > actual value is. I'm not really sure if we need to base64-encode it or just > serialize it some other way. > Oh - yeah that makes sense. In your opinion, does that prevent us from adopting another way of solving the problem if we find a better data type? > > [1] > https://developer.openstack.org/api-ref/identity/v3-ext/index.html#id404 > > > > > > > 3. The SP will have to be aware that openstack_groups is a special > key > > > that needs the encoding reversed. > > > * I wrote down "MultiDict" in my notes but I don't recall > exactly > > > what format the environment variable would take that would make a > MultiDict > > > make sense here, in any case I think encoding the whole thing as a > string > > > eliminates the need for this. > > > 4. We didn't talk about the mapping API, but here's what I think. > If > > > we were just talking about group names, the mapping API today would > work > > > like this (slight oversimplification for brevity): > > > > > > Given a list of openstack_groups like ["A", "B", "C"], it would work > like > > > this: > > > > > > [ > > > { > > > "local": > > > [ > > > { > > > "group": > > > { > > > "name": "{0}", > > > "domain": > > > { > > > "name": "federated_domain" > > > } > > > } > > > } > > > ], "remote": > > > [ > > > { > > > "type": "openstack_groups" > > > } > > > ] > > > } > > > ] > > > (paste in case the spacing makes this unreadable: > > > http://paste.openstack.org/show/730623/ ) > > > > > > But now, we no longer have a list of strings but something more like > > > [{"name": "A", "domain_name": "Default"} {"name": "B", "domain_name": > > > "Default", "name": "A", "domain_name": "domainB"}]. Since {0} isn't a > > > string, this example doesn't really work. Instead, let's assume that in > > > step (3) we converted the decoded AttributeValue text to an object. > Then > > > the mapping could look more like this: > > > > > > [ > > > { > > > "local": > > > [ > > > { > > > "group": > > > { > > > "name": "{0.name}", > > > "domain": > > > { > > > "name": "{0.domain_name}" > > > } > > > } > > > } > > > ], "remote": > > > [ > > > { > > > "type": "openstack_groups" > > > } > > > ] > > > } > > > ] > > > (paste: http://paste.openstack.org/show/730622/ ) > > > > > > > > I can't come up with a reason not to do this at the moment. If we > serialize > > the group+domain name information in SAML, then it seems appropriate to > > teach the service provider how to deserialize it and apply it to > mappings. > > Otherwise, does it make sense to build serialization into the identity > > provider if we aren't going to use the domain name? > > > > > > > Alternatively, we could forget about the namespacing problem and simply > > > say we only pass group names in the assertion, and if you have > ambiguous > > > group names you're on your own. We could also try to support both, e.g. > > > have an openstack_groups mean a list of group names for simpler use > cases, > > > and openstack_groups_unique mean the list of encoded group+domain > strings > > > for advanced use cases. > > > > > > Finally, whatever we decide for groups we should also apply to > > > openstack_roles which currently only supports global roles and not > > > domain-specific roles. > > > > > > (It's also worth noting, for clarity, that the samlize function does > > > handle namespaced projects, but this is because it's retrieving the > project > > > from the token and therefore there is only ever one project and one > project > > > domain so there is no ambiguity.) > > > > > > Thoughts? > > > > > > - Colleen (cmurphy) > > > > > > > __________________________________________________________________________ > > > OpenStack Development Mailing List (not for usage questions) > > > Unsubscribe: > openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > > > > > > __________________________________________________________________________ > > OpenStack Development Mailing List (not for usage questions) > > Unsubscribe: > openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > > __________________________________________________________________________ > OpenStack Development Mailing List (not for usage questions) > Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >
__________________________________________________________________________ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev