Add documentation for Auth Receipts and MFA
Adds API ref examples for TOTP and Auth receipts. Adds docs for MFA and changes some of the user options docs. Change-Id: Id5497064e580093e4a2c7d904670a58095833b3b
This commit is contained in:
parent
a011fb6789
commit
6564b40641
|
@ -10,7 +10,7 @@ optionally, grants authorization on a specific project, domain, or the
|
||||||
deployment system.
|
deployment system.
|
||||||
|
|
||||||
The body of an authentication request must include a payload that
|
The body of an authentication request must include a payload that
|
||||||
specifies the authentication method, which is ``password`` or
|
specifies the authentication methods, which are normally just ``password`` or
|
||||||
``token``, the credentials, and, optionally, the authorization
|
``token``, the credentials, and, optionally, the authorization
|
||||||
scope. You can scope a token to a project, domain, the deployment system, or
|
scope. You can scope a token to a project, domain, the deployment system, or
|
||||||
the token can be unscoped. You cannot scope a token to multiple scope targets.
|
the token can be unscoped. You cannot scope a token to multiple scope targets.
|
||||||
|
@ -18,6 +18,16 @@ the token can be unscoped. You cannot scope a token to multiple scope targets.
|
||||||
Tokens have IDs, which the Identity API returns in the
|
Tokens have IDs, which the Identity API returns in the
|
||||||
``X-Subject-Token`` response header.
|
``X-Subject-Token`` response header.
|
||||||
|
|
||||||
|
In the case of multi-factor authentication (MFA) more than one authentication
|
||||||
|
method needs to be supplied to authenticate. As of v3.12 a failure due to MFA
|
||||||
|
rules only partially being met will result in an auth receipt ID being returned
|
||||||
|
in the response header ``Openstack-Auth-Receipt``, and a response body that
|
||||||
|
details the receipt itself and the missing authentication methods. Supplying
|
||||||
|
the auth receipt ID in the ``Openstack-Auth-Receipt`` header in a follow-up
|
||||||
|
authentication request, with the missing authentication methods, will result in
|
||||||
|
a valid token by reusing the successful methods from the first request. This
|
||||||
|
allows MFA authentication to be a multi-step process.
|
||||||
|
|
||||||
After you obtain an authentication token, you can:
|
After you obtain an authentication token, you can:
|
||||||
|
|
||||||
- Make REST API requests to other OpenStack services. You supply the
|
- Make REST API requests to other OpenStack services. You supply the
|
||||||
|
@ -74,6 +84,10 @@ These authentication errors can occur:
|
||||||
| | - The specified ``X-Auth-Token`` header is not valid. |
|
| | - The specified ``X-Auth-Token`` header is not valid. |
|
||||||
| | |
|
| | |
|
||||||
| | - The authentication credentials are not valid. |
|
| | - The authentication credentials are not valid. |
|
||||||
|
| | |
|
||||||
|
| | - Not all MFA rules were satisfied. |
|
||||||
|
| | |
|
||||||
|
| | - The specified ``Openstack-Auth-Receipt`` header is not valid. |
|
||||||
+------------------------+----------------------------------------------------------------------+
|
+------------------------+----------------------------------------------------------------------+
|
||||||
| ``Forbidden (403)`` | The identity was successfully authenticated but it is not |
|
| ``Forbidden (403)`` | The identity was successfully authenticated but it is not |
|
||||||
| | authorized to perform the requested action. |
|
| | authorized to perform the requested action. |
|
||||||
|
@ -621,6 +635,168 @@ Example
|
||||||
:language: javascript
|
:language: javascript
|
||||||
|
|
||||||
|
|
||||||
|
Multi-Step authentication (2-Factor Password and TOTP example)
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
.. rest_method:: POST /v3/auth/tokens
|
||||||
|
|
||||||
|
Authenticates an identity and generates a token. Uses the password
|
||||||
|
authentication method, then the totp method, with an auth receipt in between.
|
||||||
|
|
||||||
|
This assumes that MFA has been enabled for the user, and a rule has been
|
||||||
|
defined requiring authentication with both password and totp.
|
||||||
|
|
||||||
|
The first request body must at least include a payload that specifies one of
|
||||||
|
``password`` or ``totp`` authentication methods which includes the credentials
|
||||||
|
in addition to an optional scope. If only one method is supplied then an auth
|
||||||
|
receipt will be returned. Scope is not retained in the receipt and must be
|
||||||
|
resupplied in subsequent requests.
|
||||||
|
|
||||||
|
While it is very possible to supply all the required auth methods at once, this
|
||||||
|
example shows the multi-step process which is likely to be more common.
|
||||||
|
|
||||||
|
More than 2 factors can be used but the same process applies to those as well;
|
||||||
|
either all auth methods are supplied at once, or in steps with one or more auth
|
||||||
|
receipts in between.
|
||||||
|
|
||||||
|
Relationship: ``https://docs.openstack.org/api/openstack-identity/3/rel/auth_tokens``
|
||||||
|
|
||||||
|
First Request
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
- nocatalog: nocatalog
|
||||||
|
- name: user_name
|
||||||
|
- auth: auth
|
||||||
|
- user: user
|
||||||
|
- scope: scope_string
|
||||||
|
- password: password
|
||||||
|
- id: user_id
|
||||||
|
- identity: identity
|
||||||
|
- methods: auth_methods_passwd
|
||||||
|
|
||||||
|
Example
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. literalinclude:: ./samples/auth/requests/project-id-password.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
|
Response
|
||||||
|
--------
|
||||||
|
|
||||||
|
Here we are expecting a 401 status, and a returned auth receipt.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
- Openstack-Auth-Receipt: Openstack-Auth-Receipt
|
||||||
|
- methods: auth_methods_receipt
|
||||||
|
- expires_at: receipt_expires_at
|
||||||
|
- issued_at: receipt_issued_at
|
||||||
|
- user: user
|
||||||
|
- required_auth_methods: required_auth_methods
|
||||||
|
|
||||||
|
Status Code
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_status_code:: success status.yaml
|
||||||
|
|
||||||
|
- 401: auth_receipt
|
||||||
|
|
||||||
|
.. rest_status_code:: error status.yaml
|
||||||
|
|
||||||
|
- 400
|
||||||
|
- 401: auth_failed
|
||||||
|
- 403
|
||||||
|
- 404
|
||||||
|
|
||||||
|
Auth Receipt Example
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. literalinclude:: ./samples/auth/responses/auth-receipt-password.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
|
Second Request
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
- Openstack-Auth-Receipt: Openstack-Auth-Receipt
|
||||||
|
- nocatalog: nocatalog
|
||||||
|
- name: user_name
|
||||||
|
- auth: auth
|
||||||
|
- user: user
|
||||||
|
- scope: scope_string
|
||||||
|
- totp: totp
|
||||||
|
- id: user_id
|
||||||
|
- identity: identity
|
||||||
|
- methods: auth_methods_totp
|
||||||
|
|
||||||
|
Example
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. literalinclude:: ./samples/auth/requests/project-id-totp.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
|
Response
|
||||||
|
--------
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
- X-Subject-Token: X-Subject-Token
|
||||||
|
- region_id: region_id_required
|
||||||
|
- methods: auth_methods_passwd
|
||||||
|
- roles: roles
|
||||||
|
- url: endpoint_url
|
||||||
|
- region: endpoint_region
|
||||||
|
- token: token
|
||||||
|
- expires_at: expires_at
|
||||||
|
- system: system_scope_response_body_optional
|
||||||
|
- domain: domain_scope_response_body_optional
|
||||||
|
- project: project_scope_response_body_optional
|
||||||
|
- issued_at: issued_at
|
||||||
|
- catalog: catalog
|
||||||
|
- user: user
|
||||||
|
- audit_ids: audit_ids
|
||||||
|
- interface: endpoint_interface
|
||||||
|
- endpoints: endpoints
|
||||||
|
- type: endpoint_type
|
||||||
|
- id: user_id
|
||||||
|
- name: user_name
|
||||||
|
|
||||||
|
Status Codes
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rest_status_code:: success status.yaml
|
||||||
|
|
||||||
|
- 201
|
||||||
|
|
||||||
|
.. rest_status_code:: error status.yaml
|
||||||
|
|
||||||
|
- 400
|
||||||
|
- 401: auth_receipt_failure
|
||||||
|
- 403
|
||||||
|
- 404
|
||||||
|
|
||||||
|
Project-Scoped Password and TOTP Example
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. literalinclude:: ./samples/auth/responses/project-scoped-password-totp.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
|
|
||||||
Validate and show information for token
|
Validate and show information for token
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
# variables in header
|
# variables in header
|
||||||
|
Openstack-Auth-Receipt:
|
||||||
|
description: |
|
||||||
|
The auth receipt. A partially successful authentication
|
||||||
|
response returns the auth receipt ID in this header rather than in the
|
||||||
|
response body.
|
||||||
|
in: header
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
X-Auth-Token:
|
X-Auth-Token:
|
||||||
description: |
|
description: |
|
||||||
A valid authentication token for an
|
A valid authentication token for an
|
||||||
|
@ -477,8 +485,8 @@ auth_domain:
|
||||||
type: object
|
type: object
|
||||||
auth_methods:
|
auth_methods:
|
||||||
description: |
|
description: |
|
||||||
The authentication method, which is ``password``,
|
The authentication methods, which are commonly ``password``,
|
||||||
``token``, or both methods. Indicates the accumulated set of
|
``token``, or other methods. Indicates the accumulated set of
|
||||||
authentication methods that were used to obtain the token. For
|
authentication methods that were used to obtain the token. For
|
||||||
example, if the token was obtained by password authentication, it
|
example, if the token was obtained by password authentication, it
|
||||||
contains ``password``. Later, if the token is exchanged by using
|
contains ``password``. Later, if the token is exchanged by using
|
||||||
|
@ -506,6 +514,19 @@ auth_methods_passwd:
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: array
|
type: array
|
||||||
|
auth_methods_receipt:
|
||||||
|
description: |
|
||||||
|
The authentication methods, which are commonly ``password``,
|
||||||
|
``totp``, or other methods. Indicates the accumulated set of
|
||||||
|
authentication methods that were used to obtain the receipt. For
|
||||||
|
example, if the receipt was obtained by password authentication, it
|
||||||
|
contains ``password``. Later, if the receipt is exchanged by using
|
||||||
|
another authentication method one or more times, the
|
||||||
|
subsequently created receipts could contain both ``password`` and
|
||||||
|
``totp`` in their ``methods`` attribute.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
auth_methods_token:
|
auth_methods_token:
|
||||||
description: |
|
description: |
|
||||||
The authentication method. For token
|
The authentication method. For token
|
||||||
|
@ -513,6 +534,13 @@ auth_methods_token:
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: array
|
type: array
|
||||||
|
auth_methods_totp:
|
||||||
|
description: |
|
||||||
|
The authentication method. For totp
|
||||||
|
authentication, specify ``totp``.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
auth_token:
|
auth_token:
|
||||||
description: |
|
description: |
|
||||||
A ``token`` object. The token authentication
|
A ``token`` object. The token authentication
|
||||||
|
@ -1433,6 +1461,38 @@ projects:
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: array
|
type: array
|
||||||
|
receipt_expires_at:
|
||||||
|
description: |
|
||||||
|
The date and time when the receipt expires.
|
||||||
|
|
||||||
|
The date and time stamp format is `ISO 8601
|
||||||
|
<https://en.wikipedia.org/wiki/ISO_8601>`_:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
CCYY-MM-DDThh:mm:ss.sssZ
|
||||||
|
|
||||||
|
For example, ``2015-08-27T09:49:58.000000Z``.
|
||||||
|
|
||||||
|
A ``null`` value indicates that the receipt never expires.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
receipt_issued_at:
|
||||||
|
description: |
|
||||||
|
The date and time when the receipt was issued.
|
||||||
|
|
||||||
|
The date and time stamp format is `ISO 8601
|
||||||
|
<https://en.wikipedia.org/wiki/ISO_8601>`_:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
CCYY-MM-DDThh:mm:ss.sssZ
|
||||||
|
|
||||||
|
For example, ``2015-08-27T09:49:58.000000Z``.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
region_id_not_required:
|
region_id_not_required:
|
||||||
description: |
|
description: |
|
||||||
(Since v3.2) The ID of the region that contains
|
(Since v3.2) The ID of the region that contains
|
||||||
|
@ -1604,6 +1664,13 @@ request_service_id_registered_limit_body_not_required:
|
||||||
in: body
|
in: body
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
required_auth_methods:
|
||||||
|
description: |
|
||||||
|
A list of authentication rules that may be used with the auth receipt
|
||||||
|
to complete the authentication process.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: list of lists
|
||||||
resource_limit:
|
resource_limit:
|
||||||
description: |
|
description: |
|
||||||
The override limit.
|
The override limit.
|
||||||
|
@ -1909,6 +1976,12 @@ token:
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: object
|
type: object
|
||||||
|
totp:
|
||||||
|
description: |
|
||||||
|
The ``totp`` object, contains the authentication information.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: object
|
||||||
user:
|
user:
|
||||||
description: |
|
description: |
|
||||||
A ``user`` object.
|
A ``user`` object.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"identity": {
|
||||||
|
"methods": [
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"totp": {
|
||||||
|
"user": {
|
||||||
|
"id": "ee4dfb6e5540447cb3741905149d9b6e",
|
||||||
|
"passcode": "123456"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"project": {
|
||||||
|
"id": "a6944d763bf64ee6a275f1263fae0352"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"receipt":{
|
||||||
|
"expires_at":"2018-07-05T08:39:23.000000Z",
|
||||||
|
"issued_at":"2018-07-05T08:34:23.000000Z",
|
||||||
|
"methods": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"user": {
|
||||||
|
"domain": {
|
||||||
|
"id": "default",
|
||||||
|
"name": "Default"
|
||||||
|
},
|
||||||
|
"id": "ee4dfb6e5540447cb3741905149d9b6e",
|
||||||
|
"name": "admin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required_auth_methods": [
|
||||||
|
["totp", "password"]
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"token": {
|
||||||
|
"audit_ids": [
|
||||||
|
"3T2dc1CGQxyJsHdDu1xkcw"
|
||||||
|
],
|
||||||
|
"catalog": [
|
||||||
|
{
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"id": "068d1b359ee84b438266cb736d81de97",
|
||||||
|
"interface": "public",
|
||||||
|
"region": "RegionOne",
|
||||||
|
"region_id": "RegionOne",
|
||||||
|
"url": "http://example.com/identity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8bfc846841ab441ca38471be6d164ced",
|
||||||
|
"interface": "admin",
|
||||||
|
"region": "RegionOne",
|
||||||
|
"region_id": "RegionOne",
|
||||||
|
"url": "http://example.com/identity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "beb6d358c3654b4bada04d4663b640b9",
|
||||||
|
"interface": "internal",
|
||||||
|
"region": "RegionOne",
|
||||||
|
"region_id": "RegionOne",
|
||||||
|
"url": "http://example.com/identity"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "identity",
|
||||||
|
"id": "050726f278654128aba89757ae25950c",
|
||||||
|
"name": "keystone"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expires_at": "2015-11-07T02:58:43.578887Z",
|
||||||
|
"is_domain": false,
|
||||||
|
"issued_at": "2015-11-07T01:58:43.578929Z",
|
||||||
|
"methods": [
|
||||||
|
"password",
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"project": {
|
||||||
|
"domain": {
|
||||||
|
"id": "default",
|
||||||
|
"name": "Default"
|
||||||
|
},
|
||||||
|
"id": "a6944d763bf64ee6a275f1263fae0352",
|
||||||
|
"name": "admin"
|
||||||
|
},
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"id": "51cc68287d524c759f47c811e6463340",
|
||||||
|
"name": "admin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"user": {
|
||||||
|
"domain": {
|
||||||
|
"id": "default",
|
||||||
|
"name": "Default"
|
||||||
|
},
|
||||||
|
"id": "ee4dfb6e5540447cb3741905149d9b6e",
|
||||||
|
"name": "admin",
|
||||||
|
"password_expires_at": "2016-11-06T15:32:17.000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,14 @@
|
||||||
401:
|
401:
|
||||||
default: |
|
default: |
|
||||||
User must authenticate before making a request.
|
User must authenticate before making a request.
|
||||||
|
auth_failed: |
|
||||||
|
Authentication attempt has failed.
|
||||||
|
auth_receipt: |
|
||||||
|
User has successfully supplied some auth methods, but not enough for full
|
||||||
|
authentication.
|
||||||
|
auth_receipt_failure: |
|
||||||
|
Authentication attempt has failed. Either the auth receipt has expired, or
|
||||||
|
the additional auth methods supplied were invalid.
|
||||||
403:
|
403:
|
||||||
default: |
|
default: |
|
||||||
Policy does not allow current user to do this operation.
|
Policy does not allow current user to do this operation.
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
License for the specific language governing permissions and limitations
|
License for the specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
|
|
||||||
|
.. _auth_totp:
|
||||||
|
|
||||||
===================================
|
===================================
|
||||||
Time-based One-time Password (TOTP)
|
Time-based One-time Password (TOTP)
|
||||||
===================================
|
===================================
|
||||||
|
|
|
@ -8,6 +8,7 @@ user and password method.
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
multi-factor-authentication
|
||||||
auth-totp
|
auth-totp
|
||||||
federation/federated_identity
|
federation/federated_identity
|
||||||
external-authentication
|
external-authentication
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
.. _multi_factor_authentication:
|
||||||
|
|
||||||
|
===========================
|
||||||
|
Multi-Factor Authentication
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Configuring MFA
|
||||||
|
===============
|
||||||
|
|
||||||
|
MFA is configured on a per user basis via the user options
|
||||||
|
:ref:`multi_factor_auth_rules` and :ref:`multi_factor_auth_enabled`. Until
|
||||||
|
these are set the user can authenticate with any one of the enabled auth
|
||||||
|
methods.
|
||||||
|
|
||||||
|
MFA rules
|
||||||
|
---------
|
||||||
|
|
||||||
|
The MFA rules allow an admin to force a user to use specific forms of
|
||||||
|
authentication or combinations of forms of authentication to get a token.
|
||||||
|
|
||||||
|
The rules are specified as follows via the user option
|
||||||
|
:ref:`multi_factor_auth_rules`::
|
||||||
|
|
||||||
|
[["password", "totp"], ["password", "custom-auth-method"]]
|
||||||
|
|
||||||
|
They are a list of lists. The elements of the sub-lists must be strings and are
|
||||||
|
intended to mirror the required authentication method names (e.g. ``password``,
|
||||||
|
``totp``, etc) as defined in the ``keystone.conf`` file in the
|
||||||
|
``[auth] methods`` option. Each list of methods specifies a rule.
|
||||||
|
|
||||||
|
If the auth methods provided by a user match (or exceed) the auth methods in
|
||||||
|
the list, that rule is used. The first rule found (rules will not be processed
|
||||||
|
in a specific order) that matches will be used. If a user has the ruleset
|
||||||
|
defined as ``[["password", "totp"]]`` the user must provide both password and
|
||||||
|
totp auth methods (and both methods must succeed) to receive a token. However,
|
||||||
|
if a user has a ruleset defined as ``[["password"], ["password", "totp"]]``
|
||||||
|
the user may use the ``password`` method on it's own but would be required
|
||||||
|
to use both ``password`` and ``totp`` if ``totp`` is specified at all.
|
||||||
|
|
||||||
|
Any auth methods that are not defined in ``keystone.conf`` in the
|
||||||
|
``[auth] methods`` option are ignored when the rules are processed. Empty
|
||||||
|
rules are not allowed. If a rule is empty due to no-valid auth methods
|
||||||
|
existing within it, the rule is discarded at authentication time. If there
|
||||||
|
are no rules or no valid rules for the user, authentication occurs in the
|
||||||
|
default manner: any single configured auth method is sufficient to receive
|
||||||
|
a token.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The ``token`` auth method typically should not be specified in any MFA
|
||||||
|
Rules. The ``token`` auth method will include all previous auth methods
|
||||||
|
for the original auth request and will match the appropriate ruleset. This
|
||||||
|
is intentional, as the ``token`` method is used for rescoping/changing
|
||||||
|
active projects.
|
||||||
|
|
||||||
|
Enabling MFA
|
||||||
|
------------
|
||||||
|
|
||||||
|
Before the MFA rules take effect on a user, MFA has to be enabled for that user
|
||||||
|
via the user option :ref:`multi_factor_auth_enabled`. By default this is unset,
|
||||||
|
and the rules will not take effect until configured.
|
||||||
|
|
||||||
|
In the case a user should be exempt from MFA Rules, regardless if they are
|
||||||
|
set, the User-Option may be set to ``False``.
|
||||||
|
|
||||||
|
Using MFA
|
||||||
|
=========
|
||||||
|
|
||||||
|
See :ref:`multi_factor_authentication_user_guide` in the user guide for some
|
||||||
|
examples.
|
||||||
|
|
||||||
|
|
||||||
|
Supported multi-factor authentication methods
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
TOTP is the only suggested second factor along with password for now, but there
|
||||||
|
are plans to include more in future.
|
||||||
|
|
||||||
|
TOTP
|
||||||
|
----
|
||||||
|
|
||||||
|
This is a simple 6 digit passcode generated by both the server and client from
|
||||||
|
a known shared secret.
|
||||||
|
|
||||||
|
This used in a multi-step fashion is the most common 2-factor method used these
|
||||||
|
days.
|
||||||
|
|
||||||
|
See: :ref:`auth_totp`
|
|
@ -22,6 +22,28 @@ User Options
|
||||||
The following options are available on user resources. If left undefined, they
|
The following options are available on user resources. If left undefined, they
|
||||||
are assumed to be false or disabled.
|
are assumed to be false or disabled.
|
||||||
|
|
||||||
|
These can be set either in the initial user creation (``POST /v3/users``)
|
||||||
|
or by updating an existing user to include new options
|
||||||
|
(``PATCH /v3/users/{user_id}``):
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"ignore_lockout_failure_attempts": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
User options of the ``Boolean`` type can be set to ``True``, ``False``, or
|
||||||
|
``None``; if the option is set to ``None``, it is removed from the user's
|
||||||
|
data structure.
|
||||||
|
|
||||||
|
.. _ignore_change_password_upon_first_use:
|
||||||
|
|
||||||
ignore_change_password_upon_first_use
|
ignore_change_password_upon_first_use
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
@ -32,9 +54,21 @@ they log into keystone for the first time. This can be useful for deployments
|
||||||
that auto-generate passwords but want to ensure a user picks a new password
|
that auto-generate passwords but want to ensure a user picks a new password
|
||||||
when they start using the deployment.
|
when they start using the deployment.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"ignore_change_password_upon_first_use": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
See the `security compliance documentation
|
See the `security compliance documentation
|
||||||
<security-compliance.html>`_ for more details.
|
<security-compliance.html>`_ for more details.
|
||||||
|
|
||||||
|
.. _ignore_password_expiry:
|
||||||
|
|
||||||
ignore_password_expiry
|
ignore_password_expiry
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
@ -45,9 +79,21 @@ Opt into ignoring global password expiration settings defined in
|
||||||
option to ``True`` will allow users to continue using passwords that may be
|
option to ``True`` will allow users to continue using passwords that may be
|
||||||
expired according to global configuration values.
|
expired according to global configuration values.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"ignore_password_expiry": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
See the `security compliance documentation
|
See the `security compliance documentation
|
||||||
<security-compliance.html>`_ for more details.
|
<security-compliance.html>`_ for more details.
|
||||||
|
|
||||||
|
.. _ignore_lockout_failure_attempts:
|
||||||
|
|
||||||
ignore_lockout_failure_attempts
|
ignore_lockout_failure_attempts
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -56,9 +102,21 @@ Type: ``Boolean``
|
||||||
If ``True``, opt into ignoring the number of times a user has authenticated and
|
If ``True``, opt into ignoring the number of times a user has authenticated and
|
||||||
locking out the user as a result.
|
locking out the user as a result.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"ignore_lockout_failure_attempts": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
See the `security compliance documentation
|
See the `security compliance documentation
|
||||||
<security-compliance.html>`_ for more details.
|
<security-compliance.html>`_ for more details.
|
||||||
|
|
||||||
|
.. _lock_password:
|
||||||
|
|
||||||
lock_password
|
lock_password
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -67,9 +125,22 @@ Type: ``Boolean``
|
||||||
If set to ``True``, this option disables the ability for users to change their
|
If set to ``True``, this option disables the ability for users to change their
|
||||||
password through self-service APIs.
|
password through self-service APIs.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"lock_password": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
See the `security compliance documentation
|
See the `security compliance documentation
|
||||||
<security-compliance.html>`_ for more details.
|
<security-compliance.html>`_ for more details.
|
||||||
|
|
||||||
|
.. _multi_factor_auth_enabled:
|
||||||
|
|
||||||
multi_factor_auth_enabled
|
multi_factor_auth_enabled
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
@ -80,6 +151,20 @@ This will result in different behavior at authentication time and the user may
|
||||||
be presented with different authentication requirements based on multi-factor
|
be presented with different authentication requirements based on multi-factor
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"multi_factor_auth_enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
See :ref:`multi_factor_authentication` for further details.
|
||||||
|
|
||||||
|
.. _multi_factor_auth_rules:
|
||||||
|
|
||||||
multi_factor_auth_rules
|
multi_factor_auth_rules
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
@ -87,3 +172,19 @@ Type: ``List of Lists of Strings``
|
||||||
|
|
||||||
Define a list of strings that represent the methods required for a user to
|
Define a list of strings that represent the methods required for a user to
|
||||||
authenticate.
|
authenticate.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"multi_factor_auth_rules": [
|
||||||
|
["password", "totp"],
|
||||||
|
["password", "u2f"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
See :ref:`multi_factor_authentication` for further details.
|
||||||
|
|
|
@ -42,18 +42,7 @@ indefinitely until the user is explicitly enabled via the API.
|
||||||
|
|
||||||
You can ensure specific users are never locked out. This can be useful for
|
You can ensure specific users are never locked out. This can be useful for
|
||||||
service accounts or administrative users. You can do this by setting
|
service accounts or administrative users. You can do this by setting
|
||||||
``ignore_lockout_failure_attempts`` to ``true`` via a user update API
|
the user option for :ref:`ignore_lockout_failure_attempts`.
|
||||||
(``PATCH /v3/users/{user_id}``):
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"user": {
|
|
||||||
"options": {
|
|
||||||
"ignore_lockout_failure_attempts": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Disabling inactive users
|
Disabling inactive users
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -85,18 +74,7 @@ authentication (first use), before being able to access any services.
|
||||||
Prior to enabling this feature, you may want to exempt some users that you do
|
Prior to enabling this feature, you may want to exempt some users that you do
|
||||||
not wish to be required to change their password. You can mark a user as
|
not wish to be required to change their password. You can mark a user as
|
||||||
exempt by setting the user options attribute
|
exempt by setting the user options attribute
|
||||||
``ignore_change_password_upon_first_use`` to ``true`` via a user update API
|
:ref:`ignore_change_password_upon_first_use`.
|
||||||
(``PATCH /v3/users/{user_id}``):
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"user": {
|
|
||||||
"options": {
|
|
||||||
"ignore_change_password_upon_first_use": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. WARNING::
|
.. WARNING::
|
||||||
|
|
||||||
|
@ -131,18 +109,7 @@ expiration date, you would need to run a SQL script against the password table
|
||||||
in the database to update the expires_at column.
|
in the database to update the expires_at column.
|
||||||
|
|
||||||
If there exists a user whose password you do not want to expire, keystone
|
If there exists a user whose password you do not want to expire, keystone
|
||||||
supports setting that user's option ``ignore_password_expiry`` to ``true``
|
supports setting that via the user option :ref:`ignore_password_expiry`.
|
||||||
via user update API (``PATCH /v3/users/{user_id}``):
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"user": {
|
|
||||||
"options": {
|
|
||||||
"ignore_password_expiry": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuring password strength requirements
|
Configuring password strength requirements
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
@ -225,24 +192,11 @@ Prevent Self-Service Password Changes
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
If there exists a user who should not be able to change her own password via
|
If there exists a user who should not be able to change her own password via
|
||||||
the keystone password change API, keystone supports setting that user's option
|
the keystone password change API, keystone supports setting that via the user
|
||||||
``lock_password`` to ``True`` via the user update API
|
option :ref:`lock_password`.
|
||||||
(``PATCH /v3/users/{user_id}``):
|
|
||||||
|
|
||||||
.. code-block:: json
|
This is typically used in the case where passwords are managed externally to
|
||||||
|
keystone.
|
||||||
{
|
|
||||||
"user": {
|
|
||||||
"options": {
|
|
||||||
"lock_password": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The ``lock_password`` user-option is typically used in the case where passwords
|
|
||||||
are managed externally to keystone. The ``lock_password`` option can be set to
|
|
||||||
``True``, ``False``, or ``None``; if the option is set to ``None``, it is
|
|
||||||
removed from the user's data structure.
|
|
||||||
|
|
||||||
.. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html
|
.. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html
|
||||||
|
|
||||||
|
|
|
@ -30,3 +30,4 @@ An end user can find the specific API documentation here, `OpenStack's Identity
|
||||||
trusts.rst
|
trusts.rst
|
||||||
json_home.rst
|
json_home.rst
|
||||||
../api_curl_examples.rst
|
../api_curl_examples.rst
|
||||||
|
multi-factor-authentication.rst
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
.. _multi_factor_authentication_user_guide:
|
||||||
|
|
||||||
|
===========================
|
||||||
|
Multi-Factor Authentication
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Configuring MFA
|
||||||
|
===============
|
||||||
|
|
||||||
|
Configuring MFA right now has to be done entirely by an admin, for how to do
|
||||||
|
that, see :ref:`multi_factor_authentication`.
|
||||||
|
|
||||||
|
Using MFA
|
||||||
|
=========
|
||||||
|
|
||||||
|
Multi-Factor Authentication with Keystone can be used in two ways, either you
|
||||||
|
treat it like current single method authentication and provide all the details
|
||||||
|
upfront, or you doing it as a multi-step process with auth receipts.
|
||||||
|
|
||||||
|
Single step
|
||||||
|
-----------
|
||||||
|
|
||||||
|
In the single step approach you would supply all the required authentication
|
||||||
|
methods in your request for a token.
|
||||||
|
|
||||||
|
Here is an example using 2 factors (``password`` and ``totp``):
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{ "auth": {
|
||||||
|
"identity": {
|
||||||
|
"methods": [
|
||||||
|
"password",
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"totp": {
|
||||||
|
"user": {
|
||||||
|
"id": "2ed179c6af12496cafa1d279cb51a78f",
|
||||||
|
"passcode": "012345"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"user": {
|
||||||
|
"id": "2ed179c6af12496cafa1d279cb51a78f",
|
||||||
|
"password": "super sekret pa55word"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
If all the supplied auth methods are valid, Keystone will return a token.
|
||||||
|
|
||||||
|
Multi-Step
|
||||||
|
----------
|
||||||
|
|
||||||
|
In the multi-step approach you can supply any one method from the auth rules:
|
||||||
|
|
||||||
|
Again we do a 2 factor example, starting with ``password``:
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{ "auth": {
|
||||||
|
"identity": {
|
||||||
|
"methods": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"password": {
|
||||||
|
"user": {
|
||||||
|
"id": "2ed179c6af12496cafa1d279cb51a78f",
|
||||||
|
"password": "super sekret pa55word"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Provided the method is valid, Keystone will still return a ``401``, but will in
|
||||||
|
the response header ``Openstack-Auth-Receipt`` return a receipt of valid auth
|
||||||
|
method for reuse later.
|
||||||
|
|
||||||
|
The response body will also contain information about the auth receipt, and
|
||||||
|
what auth methods may be missing:
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"receipt":{
|
||||||
|
"expires_at":"2018-07-05T08:39:23.000000Z",
|
||||||
|
"issued_at":"2018-07-05T08:34:23.000000Z",
|
||||||
|
"methods": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"user": {
|
||||||
|
"domain": {
|
||||||
|
"id": "default",
|
||||||
|
"name": "Default"
|
||||||
|
},
|
||||||
|
"id": "ee4dfb6e5540447cb3741905149d9b6e",
|
||||||
|
"name": "admin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required_auth_methods": [
|
||||||
|
["totp", "password"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Now you can continue authenticating by supplying the missing auth methods, and
|
||||||
|
supplying the header ``Openstack-Auth-Receipt`` as gotten from the previous
|
||||||
|
response:
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{ "auth": {
|
||||||
|
"identity": {
|
||||||
|
"methods": [
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"totp": {
|
||||||
|
"user": {
|
||||||
|
"id": "2ed179c6af12496cafa1d279cb51a78f",
|
||||||
|
"passcode": "012345"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Provided the auth methods are valid, Keystone will now supply a token. If not
|
||||||
|
you can try again until the auth receipt expires (e.g in case of TOTP timeout).
|
Loading…
Reference in New Issue