Update app cred capabilities spec
This change brings the spec, which was agreed upon nearly a year ago, into alignment with the current proposed implementation. It also cleans up some formatting and style issues. Change-Id: I0bd99d24517b90f16557aadc3d721ecee9cd8eb5
This commit is contained in:
parent
b9041f0f77
commit
c83ae97852
|
@ -16,7 +16,7 @@ credentials and trusts. Other than that they allow unfettered use of the roles
|
||||||
being delegated in the project the application credential is created for. This
|
being delegated in the project the application credential is created for. This
|
||||||
renders application credentials questionable anywhere a least-privilege
|
renders application credentials questionable anywhere a least-privilege
|
||||||
delegation is desired. Technically it would be possible to store a white list
|
delegation is desired. Technically it would be possible to store a white list
|
||||||
style list of capabilities for an application credential which other OpenStack
|
style list of access rules for an application credential which other OpenStack
|
||||||
services would then enforce. This spec outlines an approach for storing and
|
services would then enforce. This spec outlines an approach for storing and
|
||||||
handling such restrictions.
|
handling such restrictions.
|
||||||
|
|
||||||
|
@ -34,11 +34,12 @@ in the Grizzly release). Right now, trusts are used by the following projects
|
||||||
among others (list may not be complete):
|
among others (list may not be complete):
|
||||||
|
|
||||||
* Heat: operations on behalf of the user at times when a token may have expired
|
* Heat: operations on behalf of the user at times when a token may have expired
|
||||||
already.
|
already.
|
||||||
|
|
||||||
* Magnum: access to Magnum's certificate signing API and other OpenStack APIs
|
* Magnum: access to Magnum's certificate signing API and other OpenStack APIs
|
||||||
from inside a cluster's instances where the container orchestration
|
from inside a cluster's instances where the container orchestration engine
|
||||||
engine requires it (e.g. Glance as backend for docker-registry or
|
requires it (e.g. Glance as backend for docker-registry or cinder as backend
|
||||||
cinder as backend for docker-volume)
|
for docker-volume)
|
||||||
|
|
||||||
Other projects (neutron-lbaas, Barbican) hesitate to employ trusts and
|
Other projects (neutron-lbaas, Barbican) hesitate to employ trusts and
|
||||||
application credentials since they are an all-or-nothing approach: they grant
|
application credentials since they are an all-or-nothing approach: they grant
|
||||||
|
@ -78,137 +79,98 @@ The approach to implementing fine-grained permissions for application
|
||||||
credentials is two-pronged. Permission data is stored in Keystone and enforced
|
credentials is two-pronged. Permission data is stored in Keystone and enforced
|
||||||
by keystonemiddleware as follows:
|
by keystonemiddleware as follows:
|
||||||
|
|
||||||
1) Alongside an application credential, a capability list with zero or more
|
1) Alongside an application credential, a list of access rules with zero or
|
||||||
capabilities can be stored. An entry in this list consists of:
|
more access rules can be stored. An entry in this list consists of:
|
||||||
|
|
||||||
(a) A URL path (e.g. `/v2.1/servers` or `/v2.1/servers/{server_id}`).
|
(a) A URL path (e.g. `/v2.1/servers`, `/v2.1/servers/*` or
|
||||||
This URL path must be permissible according to a URL path template
|
`/v2.1/servers/{server_id}`). This URL path must be explicitly permitted
|
||||||
which must exist in the table of URL path templates (see `Permissible
|
according to an operator-configured list of access rules (see `Access Rules
|
||||||
Path Templates`_ below).
|
Config`_ below).
|
||||||
(b) A dictionary whose keys need to exactly match the placeholders in the
|
(b) A request method (e.g. `GET`)
|
||||||
URL path. Both extraneous and missing keys for one or more
|
(c) A service type (ideally matching the `published Service Types Authority`_)
|
||||||
capabilities will cause application credential creation to fail.
|
from the Keystone service catalog.
|
||||||
(c) A request type (e.g. `GET`)
|
|
||||||
(d) A service UUID from the Keystone service catalog. This UUID is not
|
|
||||||
user provided. Instead, it is filled in from the URL template this
|
|
||||||
capability is validated against.
|
|
||||||
|
|
||||||
This list is a whitelist, e.g. any request not explicitly allowed by a
|
This list is a whitelist, i.e. any request not explicitly allowed by an
|
||||||
capability is rejected. Keystone itself does not validate the content of
|
access rule is rejected. Keystone itself does not validate the content of
|
||||||
capabilities because that would require domain knowledge of each service on
|
access rules because that would require domain knowledge of each service in
|
||||||
Keystone's path. Every capability must reference an row in the table
|
the catalog. Every access rule must match a permitted access rule as
|
||||||
described in the `Permissible Path Templates`_ section below. If one or more
|
described in the `Access Rules Config`_ section below. If one or more
|
||||||
capabilities entries fail this test, API Credential creation will fail.
|
access rule entries fail this test, application credential creation will
|
||||||
|
fail.
|
||||||
|
|
||||||
2) A boolean `allow_chained` attribute of the application credential (`False`
|
2) A future iteration of this feature will create a toggle to control whether a
|
||||||
by default) controls whether chained API calls, i.e. follow-up calls issued
|
service can use one of these token to make background requests on behalf of
|
||||||
by a service as a result of an API call permitted by a capability. This may
|
the user, for example to allow the compute service to make requests to the
|
||||||
only be set to `True` if all capabilities listed in the template were
|
block storage service even though the block storage API wasn't explicitly
|
||||||
validated against an URL template with its own `allow_chained` attribute set
|
whitelisted in the application credential access rules. For the time being,
|
||||||
to `True`.
|
chained service requests like this will be unrestricted and will rely on
|
||||||
|
operator-configured policies to prevent abuse.
|
||||||
|
|
||||||
3) `keystonemiddleware` on the service's side receives the capability list
|
3) `keystonemiddleware` on the service's side receives the access rule list
|
||||||
during token validation. It then performs templating on all entries and
|
during token validation. It then checks
|
||||||
checks
|
|
||||||
|
|
||||||
(a) The service's own service ID (e.g.
|
(a) The service type (e.g. `compute`)
|
||||||
`ae8a69ae-3bc2-4189-88be-c0b9ea6ef06f`)
|
(b) The URL path (e.g. `/v2.1/servers/*` or `/v2.1/servers/{server_id}`
|
||||||
(b) The URL path (e.g. `/v2.1/servers/{*}` or
|
or `/v2.1/servers/b2088298-50e5-4c81-8a50-66bfd1d8943b`)
|
||||||
`/v2.1/servers/b2088298-50e5-4c81-8a50-66bfd1d8943b`)
|
(c) The request method (e.g. `GET`)
|
||||||
(c) The request's type (e.g. `GET`)
|
|
||||||
|
|
||||||
Against every entry in the templated URL list computed from the capability
|
Against every entry in the access rule list retrieved from the token. If an
|
||||||
information in the token (See `URL Path Templating`_ for how it is
|
access rule matches the request, checking stops and the request is handed over
|
||||||
computed). If a capability matches the request, checking stops and the
|
to `oslo.policy` for the regular role based checking. If no access rules
|
||||||
request is handed over to `oslo.policy` for the regular role based checking.
|
match, the request is rejected right away.
|
||||||
If no capabilities match, the request is rejected right away.
|
|
||||||
|
|
||||||
There are three special cases to capability list processing:
|
There are three special cases to access rule list processing:
|
||||||
|
|
||||||
(a) If no list is provided (i.e. if the `capabilities` attribute is
|
(a) If no list is provided (i.e. if the `access_rules` attribute is
|
||||||
`None`), no capability checking is performed and the request is passed
|
`None`), no access rule checking is performed and the request is passed
|
||||||
to `oslo.policy` right away.
|
to `oslo.policy` right away.
|
||||||
(b) If an empty list is provided (i.e. `[]`), all requests are rejected
|
(b) If an empty list is provided (i.e. `[]`), all requests are rejected
|
||||||
(even if the request would otherwise pass the test in (c).
|
(even if the request would otherwise pass the test in (c).
|
||||||
(c) If the application credential's `allow_chained` attribute is `True`
|
(c) If there is a valid service token in the request, `keystonemiddleware`
|
||||||
and there is a valid service token in the request,
|
passes the request to `oslo.policy` right away, though a future iteration
|
||||||
`keystonemiddleware` passes the request to `oslo.policy` right away.
|
of this feature will enable a toggle to control this behavior.
|
||||||
|
|
||||||
Permissible Path Templates
|
.. _published Service Types Authority: https://service-types.openstack.org/
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Every capability must be validated against a URL Path Template referenced by
|
Access Rules Config
|
||||||
UUID upon application credential upon creation. This section describes how an
|
-------------------
|
||||||
operator defines such URL path templates and how they are used by Keystone.
|
|
||||||
|
|
||||||
The permissible URL path templates are operator configured through the Keystone
|
Every access rule must be validated against an operator-configured list upon
|
||||||
API and stored in a dedicated table in the Keystone database. Keystone will
|
application credential upon creation, unless the operator has explicitly
|
||||||
document a curated list of URL templates for those APIs where such a thing can
|
configured a permissive mode that does no validation. This section describes how
|
||||||
be generated automatically. The operator can then use this list as-is in the
|
an operator defines a list and how they are used by Keystone.
|
||||||
simplest case, or modify it for their local setup as they chose. For every URL
|
|
||||||
template the following information is stored:
|
|
||||||
|
|
||||||
1) A service UUID that matches one of the services in the Keystone catalog.
|
The allowed access rules are operator configured as a JSON config file on disk,
|
||||||
This is copied to the capability verbatim. The service UUID is validated
|
with the idea that perhaps such a catalog might be exposed on service endpoints
|
||||||
upon URL template creation: it must match an existing service's UUID. This
|
someday. Keystone will document a curated list of URL templates for those APIs
|
||||||
UUID should not have a foreign key constraint so as not to create
|
where such a thing can be generated automatically. The operator can then use
|
||||||
dependencies from the catalog on URL templates or the capabilities validated
|
this list as-is in the simplest case, or modify it for their local setup as they
|
||||||
against them. If a service is deleted later, and a non-existent UUID is thus
|
chose. For every access rule the following information is stored:
|
||||||
being referenced, keystonemiddleware will reject any capabilities
|
|
||||||
referencing it since there is no service whose service UUID will match it at
|
1) A service type that matches one of the services in the Keystone catalog.
|
||||||
that point.
|
|
||||||
2) A UUID that serves as a unique resource identifier. This is used to
|
2) A URL path pattern, such as `/v2.1/servers/{server_id}`. The combination
|
||||||
reference the path template to use for evaluation when creating a
|
of this string and the service type from (1) must be unique. It is anchored at
|
||||||
capability. This reference is only used for validation upon application
|
the beginning of a path, i.e. access rules' path attributes must fully match
|
||||||
credential creation and not recorded as part of the application credential.
|
|
||||||
3) A URL template string, such as `/v2.1/servers/{server_id}`. The combination
|
|
||||||
of this string and the service ID from (1) must be unique. It is anchored at
|
|
||||||
the beginning of a path, i.e. capabilities' path attributes must fully match
|
|
||||||
this pattern and may not be preceded or followed by extra characters. The
|
this pattern and may not be preceded or followed by extra characters. The
|
||||||
template string may contain the following special wildcard templates:
|
template string may contain the following special wildcard templates:
|
||||||
|
|
||||||
* `{*}`: allows arbitrary strings (excluding the `/` character) in
|
* `{named_variable}`: allows arbitrary strings (excluding the `/` character).
|
||||||
capability enforcement.
|
Named placeholders in the access rule path pattern are there for
|
||||||
* `{**}`: allows arbitrary strings (including the `/` character) in
|
readability and direct comparison to API references and policy files, they
|
||||||
capability enforcement.
|
do not correlate to string formatting substitutions. Examples include
|
||||||
|
`{project_id}`, `{user_id}`, or `{server_id}`.
|
||||||
|
|
||||||
A user using a URL template containing wild cards for validating one of
|
* `*`: allows arbitrary strings (excluding the `/` character)
|
||||||
their capabilities may substitute the wild card by any string fulfilling the
|
|
||||||
|
* `**`: 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
|
constraint imposed by the wild card. This allows the operator to be
|
||||||
permissive in their URL templates (to the point of only having one "{**}"
|
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
|
pattern in the most extreme case) and the user to be more restrictive than a
|
||||||
wild card template in their capabilities.
|
wild card template in their access rules.
|
||||||
4) A boolean `allow_chained` attribute (`False` by default). If this is `True`
|
|
||||||
for all URL templates referenced when creating an application credential,
|
|
||||||
that application credential's own `allow_chained` attribute may be set to
|
|
||||||
`True`.
|
|
||||||
5) A list of template keys to be provided by the user (henceforth referred to
|
|
||||||
as "user template keys").
|
|
||||||
6) A list of template keys to be provided from token context. (henceforth
|
|
||||||
referred to as "context template keys"). The following are available:
|
|
||||||
|
|
||||||
* `domain_id` UUID of the domain the Application Credential is scoped to
|
|
||||||
(where applicable)
|
|
||||||
* `project_id` UUID of the project the Application Credential is scoped to
|
|
||||||
(where applicable)
|
|
||||||
* `user_id` UUID of the user who created the Application Credential
|
|
||||||
|
|
||||||
Between (4) and (5) all template keys in the URL template string must be
|
|
||||||
covered. If this condition is not met, creation of the path template fails.
|
|
||||||
|
|
||||||
URL Path Templating
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
`keystonemiddleware` receives the capability list information upon token
|
|
||||||
validation. It then processes each capability as follows:
|
|
||||||
|
|
||||||
1) All placeholders from the user template keys list are replaced by the
|
|
||||||
corresponding values in the user provided dictionary of values in the
|
|
||||||
capability.
|
|
||||||
2) All placeholders from the context template keys list are replaced by the
|
|
||||||
corresponding values from token context.
|
|
||||||
3) Wild card placeholders (`{*}`) are left in place. These will be used during
|
|
||||||
capability enforcement to match any string in the respective path component.
|
|
||||||
|
|
||||||
Preventing Regressions
|
Preventing Regressions
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -216,76 +178,87 @@ Preventing Regressions
|
||||||
If a Keystone API which supports this feature encounters a `keystonemiddleware`
|
If a Keystone API which supports this feature encounters a `keystonemiddleware`
|
||||||
version (or 3rd party software authenticating against Keystone) that dates to
|
version (or 3rd party software authenticating against Keystone) that dates to
|
||||||
before implementation of this feature there is potential for regression: while
|
before implementation of this feature there is potential for regression: while
|
||||||
Keystone would provide the capability list upon token validation, the other
|
Keystone would provide the access rule list upon token validation, the other
|
||||||
side would simply ignore it - giving the requests all the permissions granted
|
side would simply ignore it - giving the requests all the permissions granted
|
||||||
by the delegated roles. This can be prevented by treating application
|
by the delegated roles. This can be prevented by treating application
|
||||||
credentials with capabilities (i.e. a `capabilities` attribute that is not
|
credentials with access rules (i.e. a `access_rules` attribute that is not
|
||||||
`None`) as follows):
|
`None`) as follows):
|
||||||
|
|
||||||
1) When requesting token validation, `keystonemiddleware` (or any 3rd party
|
1) When requesting token validation, `keystonemiddleware` (or any 3rd party
|
||||||
application that supports capability enforcement) sets an
|
application that supports access rule enforcement) sets an
|
||||||
`Openstack-Identity-Capabilities` header with a version string as its value.
|
`Openstack-Identity-Access-Rules` header with a version string as its value.
|
||||||
Token validation for an application credential with a capability list will
|
Token validation for an application credential with a access rule list will
|
||||||
only succeed if this header is present. The version string will allow us to
|
only succeed if this header is present. The version string will allow us to
|
||||||
safely extend this feature by invalidating tokens using the extended version
|
safely extend this feature by invalidating tokens using the extended version
|
||||||
in situations where `keystonemiddleware` only supports an older version
|
in situations where `keystonemiddleware` only supports an older version
|
||||||
of this feature.
|
of this feature.
|
||||||
|
|
||||||
2) If there is no `Openstack-Identity-Capabilities` header in the token
|
2) If there is no `Openstack-Identity-Access-Rules` header in the token
|
||||||
validation request, token validation fails.
|
validation request, token validation fails.
|
||||||
|
|
||||||
This way we ensure that nobody erroneously assumes capabilities are being
|
This way we ensure that nobody erroneously assumes access rules are being
|
||||||
enforced in environments where outdated `keystonemiddleware` (or its equivalent
|
enforced in environments where outdated `keystonemiddleware` (or its equivalent
|
||||||
in 3rd party software) cannot enforce them because it is not aware of them. For
|
in 3rd party software) cannot enforce them because it is not aware of them. For
|
||||||
any application credentials that do not have capabilities, validation proceeds
|
any application credentials that do not have access rules, validation proceeds
|
||||||
as it would have before the introduction of capabilities (regardless of whether
|
as it would have before the introduction of access rules (regardless of whether
|
||||||
there is an `Openstack-Identity-Capabilities` or not).
|
there is an `Openstack-Identity-Access-Rules` or not).
|
||||||
|
|
||||||
Discoverability for URL Path Templates
|
Discoverability for Access Rules Config
|
||||||
--------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
Any user with a valid auth token can list the operator maintained URL path
|
Any user with a valid auth token can list the operator maintained access rules
|
||||||
templates through the Keystone API. This allows them to discover the URL path
|
through the Keystone API::
|
||||||
templates they can use for creating capability enabled application credentials.
|
|
||||||
|
|
||||||
URL Templates and Roles
|
GET /v3/access_rules_config
|
||||||
-----------------------
|
|
||||||
|
|
||||||
URL path templates will have an optional ROLE_ID value. If this value is set,
|
.. code-block:: json
|
||||||
it indicates the role that the user needs to provide in the application
|
|
||||||
|
{
|
||||||
|
"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
|
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 URL value in a capability if the
|
is set, the user will only be able to use the access rule if the user has that
|
||||||
user has that role assigned, either directly, or as a result of an implied
|
role assigned, either directly, or as a result of an implied role.
|
||||||
role.
|
|
||||||
|
|
||||||
Chained API Calls
|
Chained API Calls
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
One thing the capabilities make rather tough is chained API calls: if an API
|
One thing the access rules make rather tough is chained API calls: if an API
|
||||||
call is permitted by a capability, but the service uses the same capability
|
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
|
restricted token to call other services' APIs, these will fail. While it would
|
||||||
be possible to circumvent this problem with additional capabilities to cover
|
be possible to circumvent this problem with additional access rules to cover
|
||||||
the chained calls, that would be very poor ergonomics, especially for
|
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
|
operations with a large amount of chained API calls such as creating a Heat
|
||||||
stack.
|
stack.
|
||||||
|
|
||||||
To make it easier on users and services, the `allow_chained` attribute gives
|
A future optimization of this feature will implement a toggle for access
|
||||||
services blanket permission to perform chained API calls with the token
|
rules to give services blanket permission to perform chained API calls with the
|
||||||
resulting from the Application credential. This is implemented as follows:
|
token resulting from the Application credential. This is implemented as follows:
|
||||||
|
|
||||||
1) If `keystonemiddleware` receives a request that is permitted due to an
|
1) If `keystonemiddleware` receives a request that is permitted due to an
|
||||||
application credential with the `allow_chained` attribute set, it requests a
|
application credential with this toggle set, it requests a service token and
|
||||||
service token and adds it to the request's object's headers. Keystone only
|
adds it to the request's object's headers.
|
||||||
allows setting this `allow_chained` attribute for an application credential
|
|
||||||
all capabilities' underlying URL templates have the `allow_chained`
|
|
||||||
attribute set to `True`.
|
|
||||||
|
|
||||||
2) Follow-up requests issued by the service will then send this service token
|
2) Follow-up requests issued by the service will then send this service token
|
||||||
along with the regular token resulting from the application credential.
|
along with the regular token resulting from the application credential.
|
||||||
|
|
||||||
3) If `keystonemiddleware` encounters an application credential generated token
|
3) If `keystonemiddleware` encounters an application credential generated token
|
||||||
with `allow_chained` plus a valid service token it will ignore any
|
with this toggle plus a valid service token it will ignore any
|
||||||
non-empty capability lists and pass the request to the service as-is.
|
non-empty access rulelists and pass the request to the service as-is.
|
||||||
|
|
||||||
API Examples
|
API Examples
|
||||||
------------
|
------------
|
||||||
|
@ -301,107 +274,24 @@ follows:
|
||||||
|
|
||||||
{
|
{
|
||||||
"application_credential": {
|
"application_credential": {
|
||||||
"allow_chained": false,
|
|
||||||
"name": "allow-metrics-logs",
|
"name": "allow-metrics-logs",
|
||||||
"description": "Allow submitting metrics and logs to Monasca",
|
"description": "Allow submitting metrics and logs to Monasca",
|
||||||
"roles": [
|
"roles": [
|
||||||
{"name": "monasca-agent"}
|
{"name": "monasca-agent"}
|
||||||
]
|
]
|
||||||
"capabilities": [
|
"access_rules": [
|
||||||
{
|
{
|
||||||
"path": "/v2.0/metrics",
|
"path": "/v2.0/metrics",
|
||||||
"substitutions": {},
|
"method": "POST"
|
||||||
"type": "POST",
|
|
||||||
"url_template": "376a83c4-c6e9-4cdf-b413-ba4880bfda4d"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "/v3.0/logs",
|
"path": "/v3.0/logs",
|
||||||
"substitutions": {},
|
"method": "POST"
|
||||||
"type": "POST",
|
|
||||||
"url_template": "c73beef3-c982-4ed8-86d5-dd362af48614"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
An example creation request (issued by an operator) for a URL template might
|
|
||||||
look as follows:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
POST /v3/capability-templates
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"capability_template": {
|
|
||||||
"allow_chained": true,
|
|
||||||
"role_id": "0dbbcb80-9d70-4c86-b38a-ae826e501885",
|
|
||||||
"path": "/v2.1/servers/**",
|
|
||||||
"substitutions": {},
|
|
||||||
"service": "67764758-3bdb-462e-babf-537c8fbe7bcd",
|
|
||||||
"type": "GET"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Any user may discover the current list of URL through a
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
GET /v3/capability-templates
|
|
||||||
|
|
||||||
In response they will get a list of URL templates:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"capability_template": {
|
|
||||||
"id": "5631dd39-1451-4101-a961-bbc949624b2f",
|
|
||||||
"allow_chained": true,
|
|
||||||
"role_id": "0dbbcb80-9d70-4c86-b38a-ae826e501885",
|
|
||||||
"path": "/v2.1/servers/**",
|
|
||||||
"substitutions": {},
|
|
||||||
"service": "67764758-3bdb-462e-babf-537c8fbe7bcd",
|
|
||||||
"type": "GET"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"capability_template": {
|
|
||||||
"id": "cdfeecfb-752a-4370-9aaf-03751d3645b3",
|
|
||||||
"allow_chained": false,
|
|
||||||
"role_id": null,
|
|
||||||
"path": "/v2.1/servers/a13b634a-dde3-4e5d-bbcb-3c1482bcf6c8",
|
|
||||||
"substitutions": {},
|
|
||||||
"service": "67764758-3bdb-462e-babf-537c8fbe7bcd",
|
|
||||||
"type": "POST"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"capability_template": {
|
|
||||||
"id": "e86584c8-1a1a-4f5d-9da9-da5e265a0423",
|
|
||||||
"allow_chained": false,
|
|
||||||
"role_id": null,
|
|
||||||
"path": "/v2.0/metrics",
|
|
||||||
"substitutions": {},
|
|
||||||
"service": "1a5e983d-7ac2-4b27-a7a1-caa62a46d82a",
|
|
||||||
"type": "POST"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"capability_template": {
|
|
||||||
"id": "8458c208-6a91-4f54-af89-4598b972cd52",
|
|
||||||
"allow_chained": false,
|
|
||||||
"role_id": null,
|
|
||||||
"path": "/v3.0/logs",
|
|
||||||
"substitutions": {},
|
|
||||||
"service": "f6bd818d-861f-450b-a523-2e1546a06a18",
|
|
||||||
"type": "POST"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
Alternatives
|
Alternatives
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -427,11 +317,11 @@ Alternatives
|
||||||
superficially similar role check in `keystonemiddleware`. There are several
|
superficially similar role check in `keystonemiddleware`. There are several
|
||||||
key differences, though:
|
key differences, though:
|
||||||
|
|
||||||
(a) Application credential capabilities do not require a `Cambrian
|
(a) Application credential access rules do not require a `Cambrian
|
||||||
explosion <https://en.wikipedia.org/wiki/Cambrian_explosion>`_ of
|
explosion <https://en.wikipedia.org/wiki/Cambrian_explosion>`_ of
|
||||||
fine-grained roles (one for every API operation of every OpenStack
|
fine-grained roles (one for every API operation of every OpenStack
|
||||||
service) that must be managed by an administrator.
|
service) that must be managed by an administrator.
|
||||||
(b) Application credential capabilities does not require any changes to
|
(b) Application credential access rules does not require any changes to
|
||||||
existing policy enforcement. Instead, they add an additional check
|
existing policy enforcement. Instead, they add an additional check
|
||||||
that takes place before policy enforcement even comes into play and
|
that takes place before policy enforcement even comes into play and
|
||||||
rejects requests early. Not being entangled with policy enforcement
|
rejects requests early. Not being entangled with policy enforcement
|
||||||
|
@ -441,25 +331,25 @@ Alternatives
|
||||||
(c) The role check in `keystonemiddleware` targets administrators who want
|
(c) The role check in `keystonemiddleware` targets administrators who want
|
||||||
to create role profiles for their users, such as "give this user
|
to create role profiles for their users, such as "give this user
|
||||||
read-only access to any services' resources but without letting them
|
read-only access to any services' resources but without letting them
|
||||||
create new ones". Application credential capabilities on the other
|
create new ones". Application credential access rules on the other
|
||||||
hand, target OpenStack services and third party applications that only
|
hand, target OpenStack services and third party applications that only
|
||||||
need access to a select handful of operations such as "submit SSL
|
need access to a select handful of operations such as "submit SSL
|
||||||
certificates to the Magnum API for signing".
|
certificates to the Magnum API for signing".
|
||||||
(d) Application credential capabilities do not require keystone to be the
|
(d) Application credential access rules do not require keystone to be the
|
||||||
guardian of access control rules, since all the information needed to
|
guardian of access control rules, since all the information needed to
|
||||||
validate access is contained in the token.
|
validate access is contained in the token.
|
||||||
(e) Unlike a policy based check, a capability based check will also work
|
(e) Unlike a policy based check, an access rule based check will also work
|
||||||
for services that do not use `oslo.policy` such as Swift.
|
for services that do not use `oslo.policy` such as Swift.
|
||||||
|
|
||||||
3) One implementation detail from the previous section was discussed at length
|
3) One implementation detail from the previous section was discussed at length
|
||||||
at the Rocky PTG: one could have chosen to match for `oslo.policy` targets
|
at the Rocky PTG: one could have chosen to match for `oslo.policy` targets
|
||||||
rather than URL paths in the capabilities, which would have been easier in
|
rather than URL paths in the access rules, which would have been easier in
|
||||||
some ways. In the end we opted for url paths for the following reasons:
|
some ways. In the end we opted for url paths for the following reasons:
|
||||||
|
|
||||||
(a) This is user facing and unlike API paths, policy targets are not
|
(a) This is user facing and unlike API paths, policy targets are not
|
||||||
easily discoverable by the user since there is no documentation on
|
easily discoverable by the user since there is no documentation on
|
||||||
them. Moreover, policy targets are not as formalized as APIs and may
|
them. Moreover, policy targets are not as formalized as APIs and may
|
||||||
easily change over time, thus breaking existing capabilities.
|
easily change over time, thus breaking existing access rules.
|
||||||
|
|
||||||
(b) URL paths can be rejected in keystonemiddleware, without involving
|
(b) URL paths can be rejected in keystonemiddleware, without involving
|
||||||
`oslo.policy`, leading to a faster failure for unauthorized requests.
|
`oslo.policy`, leading to a faster failure for unauthorized requests.
|
||||||
|
@ -479,16 +369,16 @@ have various security critical aspects:
|
||||||
* This change adds additional information to the token data retrieved by
|
* This change adds additional information to the token data retrieved by
|
||||||
keystonemiddleware upon token validation.
|
keystonemiddleware upon token validation.
|
||||||
|
|
||||||
* URLs in capabilities are user-supplied strings. Care must be taken to
|
* URLs in access rules are user-supplied strings. Care must be taken to
|
||||||
guard against format string attacks in these if anything beyond character by
|
guard against format string attacks in these if anything beyond character by
|
||||||
character comparison takes place.
|
character comparison takes place.
|
||||||
|
|
||||||
* It might be a good idea to limit the length/number of capability rules per
|
* It might be a good idea to limit the length/number of access rules per
|
||||||
API credential to prevent denial of service against the Keystone database (by
|
API credential to prevent denial of service against the Keystone database (by
|
||||||
filling it with bogus rules) or the Keystone API (via large validation
|
filling it with bogus rules) or the Keystone API (via large validation
|
||||||
payloads). Another reason to introduce such a limit is the possibility to
|
payloads). Another reason to introduce such a limit is the possibility to
|
||||||
slow down a service by creating application credentials with a large number
|
slow down a service by creating application credentials with a large number
|
||||||
of non-matching capabilities, which can be used to slow down a particular
|
of non-matching access rules, which can be used to slow down a particular
|
||||||
service.
|
service.
|
||||||
|
|
||||||
* This change is unlikely to allow privilege escalation since it only adds
|
* This change is unlikely to allow privilege escalation since it only adds
|
||||||
|
@ -517,24 +407,9 @@ with the application credential.
|
||||||
That small amount of data may not be so small during the token validation,
|
That small amount of data may not be so small during the token validation,
|
||||||
though, resulting in multiple/more packets being sent in response to a
|
though, resulting in multiple/more packets being sent in response to a
|
||||||
validation request, causing congestion and/or increasing latency. This can be
|
validation request, causing congestion and/or increasing latency. This can be
|
||||||
mitigated by limiting the number of capabilities allowed per application
|
mitigated by limiting the number of access rules allowed per application
|
||||||
credential.
|
credential.
|
||||||
|
|
||||||
Other Deployer Impact
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
This change will introduce the following settings for Keystone:
|
|
||||||
|
|
||||||
* `[application_credential]/soft_capability_quota` [Default: `5`] This setting
|
|
||||||
determines the number of entries allowed in newly created capability lists
|
|
||||||
globally. `-1` denotes an unlimited number of entries. Any existing
|
|
||||||
application credentials with more capabilities will continue to work.
|
|
||||||
|
|
||||||
* `[application_credential]/hard_capability_quota` [Default: `-1`] This setting
|
|
||||||
determines the number of entries allowed in capability lists globally. `-1`
|
|
||||||
denotes an unlimited number of entries. Any existing application credentials
|
|
||||||
with more capabilities will fail token validation.
|
|
||||||
|
|
||||||
Developer Impact
|
Developer Impact
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -544,9 +419,9 @@ delegate access to a user's roles according to the principle of least
|
||||||
privilege.
|
privilege.
|
||||||
|
|
||||||
As far as the application credentials API is concerned, it will be fully
|
As far as the application credentials API is concerned, it will be fully
|
||||||
backwards compatible, since specifying capabilities when creating an
|
backwards compatible, since specifying access rules when creating an
|
||||||
application credential is optional: if none are specified, the `capabilities`
|
application credential is optional: if none are specified, the `access_rules`
|
||||||
attribute will be `None`, leading to no capability checks being performed.
|
attribute will be `None`, leading to no access rule checks being performed.
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
==============
|
==============
|
||||||
|
@ -556,24 +431,24 @@ Assignee(s)
|
||||||
|
|
||||||
Primary assignee:
|
Primary assignee:
|
||||||
|
|
||||||
* Johannes Grassler <jgr-launchpad@btw23.de> jgr-launchpad
|
* Colleen Murphy <colleen@gazlene.net> cmurphy
|
||||||
|
|
||||||
Other contributors:
|
Other contributors:
|
||||||
|
|
||||||
* Colleen Murphy <colleen@gazlene.net> cmurphy
|
|
||||||
|
|
||||||
* Adam Young <ayoung@redhat.com> ayoung
|
* Adam Young <ayoung@redhat.com> ayoung
|
||||||
|
|
||||||
|
* Johannes Grassler <jgr-launchpad@btw23.de> jgr-launchpad
|
||||||
|
|
||||||
Work Items
|
Work Items
|
||||||
----------
|
----------
|
||||||
|
|
||||||
1. Extend the application credential API and database schema in Keystone to
|
1. Extend the application credential API and database schema in Keystone to
|
||||||
allow for receiving and storing capability lists.
|
allow for receiving and storing access rule lists.
|
||||||
|
|
||||||
2. Implement handling for capabilities in python-keystoneclient and
|
2. Implement handling for access rules in python-keystoneclient and
|
||||||
python-openstackclient.
|
python-openstackclient.
|
||||||
|
|
||||||
3. Extend the Keystone token validation API to capability lists upon
|
3. Extend the Keystone token validation API to access rule lists upon
|
||||||
upon token validation.
|
upon token validation.
|
||||||
|
|
||||||
4. Implement the endpoint list check in keystonemiddleware.
|
4. Implement the endpoint list check in keystonemiddleware.
|
||||||
|
@ -586,13 +461,10 @@ None
|
||||||
Documentation Impact
|
Documentation Impact
|
||||||
====================
|
====================
|
||||||
|
|
||||||
* The capability related settings for application credentials need to be
|
* The access rule related settings for application credentials need to be
|
||||||
documented in the release notes and the admin guide.
|
documented in the release notes and the admin guide.
|
||||||
|
|
||||||
* The URL template "language" outlined in the `Permissible Path Templates`_
|
* Documentation on access rules needs to be added to the *Application
|
||||||
section needs to be documented in the Keystone admin guide.
|
|
||||||
|
|
||||||
* Documentation on capabilities needs to be added to the *Application
|
|
||||||
Credentials* section of the Keystone user documentation.
|
Credentials* section of the Keystone user documentation.
|
||||||
|
|
||||||
References
|
References
|
||||||
|
@ -606,7 +478,7 @@ References
|
||||||
|
|
||||||
* Spec for securing Monasca metric submission from inside VMs
|
* Spec for securing Monasca metric submission from inside VMs
|
||||||
https://review.openstack.org/#/c/507110/ (would be greatly simplified by
|
https://review.openstack.org/#/c/507110/ (would be greatly simplified by
|
||||||
having capabilities in application credentials)
|
having access rules in application credentials)
|
||||||
|
|
||||||
* Documentation on Barbican ACLs:
|
* Documentation on Barbican ACLs:
|
||||||
http://developer.openstack.org/api-guide/key-manager/acls.html
|
http://developer.openstack.org/api-guide/key-manager/acls.html
|
||||||
|
@ -616,3 +488,9 @@ References
|
||||||
|
|
||||||
* Generating a list of URL patterns for OpenStack services
|
* Generating a list of URL patterns for OpenStack services
|
||||||
http://adam.younglogic.com/2018/03/generating-url-patterns/
|
http://adam.younglogic.com/2018/03/generating-url-patterns/
|
||||||
|
|
||||||
|
* Related concept for Istio:
|
||||||
|
https://istio.io/docs/reference/config/authorization/istio.rbac.v1alpha1/#AccessRule
|
||||||
|
|
||||||
|
* Updated design discussion:
|
||||||
|
http://lists.openstack.org/pipermail/openstack-discuss/2019-February/003031.html
|
||||||
|
|
Loading…
Reference in New Issue