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