Update access rules spec with decisions from PTG
Change-Id: I58b1b57febaea7f8bc75bf9e737e2d42f7823cf6
This commit is contained in:
parent
7837c2031e
commit
94df8711bc
|
@ -93,20 +93,13 @@ by keystonemiddleware as follows:
|
|||
This list is a whitelist, i.e. any request not explicitly allowed by an
|
||||
access rule is rejected. Keystone itself does not validate the content of
|
||||
access rules because that would require domain knowledge of each service in
|
||||
the catalog. Every access rule must match a permitted access rule as
|
||||
described in the `Access Rules Config`_ section below. If one or more
|
||||
access rule entries fail this test, application credential creation will
|
||||
fail.
|
||||
the catalog.
|
||||
|
||||
2) A future iteration of this feature will create a toggle to control whether a
|
||||
service can use one of these token to make background requests on behalf of
|
||||
the user, for example to allow the compute service to make requests to the
|
||||
block storage service even though the block storage API wasn't explicitly
|
||||
whitelisted in the application credential access rules. For the time being,
|
||||
chained service requests like this will be unrestricted and will rely on
|
||||
operator-configured policies to prevent abuse.
|
||||
The access rules are stored in a separate database table and linked to the
|
||||
application credential so that old rules can be re-used with new application
|
||||
credentials.
|
||||
|
||||
3) `keystonemiddleware` on the service's side receives the access rule list
|
||||
2) `keystonemiddleware` on the service's side receives the access rule list
|
||||
during token validation. It then checks
|
||||
|
||||
(a) The service type (e.g. `compute`)
|
||||
|
@ -132,46 +125,6 @@ by keystonemiddleware as follows:
|
|||
|
||||
.. _published Service Types Authority: https://service-types.openstack.org/
|
||||
|
||||
Access Rules Config
|
||||
-------------------
|
||||
|
||||
Every access rule must be validated against an operator-configured list upon
|
||||
application credential upon creation, unless the operator has explicitly
|
||||
configured a permissive mode that does no validation. This section describes how
|
||||
an operator defines a list and how they are used by Keystone.
|
||||
|
||||
The allowed access rules are operator configured as a JSON config file on disk,
|
||||
with the idea that perhaps such a catalog might be exposed on service endpoints
|
||||
someday. Keystone will document a curated list of URL templates for those APIs
|
||||
where such a thing can be generated automatically. The operator can then use
|
||||
this list as-is in the simplest case, or modify it for their local setup as they
|
||||
chose. For every access rule the following information is stored:
|
||||
|
||||
1) A service type that matches one of the services in the Keystone catalog.
|
||||
|
||||
2) A URL path pattern, such as `/v2.1/servers/{server_id}`. The combination
|
||||
of this string and the service type from (1) must be unique. It is anchored at
|
||||
the beginning of a path, i.e. access rules' path attributes must fully match
|
||||
this pattern and may not be preceded or followed by extra characters. The
|
||||
template string may contain the following special wildcard templates:
|
||||
|
||||
* `{named_variable}`: allows arbitrary strings (excluding the `/` character).
|
||||
Named placeholders in the access rule path pattern are there for
|
||||
readability and direct comparison to API references and policy files, they
|
||||
do not correlate to string formatting substitutions. Examples include
|
||||
`{project_id}`, `{user_id}`, or `{server_id}`.
|
||||
|
||||
* `*`: allows arbitrary strings (excluding the `/` character)
|
||||
|
||||
* `**`: allows arbitrary strings (including the `/` character)
|
||||
|
||||
A user using a path pattern containing wild cards for validating one of
|
||||
their access rules may substitute the wild card by any string fulfilling the
|
||||
constraint imposed by the wild card. This allows the operator to be
|
||||
permissive in their URL templates (to the point of only having one "**"
|
||||
pattern in the most extreme case) and the user to be more restrictive than a
|
||||
wild card template in their access rules.
|
||||
|
||||
Preventing Regressions
|
||||
----------------------
|
||||
|
||||
|
@ -203,70 +156,10 @@ any application credentials that do not have access rules, validation proceeds
|
|||
as it would have before the introduction of access rules (regardless of whether
|
||||
there is an `Openstack-Identity-Access-Rules` or not).
|
||||
|
||||
Discoverability for Access Rules Config
|
||||
---------------------------------------
|
||||
|
||||
Any user with a valid auth token can list the operator maintained access rules
|
||||
through the Keystone API::
|
||||
|
||||
GET /v3/access_rules_config
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"compute": [
|
||||
{
|
||||
"path": "/v2.1/servers",
|
||||
"method": "GET"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
This allows them to discover the URL path templates they can use for creating
|
||||
access rules in application credentials.
|
||||
|
||||
Access Rules and Roles
|
||||
----------------------
|
||||
|
||||
Configured access rules will have an optional ROLE_ID value. If this value is
|
||||
set, it indicates the role that the user needs to provide in the application
|
||||
credential in order for the call to proceed. In addition, if the role_id value
|
||||
is set, the user will only be able to use the access rule if the user has that
|
||||
role assigned, either directly, or as a result of an implied role.
|
||||
|
||||
Chained API Calls
|
||||
-----------------
|
||||
|
||||
One thing the access rules make rather tough is chained API calls: if an API
|
||||
call is permitted by an access rule, but the service uses the same access rule
|
||||
restricted token to call other services' APIs, these will fail. While it would
|
||||
be possible to circumvent this problem with additional access rules to cover
|
||||
the chained calls, that would be very poor ergonomics, especially for
|
||||
operations with a large amount of chained API calls such as creating a Heat
|
||||
stack.
|
||||
|
||||
A future optimization of this feature will implement a toggle for access
|
||||
rules to give services blanket permission to perform chained API calls with the
|
||||
token resulting from the Application credential. This is implemented as follows:
|
||||
|
||||
1) If `keystonemiddleware` receives a request that is permitted due to an
|
||||
application credential with this toggle set, it requests a service token and
|
||||
adds it to the request's object's headers.
|
||||
|
||||
2) Follow-up requests issued by the service will then send this service token
|
||||
along with the regular token resulting from the application credential.
|
||||
|
||||
3) If `keystonemiddleware` encounters an application credential generated token
|
||||
with this toggle plus a valid service token it will ignore any
|
||||
non-empty access rulelists and pass the request to the service as-is.
|
||||
|
||||
API Examples
|
||||
------------
|
||||
|
||||
An example creation request for an application credential might look as
|
||||
follows:
|
||||
|
||||
::
|
||||
An example creation request for an application credential looks as follows::
|
||||
|
||||
POST /v3/users/{user_id}/application_credentials
|
||||
|
||||
|
@ -276,22 +169,66 @@ follows:
|
|||
"application_credential": {
|
||||
"name": "allow-metrics-logs",
|
||||
"description": "Allow submitting metrics and logs to Monasca",
|
||||
"roles": [
|
||||
{"name": "monasca-agent"}
|
||||
]
|
||||
"access_rules": [
|
||||
{
|
||||
"path": "/v2.0/metrics",
|
||||
"method": "POST"
|
||||
},
|
||||
{
|
||||
"path": "/v3.0/logs",
|
||||
"method": "POST"
|
||||
}
|
||||
{
|
||||
"path": "/v2.0/metrics",
|
||||
"method": "POST"
|
||||
},
|
||||
{
|
||||
"path": "/v3.0/logs",
|
||||
"method": "POST"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
With this, two new access rules will be created under the user's ID. They can be
|
||||
queried like this:
|
||||
|
||||
Request::
|
||||
|
||||
GET /v3/users/{user_id}/access_rules
|
||||
|
||||
Response:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"access_rules": [
|
||||
{
|
||||
"id": "180e86bc",
|
||||
"path": "/v2.0/metrics",
|
||||
"method": "POST"
|
||||
},
|
||||
{
|
||||
"id": "03e13d17",
|
||||
"path": "/v3.0/logs",
|
||||
"method": "POST"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
If desired, they could then be re-used for another application credential by
|
||||
providing the ID::
|
||||
|
||||
POST /v3/users/{user_id}/application_credentials
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"application_credential": {
|
||||
"name": "allow-just-metrics",
|
||||
"description": "Allow submitting only metrics to Monasca",
|
||||
"access_rules": [
|
||||
{
|
||||
"id": "180e86bc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
|
@ -354,6 +291,44 @@ Alternatives
|
|||
(b) URL paths can be rejected in keystonemiddleware, without involving
|
||||
`oslo.policy`, leading to a faster failure for unauthorized requests.
|
||||
|
||||
Future Considerations
|
||||
---------------------
|
||||
|
||||
Chained API Calls
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
A future iteration of this feature may create a toggle to control whether a
|
||||
service can use one of these tokens to make background requests on behalf of
|
||||
the user, for example to allow the compute service to make requests to the
|
||||
block storage service even though the block storage API wasn't explicitly
|
||||
whitelisted in the application credential access rules. For the time being,
|
||||
chained service requests like this will leverage service tokens to ensure
|
||||
that subsequent requests made on behalf of a user will be completed as normal,
|
||||
and will rely on operator-configured policies to prevent abuse.
|
||||
|
||||
Access Rules Config
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A future iteration of this feature may enable a way for operators to restrict
|
||||
the allowed access rules that a user may configure by creating a global
|
||||
whitelist of access rules against which users' access rules are validated prior
|
||||
to the creation of the application credential. The value of this would be to assist
|
||||
users in creating valid access rules by validating them against known working
|
||||
rules. It would also give the operator more control of the overall access
|
||||
control configuration. However, for the time being, this feature is infeasible
|
||||
because we lack discoverability of APIs and it is impossible to create a
|
||||
complete list of valid access rules for all services across OpenStack and
|
||||
external to OpenStack. Since providing a complete list is infeasible, leaving it
|
||||
up to the operator to curate their own list causes a poor operating experience
|
||||
for the operator and the list would be susceptible to mistakes, which in turn
|
||||
would cause an extremely poor user experience for the end user.
|
||||
|
||||
When this feature becomes feasible, another possibility is to allow operators to
|
||||
configure a role ID for each access rule to indicate that the user needs to
|
||||
provide that role in the application credential in order for the call to
|
||||
proceed. This allows for greater alignment between policy rules and access
|
||||
rules.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
|
@ -494,3 +469,9 @@ References
|
|||
|
||||
* Updated design discussion:
|
||||
http://lists.openstack.org/pipermail/openstack-discuss/2019-February/003031.html
|
||||
|
||||
* Notes from Train Forum session:
|
||||
https://etherpad.openstack.org/p/DEN-keystone-forum-sessions-app-creds
|
||||
|
||||
* Notes from Train PTG session:
|
||||
https://etherpad.openstack.org/p/keystone-train-ptg-application-credentials
|
||||
|
|
Loading…
Reference in New Issue