[dev][keystone] App Cred Capabilities Update
I have an initial draft of application credential capabilities available for review[1]. The spec[2] was not straightforward to implement. There were a few parts that I found unintuitive, user-unfriendly, and overcomplicated. The current proposed implementation differs from the spec in some ways that I want to discuss with the team. Given that non-client library freeze is next week, and the changes we need in keystonemiddleware also require changes in keystoneclient, I'm not sure there is enough time to properly flesh this out and allow for thorough code review, but if we miss the deadline we can be ready to get this in in the beginning of next cycle (with apologies to everyone waiting on this feature - I just want to make sure we get it right with minimal regrets). * Naming As always, naming is hard. In the spec, we've called the property that is attached to the app cred "capabilities" (for the sake of this email I'm going to call it user-created-rules), and we've called the operator-configured list of available endpoints "permissible path templates" (for the sake of this email I'm going to call it operator-created-rules). I find both confusing and awkward. "Permissible path templates" is not a great name because the rule is actually about more than just the path, it's about the request as a whole, including the method. I'd like to avoid saying "template" too because that evokes a picture of something like a Jinja or ERB template, which is not what this is, and because I'd like to avoid the whole string substitution thing - more on that below. In the implementation, I've renamed the operator-created-rules to "access rules". I stole this from Istio after Adam pointed out they have a really similar concept[3]. I really like this name because I think it well-describes the thing we're building without already being overloaded. So far, I've kept the user-created-rules as "capabilities" but I'm not a fan of it because it's an overloaded word and not very descriptive, although in my opinion it is still more descriptive than "whitelist" which is what we were originally going to call it. It might make sense to relate this property somehow to the operator-created-rules - perhaps by calling it access_rules_list, or granted_access_rules. Or we could call *this* thing the access rules, and call the other thing allowed_access_rules or permitted_access_rules. * Substitutions The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example: Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context. Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions. * UUIDs The spec says each operator-created-rule should have its own UUID, and the end user needs to look up and provide this UUID when they create the app cred rule. This has the benefit of having a fast lookup because we've put the onus on the user to look up the rule themselves, but I think it is very user-unfriendly. In the proposed implementation, I've done away with UUIDs on the operator-created-rules, and instead a match is looked up based on the service type, request path and method, and the "allow_chained" attribute (more on that next). Depending on how big we think this list of APIs will get, this will have some impact on performance on creation time (not at token validation time). UUIDs make sense for singleton resources that are created in a database. I imagine this starting as an operator-managed configuration file, and maybe some day in the future a catalog of this sort could be published by the services so that the operator doesn't have to maintain it themselves. To that end, I've implemented the operator-created-rules driver with a JSON file backend. But with this style of implementation, including UUIDs for every rule is awkward - it only makes sense if we're generating the resources within keystone and storing them in a database. * allow_chained The allow_chained attribute looks and feels awkward and adds complexity to the code Is there really a case when either the user or operator would not want to allow a service to make a request on behalf of a user who is making a more general request? Also, can we find a better name for it? Those are all the major question marks for me. There are some other minor differentiations from the spec and I will propose an update that makes it consistent with reality after we have these other questions sorted out. Colleen [1] https://review.openstack.org/#/q/topic:bp/whitelist-extension-for-app-creds [2] http://specs.openstack.org/openstack/keystone-specs/specs/keystone/stein/cap... [3] https://istio.io/docs/reference/config/authorization/istio.rbac.v1alpha1/#Ac...
On 2/21/19 3:11 PM, Colleen Murphy wrote:
I have an initial draft of application credential capabilities available for review[1]. The spec[2] was not straightforward to implement. There were a few parts that I found unintuitive, user-unfriendly, and overcomplicated. The current proposed implementation differs from the spec in some ways that I want to discuss with the team. Given that non-client library freeze is next week, and the changes we need in keystonemiddleware also require changes in keystoneclient, I'm not sure there is enough time to properly flesh this out and allow for thorough code review, but if we miss the deadline we can be ready to get this in in the beginning of next cycle (with apologies to everyone waiting on this feature - I just want to make sure we get it right with minimal regrets).
I'm all for spending extra time to work through this if needed. Thanks for raising it to the list.
* Naming
As always, naming is hard. In the spec, we've called the property that is attached to the app cred "capabilities" (for the sake of this email I'm going to call it user-created-rules), and we've called the operator-configured list of available endpoints "permissible path templates" (for the sake of this email I'm going to call it operator-created-rules). I find both confusing and awkward.
"Permissible path templates" is not a great name because the rule is actually about more than just the path, it's about the request as a whole, including the method. I'd like to avoid saying "template" too because that evokes a picture of something like a Jinja or ERB template, which is not what this is, and because I'd like to avoid the whole string substitution thing - more on that below. In the implementation, I've renamed the operator-created-rules to "access rules". I stole this from Istio after Adam pointed out they have a really similar concept[3]. I really like this name because I think it well-describes the thing we're building without already being overloaded.
I struggled with this name, but I didn't have a worth-while replacement to suggest. I like using "access rules" but...
So far, I've kept the user-created-rules as "capabilities" but I'm not a fan of it because it's an overloaded word and not very descriptive, although in my opinion it is still more descriptive than "whitelist" which is what we were originally going to call it. It might make sense to relate this property somehow to the operator-created-rules - perhaps by calling it access_rules_list, or granted_access_rules. Or we could call *this* thing the access rules, and call the other thing allowed_access_rules or permitted_access_rules.
... I think the final proposal here is a great idea, using "access rules" for both with one having a slightly more specific derivative, tailored either for operators or users. The fact we have an association between the two via naming is better than what we had with "template" and "capability".
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions.
I agree about the awkwardness and complexity, but I do want to clarify. Using the example above, going with * and ** would mean that tokens generated from that application credential would be actionable on any project tag for the project the application credential was created for and not just 'foobar'. For an initial implementation, I think that's fine. Sure, creating an application credential specific to a single server is ideal, but at least we're heading in the right direction by limiting its usage to a single API. If we get that right - we should be able to iteratively add filtering later*. I wouldn't mind re-raising this particular point after we have more feedback from the user community. * iff we need to
* UUIDs
The spec says each operator-created-rule should have its own UUID, and the end user needs to look up and provide this UUID when they create the app cred rule. This has the benefit of having a fast lookup because we've put the onus on the user to look up the rule themselves, but I think it is very user-unfriendly. In the proposed implementation, I've done away with UUIDs on the operator-created-rules, and instead a match is looked up based on the service type, request path and method, and the "allow_chained" attribute (more on that next). Depending on how big we think this list of APIs will get, this will have some impact on performance on creation time (not at token validation time).
UUIDs make sense for singleton resources that are created in a database. I imagine this starting as an operator-managed configuration file, and maybe some day in the future a catalog of this sort could be published by the services so that the operator doesn't have to maintain it themselves. To that end, I've implemented the operator-created-rules driver with a JSON file backend. But with this style of implementation, including UUIDs for every rule is awkward - it only makes sense if we're generating the resources within keystone and storing them in a database.
* allow_chained
The allow_chained attribute looks and feels awkward and adds complexity to the code Is there really a case when either the user or operator would not want to allow a service to make a request on behalf of a user who is making a more general request? Also, can we find a better name for it?
Not that I can think of, but I'd like to hear an operator or user chime in. The example brought up in IRC advocating for the attribute was: - I need to create an application credential that "something" can use to create a server, but that "something" can't create ephemeral storage Otherwise, maybe we can meet in the middle by deciding a sane default behavior and implementing the toggle later? Regarding the name, it's not really clear what we're chaining. But, after re-reading the details in the specification, it's clear this was specific to "service chaining". I'll have to dig my naming hat out of the closet to come up with something more useful...
Those are all the major question marks for me. There are some other minor differentiations from the spec and I will propose an update that makes it consistent with reality after we have these other questions sorted out.
It would have taken me way longer to distill this from Gerrit. Thanks again for taking the time to write it up.
Colleen
[1] https://review.openstack.org/#/q/topic:bp/whitelist-extension-for-app-creds [2] http://specs.openstack.org/openstack/keystone-specs/specs/keystone/stein/cap... [3] https://istio.io/docs/reference/config/authorization/istio.rbac.v1alpha1/#Ac...
On Thu, Feb 21, 2019, at 11:32 PM, Lance Bragstad wrote:
On 2/21/19 3:11 PM, Colleen Murphy wrote:
[snipped]
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions.
I agree about the awkwardness and complexity, but I do want to clarify. Using the example above, going with * and ** would mean that tokens generated from that application credential would be actionable on any project tag for the project the application credential was created for and not just 'foobar'.
Not exactly. Say the operator has configured a rule like: GET /v3/projects/*/tags/* The user then has the ability to configure one or more of several rules: GET /v3/projects/*/tags/* # this application credential can be used on any project on any tag GET /v3/projects/UUID/tags/* # this application credential can be used on a specific project on any tag GET /v3/projects/*/tags/foobar # this application credential can be used on any project but only for tag "foobar" GET /v3/projects/UUID/tags/foobar # this application credential can only be used on one specific project and one specific tag The matching rule for capability creation would be flexible enough to allow any of these.
For an initial implementation, I think that's fine. Sure, creating an application credential specific to a single server is ideal, but at least we're heading in the right direction by limiting its usage to a single API. If we get that right - we should be able to iteratively add filtering later*. I wouldn't mind re-raising this particular point after we have more feedback from the user community.
* iff we need to
[snipped] Colleen
On 2/22/19 4:54 AM, Colleen Murphy wrote:
On Thu, Feb 21, 2019, at 11:32 PM, Lance Bragstad wrote:
On 2/21/19 3:11 PM, Colleen Murphy wrote:
[snipped]
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions. I agree about the awkwardness and complexity, but I do want to clarify. Using the example above, going with * and ** would mean that tokens generated from that application credential would be actionable on any project tag for the project the application credential was created for and not just 'foobar'. Not exactly. Say the operator has configured a rule like:
GET /v3/projects/*/tags/*
The user then has the ability to configure one or more of several rules:
GET /v3/projects/*/tags/* # this application credential can be used on any project on any tag GET /v3/projects/UUID/tags/* # this application credential can be used on a specific project on any tag GET /v3/projects/*/tags/foobar # this application credential can be used on any project but only for tag "foobar" GET /v3/projects/UUID/tags/foobar # this application credential can only be used on one specific project and one specific tag
The matching rule for capability creation would be flexible enough to allow any of these.
Oh - so we're just not allowing for the substitution to be a formal attribute of the application credential?
For an initial implementation, I think that's fine. Sure, creating an application credential specific to a single server is ideal, but at least we're heading in the right direction by limiting its usage to a single API. If we get that right - we should be able to iteratively add filtering later*. I wouldn't mind re-raising this particular point after we have more feedback from the user community.
* iff we need to
[snipped]
Colleen
On Fri, Feb 22, 2019, at 5:27 PM, Lance Bragstad wrote:
On 2/22/19 4:54 AM, Colleen Murphy wrote:
On Thu, Feb 21, 2019, at 11:32 PM, Lance Bragstad wrote:
On 2/21/19 3:11 PM, Colleen Murphy wrote:
[snipped]
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions. I agree about the awkwardness and complexity, but I do want to clarify. Using the example above, going with * and ** would mean that tokens generated from that application credential would be actionable on any project tag for the project the application credential was created for and not just 'foobar'. Not exactly. Say the operator has configured a rule like:
GET /v3/projects/*/tags/*
The user then has the ability to configure one or more of several rules:
GET /v3/projects/*/tags/* # this application credential can be used on any project on any tag GET /v3/projects/UUID/tags/* # this application credential can be used on a specific project on any tag GET /v3/projects/*/tags/foobar # this application credential can be used on any project but only for tag "foobar" GET /v3/projects/UUID/tags/foobar # this application credential can only be used on one specific project and one specific tag
The matching rule for capability creation would be flexible enough to allow any of these.
Oh - so we're just not allowing for the substitution to be a formal attribute of the application credential?
Right, and similarly the list of "user template keys" and "context template keys" in the operator-created-rules won't be needed any more.
For an initial implementation, I think that's fine. Sure, creating an application credential specific to a single server is ideal, but at least we're heading in the right direction by limiting its usage to a single API. If we get that right - we should be able to iteratively add filtering later*. I wouldn't mind re-raising this particular point after we have more feedback from the user community.
* iff we need to
[snipped]
Colleen
Attachments: * signature.asc
On 2/22/19 12:22 PM, Colleen Murphy wrote:
On Fri, Feb 22, 2019, at 5:27 PM, Lance Bragstad wrote:
On 2/22/19 4:54 AM, Colleen Murphy wrote:
On Thu, Feb 21, 2019, at 11:32 PM, Lance Bragstad wrote:
On 2/21/19 3:11 PM, Colleen Murphy wrote: [snipped]
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions. I agree about the awkwardness and complexity, but I do want to clarify. Using the example above, going with * and ** would mean that tokens generated from that application credential would be actionable on any project tag for the project the application credential was created for and not just 'foobar'. Not exactly. Say the operator has configured a rule like:
GET /v3/projects/*/tags/*
The user then has the ability to configure one or more of several rules:
GET /v3/projects/*/tags/* # this application credential can be used on any project on any tag GET /v3/projects/UUID/tags/* # this application credential can be used on a specific project on any tag GET /v3/projects/*/tags/foobar # this application credential can be used on any project but only for tag "foobar" GET /v3/projects/UUID/tags/foobar # this application credential can only be used on one specific project and one specific tag
The matching rule for capability creation would be flexible enough to allow any of these. Oh - so we're just not allowing for the substitution to be a formal attribute of the application credential?
Right, and similarly the list of "user template keys" and "context template keys" in the operator-created-rules won't be needed any more.
Awesome, I'm on board. This is more usable than how I originally interpreted the email. We can always revisit this later, too.
For an initial implementation, I think that's fine. Sure, creating an application credential specific to a single server is ideal, but at least we're heading in the right direction by limiting its usage to a single API. If we get that right - we should be able to iteratively add filtering later*. I wouldn't mind re-raising this particular point after we have more feedback from the user community.
* iff we need to
[snipped]
Colleen
Attachments: * signature.asc
On Thu, Feb 21, 2019, at 10:11 PM, Colleen Murphy wrote:
I have an initial draft of application credential capabilities available for review[1]. The spec[2] was not straightforward to implement. There were a few parts that I found unintuitive, user-unfriendly, and overcomplicated. The current proposed implementation differs from the spec in some ways that I want to discuss with the team. Given that non-client library freeze is next week, and the changes we need in keystonemiddleware also require changes in keystoneclient, I'm not sure there is enough time to properly flesh this out and allow for thorough code review, but if we miss the deadline we can be ready to get this in in the beginning of next cycle (with apologies to everyone waiting on this feature - I just want to make sure we get it right with minimal regrets).
* Naming
As always, naming is hard. In the spec, we've called the property that is attached to the app cred "capabilities" (for the sake of this email I'm going to call it user-created-rules), and we've called the operator-configured list of available endpoints "permissible path templates" (for the sake of this email I'm going to call it operator-created-rules). I find both confusing and awkward.
"Permissible path templates" is not a great name because the rule is actually about more than just the path, it's about the request as a whole, including the method. I'd like to avoid saying "template" too because that evokes a picture of something like a Jinja or ERB template, which is not what this is, and because I'd like to avoid the whole string substitution thing - more on that below. In the implementation, I've renamed the operator-created-rules to "access rules". I stole this from Istio after Adam pointed out they have a really similar concept[3]. I really like this name because I think it well-describes the thing we're building without already being overloaded.
So far, I've kept the user-created-rules as "capabilities" but I'm not a fan of it because it's an overloaded word and not very descriptive, although in my opinion it is still more descriptive than "whitelist" which is what we were originally going to call it. It might make sense to relate this property somehow to the operator-created-rules - perhaps by calling it access_rules_list, or granted_access_rules. Or we could call *this* thing the access rules, and call the other thing allowed_access_rules or permitted_access_rules.
* Substitutions
The way the spec lays out variable components of the URL paths for both user-created-rules and operator-created-rules is unnecessarily complex and in some cases faulty. The only way I can explain how complicated it is is to try to give an example:
Let's say we want to allow a user to create an application credential that allows the holder to issue a GET request on the identity API that looks like /v3/projects/ef7284b4-3a75-4570-8ea8-b30214f18538/tags/foobar. The spec says that the string '/v3/projects/{project_id}/tags/{tag}' is what should be provided verbatim in the "path" attribute of a "capability", then there should be a "substitutions" attribute that sets {"tag": "foobar"}, then the project_id should be taken from the token scope at app cred usage time. When the capability is validated against the operator-created-rules at app cred creation time, it needs to check that the path string matches exactly, that the keys of the "substitutions" dict matches the "user template keys" list, and that keys required by the "context template keys" are provided by the token context.
Taking the project ID, domain ID, or user ID from the token scope is not going to work because some of these APIs may actually be system-scoped APIs - it's just not a hard and fast rule that a project/domain/user ID in the URL maps to the same user and scope of the token used to create it. Once we do away with that, it stops making sense to have a separate attribute for the user-provided substitutions when they could just include that in the URL path to begin with. So the proposed implementation simply allows the wildcards * and ** in both the operator-created-rules and user-created-rules, no python-formatting variable substitutions.
* UUIDs
The spec says each operator-created-rule should have its own UUID, and the end user needs to look up and provide this UUID when they create the app cred rule. This has the benefit of having a fast lookup because we've put the onus on the user to look up the rule themselves, but I think it is very user-unfriendly. In the proposed implementation, I've done away with UUIDs on the operator-created-rules, and instead a match is looked up based on the service type, request path and method, and the "allow_chained" attribute (more on that next). Depending on how big we think this list of APIs will get, this will have some impact on performance on creation time (not at token validation time).
UUIDs make sense for singleton resources that are created in a database. I imagine this starting as an operator-managed configuration file, and maybe some day in the future a catalog of this sort could be published by the services so that the operator doesn't have to maintain it themselves. To that end, I've implemented the operator-created-rules driver with a JSON file backend. But with this style of implementation, including UUIDs for every rule is awkward - it only makes sense if we're generating the resources within keystone and storing them in a database.
* allow_chained
The allow_chained attribute looks and feels awkward and adds complexity to the code Is there really a case when either the user or operator would not want to allow a service to make a request on behalf of a user who is making a more general request? Also, can we find a better name for it?
Those are all the major question marks for me. There are some other minor differentiations from the spec and I will propose an update that makes it consistent with reality after we have these other questions sorted out.
Colleen
[1] https://review.openstack.org/#/q/topic:bp/whitelist-extension-for-app-creds [2] http://specs.openstack.org/openstack/keystone-specs/specs/keystone/stein/cap... [3] https://istio.io/docs/reference/config/authorization/istio.rbac.v1alpha1/#Ac...
We discussed this a bit on IRC[4] and I've proposed a revision to the spec[5] to capture the proposed alterations. Colleen [4] http://eavesdrop.openstack.org/irclogs/%23openstack-keystone/%23openstack-ke... [5] https://review.openstack.org/639182
participants (2)
-
Colleen Murphy
-
Lance Bragstad