diff --git a/doc/source/admin/identity-auth-token-middleware.rst b/doc/source/admin/identity-auth-token-middleware.rst
new file mode 100644
index 0000000000..291d4f777b
--- /dev/null
+++ b/doc/source/admin/identity-auth-token-middleware.rst
@@ -0,0 +1,74 @@
+Authentication middleware with user name and password
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also configure Identity authentication middleware using the
+``admin_user`` and ``admin_password`` options.
+
+.. note::
+
+ The ``admin_token`` option is deprecated and no longer used for
+ configuring auth_token middleware.
+
+For services that have a separate paste-deploy ``.ini`` file, you can
+configure the authentication middleware in the ``[keystone_authtoken]``
+section of the main configuration file, such as ``nova.conf``. In
+Compute, for example, you can remove the middleware parameters from
+``api-paste.ini``, as follows:
+
+.. code-block:: ini
+
+ [filter:authtoken]
+ paste.filter_factory = keystonemiddleware.auth_token:filter_factory
+
+
+And set the following values in ``nova.conf`` as follows:
+
+.. code-block:: ini
+
+ [DEFAULT]
+ # ...
+ auth_strategy=keystone
+
+ [keystone_authtoken]
+ auth_uri = http://controller:5000/v2.0
+ identity_uri = http://controller:35357
+ admin_user = admin
+ admin_password = SuperSekretPassword
+ admin_tenant_name = service
+
+.. note::
+
+ The middleware parameters in the paste config take priority. You
+ must remove them to use the values in the ``[keystone_authtoken]``
+ section.
+
+.. note::
+
+ Comment out any ``auth_host``, ``auth_port``, and
+ ``auth_protocol`` options because the ``identity_uri`` option
+ replaces them.
+
+This sample paste config filter makes use of the ``admin_user`` and
+``admin_password`` options:
+
+.. code-block:: ini
+
+ [filter:authtoken]
+ paste.filter_factory = keystonemiddleware.auth_token:filter_factory
+ auth_uri = http://controller:5000/v2.0
+ identity_uri = http://controller:35357
+ auth_token = 012345SECRET99TOKEN012345
+ admin_user = admin
+ admin_password = keystone123
+
+.. note::
+
+ Using this option requires an admin project/role relationship. The
+ admin user is granted access to the admin role on the admin project.
+
+.. note::
+
+ Comment out any ``auth_host``, ``auth_port``, and
+ ``auth_protocol`` options because the ``identity_uri`` option
+ replaces them.
+
diff --git a/doc/source/admin/identity-caching-layer.rst b/doc/source/admin/identity-caching-layer.rst
new file mode 100644
index 0000000000..7fb62b1c19
--- /dev/null
+++ b/doc/source/admin/identity-caching-layer.rst
@@ -0,0 +1,128 @@
+.. :orphan:
+
+Caching layer
+~~~~~~~~~~~~~
+
+OpenStack Identity supports a caching layer that is above the
+configurable subsystems (for example, token). OpenStack Identity uses the
+`oslo.cache `__
+library which allows flexible cache back ends. The majority of the
+caching configuration options are set in the ``[cache]`` section of the
+``/etc/keystone/keystone.conf`` file. However, each section that has
+the capability to be cached usually has a caching boolean value that
+toggles caching.
+
+So to enable only the token back end caching, set the values as follows:
+
+.. code-block:: ini
+
+ [cache]
+ enabled=true
+
+ [catalog]
+ caching=false
+
+ [domain_config]
+ caching=false
+
+ [federation]
+ caching=false
+
+ [resource]
+ caching=false
+
+ [revoke]
+ caching=false
+
+ [role]
+ caching=false
+
+ [token]
+ caching=true
+
+.. note::
+
+ Since the Newton release, the default setting is enabled for subsystem
+ caching and the global toggle. As a result, all subsystems that support
+ caching are doing this by default.
+
+Caching for tokens and tokens validation
+----------------------------------------
+
+All types of tokens benefit from caching, including Fernet tokens. Although
+Fernet tokens do not need to be persisted, they should still be cached for
+optimal token validation performance.
+
+The token system has a separate ``cache_time`` configuration option,
+that can be set to a value above or below the global ``expiration_time``
+default, allowing for different caching behavior from the other systems
+in OpenStack Identity. This option is set in the ``[token]`` section of
+the configuration file.
+
+The token revocation list cache time is handled by the configuration
+option ``revocation_cache_time`` in the ``[token]`` section. The
+revocation list is refreshed whenever a token is revoked. It typically
+sees significantly more requests than specific token retrievals or token
+validation calls.
+
+Here is a list of actions that are affected by the cached time: getting
+a new token, revoking tokens, validating tokens, checking v2 tokens, and
+checking v3 tokens.
+
+The delete token API calls invalidate the cache for the tokens being
+acted upon, as well as invalidating the cache for the revoked token list
+and the validate/check token calls.
+
+Token caching is configurable independently of the ``revocation_list``
+caching. Lifted expiration checks from the token drivers to the token
+manager. This ensures that cached tokens will still raise a
+``TokenNotFound`` flag when expired.
+
+For cache consistency, all token IDs are transformed into the short
+token hash at the provider and token driver level. Some methods have
+access to the full ID (PKI Tokens), and some methods do not. Cache
+invalidation is inconsistent without token ID normalization.
+
+Caching for non-token resources
+-------------------------------
+
+Various other keystone components have a separate ``cache_time`` configuration
+option, that can be set to a value above or below the global
+``expiration_time`` default, allowing for different caching behavior
+from the other systems in Identity service. This option can be set in various
+sections (for example, ``[role]`` and ``[resource]``) of the configuration
+file.
+The create, update, and delete actions for domains, projects and roles
+will perform proper invalidations of the cached methods listed above.
+
+For more information about the different back ends (and configuration
+options), see:
+
+- `dogpile.cache.memory `__
+
+- `dogpile.cache.memcached `__
+
+ .. note::
+
+ The memory back end is not suitable for use in a production
+ environment.
+
+- `dogpile.cache.redis `__
+
+- `dogpile.cache.dbm `__
+
+Configure the Memcached back end example
+----------------------------------------
+
+The following example shows how to configure the memcached back end:
+
+.. code-block:: ini
+
+ [cache]
+
+ enabled = true
+ backend = dogpile.cache.memcached
+ backend_argument = url:127.0.0.1:11211
+
+You need to specify the URL to reach the ``memcached`` instance with the
+``backend_argument`` parameter.
diff --git a/doc/source/admin/identity-certificates-for-pki.rst b/doc/source/admin/identity-certificates-for-pki.rst
new file mode 100644
index 0000000000..2c518cc63e
--- /dev/null
+++ b/doc/source/admin/identity-certificates-for-pki.rst
@@ -0,0 +1,237 @@
+====================
+Certificates for PKI
+====================
+
+PKI stands for Public Key Infrastructure. Tokens are documents,
+cryptographically signed using the X509 standard. In order to work
+correctly token generation requires a public/private key pair. The
+public key must be signed in an X509 certificate, and the certificate
+used to sign it must be available as a Certificate Authority (CA)
+certificate. These files can be generated either using the
+:command:`keystone-manage` utility, or externally generated. The files need to
+be in the locations specified by the top level Identity service
+configuration file ``/etc/keystone/keystone.conf`` as specified in the
+above section. Additionally, the private key should only be readable by
+the system user that will run the Identity service.
+
+
+.. warning::
+
+ The certificates can be world readable, but the private key cannot
+ be. The private key should only be readable by the account that is
+ going to sign tokens. When generating files with the
+ :command:`keystone-manage pki_setup` command, your best option is to run
+ as the pki user. If you run :command:`keystone-manage` as root, you can
+ append ``--keystone-user`` and ``--keystone-group`` parameters
+ to set the user name and group keystone is going to run under.
+
+The values that specify where to read the certificates are under the
+``[signing]`` section of the configuration file. The configuration
+values are:
+
+- ``certfile``
+ Location of certificate used to verify tokens. Default is
+ ``/etc/keystone/ssl/certs/signing_cert.pem``.
+
+- ``keyfile``
+ Location of private key used to sign tokens. Default is
+ ``/etc/keystone/ssl/private/signing_key.pem``.
+
+- ``ca_certs``
+ Location of certificate for the authority that issued
+ the above certificate. Default is
+ ``/etc/keystone/ssl/certs/ca.pem``.
+
+- ``ca_key``
+ Location of the private key used by the CA. Default is
+ ``/etc/keystone/ssl/private/cakey.pem``.
+
+- ``key_size``
+ Default is ``2048``.
+
+- ``valid_days``
+ Default is ``3650``.
+
+- ``cert_subject``
+ Certificate subject (auto generated certificate) for token signing.
+ Default is ``/C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com``.
+
+When generating certificates with the :command:`keystone-manage pki_setup`
+command, the ``ca_key``, ``key_size``, and ``valid_days`` configuration
+options are used.
+
+If the :command:`keystone-manage pki_setup` command is not used to generate
+certificates, or you are providing your own certificates, these values
+do not need to be set.
+
+If ``provider=keystone.token.providers.uuid.Provider`` in the
+``[token]`` section of the keystone configuration file, a typical token
+looks like ``53f7f6ef0cc344b5be706bcc8b1479e1``. If
+``provider=keystone.token.providers.pki.Provider``, a typical token is a
+much longer string, such as::
+
+ MIIKtgYJKoZIhvcNAQcCoIIKpzCCCqMCAQExCTAHBgUrDgMCGjCCCY8GCSqGSIb3DQEHAaCCCYAEggl8eyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxMy0wNS0z
+ MFQxNTo1MjowNi43MzMxOTgiLCAiZXhwaXJlcyI6ICIyMDEzLTA1LTMxVDE1OjUyOjA2WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogbnVs
+ bCwgImVuYWJsZWQiOiB0cnVlLCAiaWQiOiAiYzJjNTliNGQzZDI4NGQ4ZmEwOWYxNjljYjE4MDBlMDYiLCAibmFtZSI6ICJkZW1vIn19LCAic2VydmljZUNhdGFsb2ciOiBbeyJlbmRw
+ b2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTkyLjE2OC4yNy4xMDA6ODc3NC92Mi9jMmM1OWI0ZDNkMjg0ZDhmYTA5ZjE2OWNiMTgwMGUwNiIsICJyZWdpb24iOiAiUmVnaW9u
+ T25lIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDo4Nzc0L3YyL2MyYzU5YjRkM2QyODRkOGZhMDlmMTY5Y2IxODAwZTA2IiwgImlkIjogIjFmYjMzYmM5M2Y5
+ ODRhNGNhZTk3MmViNzcwOTgzZTJlIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yNy4xMDA6ODc3NC92Mi9jMmM1OWI0ZDNkMjg0ZDhmYTA5ZjE2OWNiMTgwMGUwNiJ9XSwg
+ ImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAibm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3
+ LjEwMDozMzMzIiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE5Mi4xNjguMjcuMTAwOjMzMzMiLCAiaWQiOiAiN2JjMThjYzk1NWFiNDNkYjhm
+ MGU2YWNlNDU4NjZmMzAiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDozMzMzIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogInMzIiwgIm5hbWUi
+ OiAiczMifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTkyLjE2OC4yNy4xMDA6OTI5MiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVybmFsVVJMIjog
+ Imh0dHA6Ly8xOTIuMTY4LjI3LjEwMDo5MjkyIiwgImlkIjogIjczODQzNTJhNTQ0MjQ1NzVhM2NkOTVkN2E0YzNjZGY1IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4yNy4x
+ MDA6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6
+ Ly8xOTIuMTY4LjI3LjEwMDo4Nzc2L3YxL2MyYzU5YjRkM2QyODRkOGZhMDlmMTY5Y2IxODAwZTA2IiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDov
+ LzE5Mi4xNjguMjcuMTAwOjg3NzYvdjEvYzJjNTliNGQzZDI4NGQ4ZmEwOWYxNjljYjE4MDBlMDYiLCAiaWQiOiAiMzQ3ZWQ2ZThjMjkxNGU1MGFlMmJiNjA2YWQxNDdjNTQiLCAicHVi
+ bGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDo4Nzc2L3YxL2MyYzU5YjRkM2QyODRkOGZhMDlmMTY5Y2IxODAwZTA2In1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBl
+ IjogInZvbHVtZSIsICJuYW1lIjogImNpbmRlciJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDo4NzczL3NlcnZpY2VzL0FkbWluIiwg
+ InJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE5Mi4xNjguMjcuMTAwOjg3NzMvc2VydmljZXMvQ2xvdWQiLCAiaWQiOiAiMmIwZGMyYjNlY2U4NGJj
+ YWE1NDAzMDMzNzI5YzY3MjIiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDo4NzczL3NlcnZpY2VzL0Nsb3VkIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0
+ eXBlIjogImVjMiIsICJuYW1lIjogImVjMiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xOTIuMTY4LjI3LjEwMDozNTM1Ny92Mi4wIiwgInJlZ2lvbiI6ICJS
+ ZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE5Mi4xNjguMjcuMTAwOjUwMDAvdjIuMCIsICJpZCI6ICJiNTY2Y2JlZjA2NjQ0ZmY2OWMyOTMxNzY2Yjc5MTIyOSIsICJw
+ dWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMjcuMTAwOjUwMDAvdjIuMCJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpZGVudGl0eSIsICJuYW1lIjogImtleXN0
+ b25lIn1dLCAidXNlciI6IHsidXNlcm5hbWUiOiAiZGVtbyIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiZTVhMTM3NGE4YTRmNDI4NWIzYWQ3MzQ1MWU2MDY4YjEiLCAicm9sZXMi
+ OiBbeyJuYW1lIjogImFub3RoZXJyb2xlIn0sIHsibmFtZSI6ICJNZW1iZXIifV0sICJuYW1lIjogImRlbW8ifSwgIm1ldGFkYXRhIjogeyJpc19hZG1pbiI6IDAsICJyb2xlcyI6IFsi
+ YWRiODM3NDVkYzQzNGJhMzk5ODllNjBjOTIzYWZhMjgiLCAiMzM2ZTFiNjE1N2Y3NGFmZGJhNWUwYTYwMWUwNjM5MmYiXX19fTGB-zCB-AIBATBcMFcxCzAJBgNVBAYTAlVTMQ4wDAYD
+ VQQIEwVVbnNldDEOMAwGA1UEBxMFVW5zZXQxDjAMBgNVBAoTBVVuc2V0MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20CAQEwBwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEgYCAHLpsEs2R
+ nouriuiCgFayIqCssK3SVdhOMINiuJtqv0sE-wBDFiEj-Prcudqlz-n+6q7VgV4mwMPszz39-rwp+P5l4AjrJasUm7FrO-4l02tPLaaZXU1gBQ1jUG5e5aL5jPDP08HbCWuX6wr-QQQB
+ SrWY8lF3HrTcJT23sZIleg==
+
+Sign certificate issued by external CA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use a signing certificate issued by an external CA instead of
+generated by :command:`keystone-manage`. However, a certificate issued by an
+external CA must satisfy the following conditions:
+
+- All certificate and key files must be in Privacy Enhanced Mail (PEM)
+ format
+
+- Private key files must not be protected by a password
+
+When using a signing certificate issued by an external CA, you do not
+need to specify ``key_size``, ``valid_days``, and ``ca_password`` as
+they will be ignored.
+
+The basic workflow for using a signing certificate issued by an external
+CA involves:
+
+#. Request Signing Certificate from External CA
+
+#. Convert certificate and private key to PEM if needed
+
+#. Install External Signing Certificate
+
+Request a signing certificate from an external CA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One way to request a signing certificate from an external CA is to first
+generate a PKCS #10 Certificate Request Syntax (CRS) using OpenSSL CLI.
+
+Create a certificate request configuration file. For example, create the
+``cert_req.conf`` file, as follows:
+
+.. code-block:: ini
+
+ [ req ]
+ default_bits = 4096
+ default_keyfile = keystonekey.pem
+ default_md = sha256
+
+ prompt = no
+ distinguished_name = distinguished_name
+
+ [ distinguished_name ]
+ countryName = US
+ stateOrProvinceName = CA
+ localityName = Sunnyvale
+ organizationName = OpenStack
+ organizationalUnitName = Keystone
+ commonName = Keystone Signing
+ emailAddress = keystone@openstack.org
+
+Then generate a CRS with OpenSSL CLI. **Do not encrypt the generated
+private key. You must use the -nodes option.**
+
+For example:
+
+.. code-block:: console
+
+ $ openssl req -newkey rsa:1024 -keyout signing_key.pem -keyform PEM \
+ -out signing_cert_req.pem -outform PEM -config cert_req.conf -nodes
+
+If everything is successful, you should end up with
+``signing_cert_req.pem`` and ``signing_key.pem``. Send
+``signing_cert_req.pem`` to your CA to request a token signing certificate
+and make sure to ask the certificate to be in PEM format. Also, make sure your
+trusted CA certificate chain is also in PEM format.
+
+Install an external signing certificate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Assuming you have the following already:
+
+- ``signing_cert.pem``
+ (Keystone token) signing certificate in PEM format
+
+- ``signing_key.pem``
+ Corresponding (non-encrypted) private key in PEM format
+
+- ``cacert.pem``
+ Trust CA certificate chain in PEM format
+
+Copy the above to your certificate directory. For example:
+
+.. code-block:: console
+
+ # mkdir -p /etc/keystone/ssl/certs
+ # cp signing_cert.pem /etc/keystone/ssl/certs/
+ # cp signing_key.pem /etc/keystone/ssl/certs/
+ # cp cacert.pem /etc/keystone/ssl/certs/
+ # chmod -R 700 /etc/keystone/ssl/certs
+
+.. note::
+
+ Make sure the certificate directory is only accessible by root.
+
+.. note::
+
+ The procedure of copying the key and cert files may be improved if
+ done after first running :command:`keystone-manage pki_setup` since this
+ command also creates other needed files, such as the ``index.txt``
+ and ``serial`` files.
+
+ Also, when copying the necessary files to a different server for
+ replicating the functionality, the entire directory of files is
+ needed, not just the key and cert files.
+
+If your certificate directory path is different from the default
+``/etc/keystone/ssl/certs``, make sure it is reflected in the
+``[signing]`` section of the configuration file.
+
+Switching out expired signing certificates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following procedure details how to switch out expired signing
+certificates with no cloud outages.
+
+#. Generate a new signing key.
+
+#. Generate a new certificate request.
+
+#. Sign the new certificate with the existing CA to generate a new
+ ``signing_cert``.
+
+#. Append the new ``signing_cert`` to the old ``signing_cert``. Ensure the
+ old certificate is in the file first.
+
+#. Remove all signing certificates from all your hosts to force OpenStack
+ Compute to download the new ``signing_cert``.
+
+#. Replace the old signing key with the new signing key. Move the new
+ signing certificate above the old certificate in the ``signing_cert``
+ file.
+
+#. After the old certificate reads as expired, you can safely remove the
+ old signing certificate from the file.
diff --git a/doc/source/admin/identity-concepts.rst b/doc/source/admin/identity-concepts.rst
new file mode 100644
index 0000000000..cc60b4f9d6
--- /dev/null
+++ b/doc/source/admin/identity-concepts.rst
@@ -0,0 +1,354 @@
+=================
+Identity concepts
+=================
+
+Authentication
+ The process of confirming the identity of a user. To confirm an incoming
+ request, OpenStack Identity validates a set of credentials users
+ supply. Initially, these credentials are a user name and password, or a
+ user name and API key. When OpenStack Identity validates user credentials,
+ it issues an authentication token. Users provide the token in
+ subsequent requests.
+
+Credentials
+ Data that confirms the identity of the user. For example, user
+ name and password, user name and API key, or an authentication
+ token that the Identity service provides.
+
+Domain
+ An Identity service API v3 entity. Domains are a collection of
+ projects and users that define administrative boundaries for
+ managing Identity entities. Domains can represent an
+ individual, company, or operator-owned space. They expose
+ administrative activities directly to system users. Users can be
+ granted the administrator role for a domain. A domain
+ administrator can create projects, users, and groups in a domain
+ and assign roles to users and groups in a domain.
+
+Endpoint
+ A network-accessible address, usually a URL, through which you can
+ access a service. If you are using an extension for templates, you
+ can create an endpoint template that represents the templates of
+ all consumable services that are available across the regions.
+
+Group
+ An Identity service API v3 entity. Groups are a collection of
+ users owned by a domain. A group role, granted to a domain
+ or project, applies to all users in the group. Adding or removing
+ users to or from a group grants or revokes their role and
+ authentication to the associated domain or project.
+
+OpenStackClient
+ A command-line interface for several OpenStack services including
+ the Identity API. For example, a user can run the
+ :command:`openstack service create` and
+ :command:`openstack endpoint create` commands to register services
+ in their OpenStack installation.
+
+Project
+ A container that groups or isolates resources or identity objects.
+ Depending on the service operator, a project might map to a
+ customer, account, organization, or tenant.
+
+Region
+ An Identity service API v3 entity. Represents a general division
+ in an OpenStack deployment. You can associate zero or more
+ sub-regions with a region to make a tree-like structured hierarchy.
+ Although a region does not have a geographical connotation, a
+ deployment can use a geographical name for a region, such as ``us-east``.
+
+Role
+ A personality with a defined set of user rights and privileges to
+ perform a specific set of operations. The Identity service issues
+ a token to a user that includes a list of roles. When a user calls
+ a service, that service interprets the user role set, and
+ determines to which operations or resources each role grants
+ access.
+
+Service
+ An OpenStack service, such as Compute (nova), Object Storage
+ (swift), or Image service (glance), that provides one or more
+ endpoints through which users can access resources and perform
+ operations.
+
+Token
+ An alpha-numeric text string that enables access to OpenStack APIs
+ and resources. A token may be revoked at any time and is valid for
+ a finite duration. While OpenStack Identity supports token-based
+ authentication in this release, it intends to support additional
+ protocols in the future. OpenStack Identity is an integration
+ service that does not aspire to be a full-fledged identity store
+ and management solution.
+
+User
+ A digital representation of a person, system, or service that uses
+ OpenStack cloud services. The Identity service validates that
+ incoming requests are made by the user who claims to be making the
+ call. Users have a login and can access resources by using
+ assigned tokens. Users can be directly assigned to a particular
+ project and behave as if they are contained in that project.
+
+User management
+~~~~~~~~~~~~~~~
+
+Identity user management examples:
+
+* Create a user named ``alice``:
+
+ .. code-block:: console
+
+ $ openstack user create --password-prompt --email alice@example.com alice
+
+* Create a project named ``acme``:
+
+ .. code-block:: console
+
+ $ openstack project create acme --domain default
+
+* Create a domain named ``emea``:
+
+ .. code-block:: console
+
+ $ openstack --os-identity-api-version=3 domain create emea
+
+* Create a role named ``compute-user``:
+
+ .. code-block:: console
+
+ $ openstack role create compute-user
+
+ .. note::
+
+ Individual services assign meaning to roles, typically through
+ limiting or granting access to users with the role to the
+ operations that the service supports. Role access is typically
+ configured in the service's ``policy.json`` file. For example,
+ to limit Compute access to the ``compute-user`` role, edit the
+ Compute service's ``policy.json`` file to require this role for
+ Compute operations.
+
+The Identity service assigns a project and a role to a user. You might
+assign the ``compute-user`` role to the ``alice`` user in the ``acme``
+project:
+
+.. code-block:: console
+
+ $ openstack role add --project acme --user alice compute-user
+
+A user can have different roles in different projects. For example, Alice
+might also have the ``admin`` role in the ``Cyberdyne`` project. A user
+can also have multiple roles in the same project.
+
+The ``/etc/[SERVICE_CODENAME]/policy.json`` file controls the
+tasks that users can perform for a given service. For example, the
+``/etc/nova/policy.json`` file specifies the access policy for the
+Compute service, the ``/etc/glance/policy.json`` file specifies
+the access policy for the Image service, and the
+``/etc/keystone/policy.json`` file specifies the access policy for
+the Identity service.
+
+The default ``policy.json`` files in the Compute, Identity, and
+Image services recognize only the ``admin`` role. Any user with
+any role in a project can access all operations that do not require the
+``admin`` role.
+
+To restrict users from performing operations in, for example, the
+Compute service, you must create a role in the Identity service and
+then modify the ``/etc/nova/policy.json`` file so that this role
+is required for Compute operations.
+
+For example, the following line in the ``/etc/cinder/policy.json``
+file does not restrict which users can create volumes:
+
+.. code-block:: none
+
+ "volume:create": "",
+
+If the user has any role in a project, he can create volumes in that
+project.
+
+To restrict the creation of volumes to users who have the
+``compute-user`` role in a particular project, you add ``"role:compute-user"``:
+
+.. code-block:: none
+
+ "volume:create": "role:compute-user",
+
+To restrict all Compute service requests to require this role, the
+resulting file looks like:
+
+.. code-block:: json
+
+ {
+ "admin_or_owner": "role:admin or project_id:%(project_id)s",
+ "default": "rule:admin_or_owner",
+ "compute:create": "role:compute-user",
+ "compute:create:attach_network": "role:compute-user",
+ "compute:create:attach_volume": "role:compute-user",
+ "compute:get_all": "role:compute-user",
+ "compute:unlock_override": "rule:admin_api",
+ "admin_api": "role:admin",
+ "compute_extension:accounts": "rule:admin_api",
+ "compute_extension:admin_actions": "rule:admin_api",
+ "compute_extension:admin_actions:pause": "rule:admin_or_owner",
+ "compute_extension:admin_actions:unpause": "rule:admin_or_owner",
+ "compute_extension:admin_actions:suspend": "rule:admin_or_owner",
+ "compute_extension:admin_actions:resume": "rule:admin_or_owner",
+ "compute_extension:admin_actions:lock": "rule:admin_or_owner",
+ "compute_extension:admin_actions:unlock": "rule:admin_or_owner",
+ "compute_extension:admin_actions:resetNetwork": "rule:admin_api",
+ "compute_extension:admin_actions:injectNetworkInfo": "rule:admin_api",
+ "compute_extension:admin_actions:createBackup": "rule:admin_or_owner",
+ "compute_extension:admin_actions:migrateLive": "rule:admin_api",
+ "compute_extension:admin_actions:migrate": "rule:admin_api",
+ "compute_extension:aggregates": "rule:admin_api",
+ "compute_extension:certificates": "role:compute-user",
+ "compute_extension:cloudpipe": "rule:admin_api",
+ "compute_extension:console_output": "role:compute-user",
+ "compute_extension:consoles": "role:compute-user",
+ "compute_extension:createserverext": "role:compute-user",
+ "compute_extension:deferred_delete": "role:compute-user",
+ "compute_extension:disk_config": "role:compute-user",
+ "compute_extension:evacuate": "rule:admin_api",
+ "compute_extension:extended_server_attributes": "rule:admin_api",
+ "compute_extension:extended_status": "role:compute-user",
+ "compute_extension:flavorextradata": "role:compute-user",
+ "compute_extension:flavorextraspecs": "role:compute-user",
+ "compute_extension:flavormanage": "rule:admin_api",
+ "compute_extension:floating_ip_dns": "role:compute-user",
+ "compute_extension:floating_ip_pools": "role:compute-user",
+ "compute_extension:floating_ips": "role:compute-user",
+ "compute_extension:hosts": "rule:admin_api",
+ "compute_extension:keypairs": "role:compute-user",
+ "compute_extension:multinic": "role:compute-user",
+ "compute_extension:networks": "rule:admin_api",
+ "compute_extension:quotas": "role:compute-user",
+ "compute_extension:rescue": "role:compute-user",
+ "compute_extension:security_groups": "role:compute-user",
+ "compute_extension:server_action_list": "rule:admin_api",
+ "compute_extension:server_diagnostics": "rule:admin_api",
+ "compute_extension:simple_tenant_usage:show": "rule:admin_or_owner",
+ "compute_extension:simple_tenant_usage:list": "rule:admin_api",
+ "compute_extension:users": "rule:admin_api",
+ "compute_extension:virtual_interfaces": "role:compute-user",
+ "compute_extension:virtual_storage_arrays": "role:compute-user",
+ "compute_extension:volumes": "role:compute-user",
+ "compute_extension:volume_attachments:index": "role:compute-user",
+ "compute_extension:volume_attachments:show": "role:compute-user",
+ "compute_extension:volume_attachments:create": "role:compute-user",
+ "compute_extension:volume_attachments:delete": "role:compute-user",
+ "compute_extension:volumetypes": "role:compute-user",
+ "volume:create": "role:compute-user",
+ "volume:get_all": "role:compute-user",
+ "volume:get_volume_metadata": "role:compute-user",
+ "volume:get_snapshot": "role:compute-user",
+ "volume:get_all_snapshots": "role:compute-user",
+ "network:get_all_networks": "role:compute-user",
+ "network:get_network": "role:compute-user",
+ "network:delete_network": "role:compute-user",
+ "network:disassociate_network": "role:compute-user",
+ "network:get_vifs_by_instance": "role:compute-user",
+ "network:allocate_for_instance": "role:compute-user",
+ "network:deallocate_for_instance": "role:compute-user",
+ "network:validate_networks": "role:compute-user",
+ "network:get_instance_uuids_by_ip_filter": "role:compute-user",
+ "network:get_floating_ip": "role:compute-user",
+ "network:get_floating_ip_pools": "role:compute-user",
+ "network:get_floating_ip_by_address": "role:compute-user",
+ "network:get_floating_ips_by_project": "role:compute-user",
+ "network:get_floating_ips_by_fixed_address": "role:compute-user",
+ "network:allocate_floating_ip": "role:compute-user",
+ "network:deallocate_floating_ip": "role:compute-user",
+ "network:associate_floating_ip": "role:compute-user",
+ "network:disassociate_floating_ip": "role:compute-user",
+ "network:get_fixed_ip": "role:compute-user",
+ "network:add_fixed_ip_to_instance": "role:compute-user",
+ "network:remove_fixed_ip_from_instance": "role:compute-user",
+ "network:add_network_to_project": "role:compute-user",
+ "network:get_instance_nw_info": "role:compute-user",
+ "network:get_dns_domains": "role:compute-user",
+ "network:add_dns_entry": "role:compute-user",
+ "network:modify_dns_entry": "role:compute-user",
+ "network:delete_dns_entry": "role:compute-user",
+ "network:get_dns_entries_by_address": "role:compute-user",
+ "network:get_dns_entries_by_name": "role:compute-user",
+ "network:create_private_dns_domain": "role:compute-user",
+ "network:create_public_dns_domain": "role:compute-user",
+ "network:delete_dns_domain": "role:compute-user"
+ }
+
+Service management
+~~~~~~~~~~~~~~~~~~
+
+The Identity service provides identity, token, catalog, and policy
+services. It consists of:
+
+* keystone Web Server Gateway Interface (WSGI) service
+ Can be run in a WSGI-capable web server such as Apache httpd to provide
+ the Identity service. The service and administrative APIs are run as
+ separate instances of the WSGI service.
+
+* Identity service functions
+ Each has a pluggable back end that allow different ways to use the
+ particular service. Most support standard back ends like LDAP or SQL.
+
+* keystone-all
+ Starts both the service and administrative APIs in a single process.
+ Using federation with keystone-all is not supported. keystone-all is
+ deprecated in favor of the WSGI service. Also, this will be removed
+ in Newton.
+
+The Identity service also maintains a user that corresponds to each
+service, such as, a user named ``nova`` for the Compute service, and a
+special service project called ``service``.
+
+For information about how to create services and endpoints, see the
+`OpenStack Administrator Guide `__.
+
+Groups
+~~~~~~
+
+A group is a collection of users in a domain. Administrators can
+create groups and add users to them. A role can then be assigned to
+the group, rather than individual users. Groups were introduced with
+the Identity API v3.
+
+Identity API V3 provides the following group-related operations:
+
+* Create a group
+
+* Delete a group
+
+* Update a group (change its name or description)
+
+* Add a user to a group
+
+* Remove a user from a group
+
+* List group members
+
+* List groups for a user
+
+* Assign a role on a project to a group
+
+* Assign a role on a domain to a group
+
+* Query role assignments to groups
+
+.. note::
+
+ The Identity service server might not allow all operations. For
+ example, if you use the Identity server with the LDAP Identity
+ back end and group updates are disabled, a request to create,
+ delete, or update a group fails.
+
+Here are a couple of examples:
+
+* Group A is granted Role A on Project A. If User A is a member of Group
+ A, when User A gets a token scoped to Project A, the token also
+ includes Role A.
+
+* Group B is granted Role B on Domain B. If User B is a member of
+ Group B, when User B gets a token scoped to Domain B, the token also
+ includes Role B.
diff --git a/doc/source/admin/identity-domain-specific-config.rst b/doc/source/admin/identity-domain-specific-config.rst
new file mode 100644
index 0000000000..b15f69889a
--- /dev/null
+++ b/doc/source/admin/identity-domain-specific-config.rst
@@ -0,0 +1,69 @@
+=============================
+Domain-specific configuration
+=============================
+
+The Identity service supports domain-specific Identity drivers.
+The drivers allow a domain to have its own LDAP or SQL back end.
+By default, domain-specific drivers are disabled.
+
+Domain-specific Identity configuration options can be stored in
+domain-specific configuration files, or in the Identity SQL
+database using API REST calls.
+
+.. note::
+
+ Storing and managing configuration options in an SQL database is
+ experimental in Kilo, and added to the Identity service in the
+ Liberty release.
+
+Enable drivers for domain-specific configuration files
+------------------------------------------------------
+
+To enable domain-specific drivers, set these options in the
+``/etc/keystone/keystone.conf`` file:
+
+.. code-block:: ini
+
+ [identity]
+ domain_specific_drivers_enabled = True
+ domain_config_dir = /etc/keystone/domains
+
+When you enable domain-specific drivers, Identity looks in the
+``domain_config_dir`` directory for configuration files that are named as
+``keystone.DOMAIN_NAME.conf``. A domain without a domain-specific
+configuration file uses options in the primary configuration file.
+
+Enable drivers for storing configuration options in SQL database
+----------------------------------------------------------------
+
+To enable domain-specific drivers, set these options in the
+``/etc/keystone/keystone.conf`` file:
+
+.. code-block:: ini
+
+ [identity]
+ domain_specific_drivers_enabled = True
+ domain_configurations_from_database = True
+
+Any domain-specific configuration options specified through the
+Identity v3 API will override domain-specific configuration files in the
+``/etc/keystone/domains`` directory.
+
+Migrate domain-specific configuration files to the SQL database
+---------------------------------------------------------------
+
+You can use the ``keystone-manage`` command to migrate configuration
+options in domain-specific configuration files to the SQL database:
+
+.. code-block:: console
+
+ # keystone-manage domain_config_upload --all
+
+To upload options from a specific domain-configuration file, specify the
+domain name:
+
+.. code-block:: console
+
+ # keystone-manage domain_config_upload --domain-name DOMAIN_NAME
+
+
diff --git a/doc/source/admin/identity-external-authentication.rst b/doc/source/admin/identity-external-authentication.rst
new file mode 100644
index 0000000000..62b55714e4
--- /dev/null
+++ b/doc/source/admin/identity-external-authentication.rst
@@ -0,0 +1,41 @@
+=====================================
+External authentication with Identity
+=====================================
+
+When Identity runs in ``apache-httpd``, you can use external
+authentication methods that differ from the authentication provided by
+the identity store back end. For example, you can use an SQL identity
+back end together with X.509 authentication and Kerberos, instead of
+using the user name and password combination.
+
+Use HTTPD authentication
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Web servers, like Apache HTTP, support many methods of authentication.
+Identity can allow the web server to perform the authentication. The web
+server then passes the authenticated user to Identity by using the
+``REMOTE_USER`` environment variable. This user must already exist in
+the Identity back end to get a token from the controller. To use this
+method, Identity should run on ``apache-httpd``.
+
+Use X.509
+~~~~~~~~~
+
+The following Apache configuration snippet authenticates the user based
+on a valid X.509 certificate from a known CA:
+
+.. code-block:: none
+
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/ssl.cert
+ SSLCertificateKeyFile /etc/ssl/private/ssl.key
+
+ SSLCACertificatePath /etc/ssl/allowed_cas
+ SSLCARevocationPath /etc/ssl/allowed_cas
+ SSLUserName SSL_CLIENT_S_DN_CN
+ SSLVerifyClient require
+ SSLVerifyDepth 10
+
+ (...)
+
diff --git a/doc/source/admin/identity-fernet-token-faq.rst b/doc/source/admin/identity-fernet-token-faq.rst
new file mode 100644
index 0000000000..2b2cdb0cb7
--- /dev/null
+++ b/doc/source/admin/identity-fernet-token-faq.rst
@@ -0,0 +1,345 @@
+===================================
+Fernet - Frequently Asked Questions
+===================================
+
+The following questions have been asked periodically since the initial release
+of the fernet token format in Kilo.
+
+What are the different types of keys?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A key repository is required by keystone in order to create fernet tokens.
+These keys are used to encrypt and decrypt the information that makes up the
+payload of the token. Each key in the repository can have one of three states.
+The state of the key determines how keystone uses a key with fernet tokens. The
+different types are as follows:
+
+Primary key:
+ There is only ever one primary key in a key repository. The primary key is
+ allowed to encrypt and decrypt tokens. This key is always named as the
+ highest index in the repository.
+Secondary key:
+ A secondary key was at one point a primary key, but has been demoted in place
+ of another primary key. It is only allowed to decrypt tokens. Since it was
+ the primary at some point in time, its existence in the key repository is
+ justified. Keystone needs to be able to decrypt tokens that were created with
+ old primary keys.
+Staged key:
+ The staged key is a special key that shares some similarities with secondary
+ keys. There can only ever be one staged key in a repository and it must
+ exist. Just like secondary keys, staged keys have the ability to decrypt
+ tokens. Unlike secondary keys, staged keys have never been a primary key. In
+ fact, they are opposites since the staged key will always be the next primary
+ key. This helps clarify the name because they are the next key staged to be
+ the primary key. This key is always named as ``0`` in the key repository.
+
+So, how does a staged key help me and why do I care about it?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The fernet keys have a natural lifecycle. Each key starts as a staged key, is
+promoted to be the primary key, and then demoted to be a secondary key. New
+tokens can only be encrypted with a primary key. Secondary and staged keys are
+never used to encrypt token. The staged key is a special key given the order of
+events and the attributes of each type of key. The staged key is the only key
+in the repository that has not had a chance to encrypt any tokens yet, but it
+is still allowed to decrypt tokens. As an operator, this gives you the chance
+to perform a key rotation on one keystone node, and distribute the new key set
+over a span of time. This does not require the distribution to take place in an
+ultra short period of time. Tokens encrypted with a primary key can be
+decrypted, and validated, on other nodes where that key is still staged.
+
+Where do I put my key repository?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The key repository is specified using the ``key_repository`` option in the
+keystone configuration file. The keystone process should be able to read and
+write to this location but it should be kept secret otherwise. Currently,
+keystone only supports file-backed key repositories.
+
+.. code-block:: ini
+
+ [fernet_tokens]
+ key_repository = /etc/keystone/fernet-keys/
+
+What is the recommended way to rotate and distribute keys?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :command:`keystone-manage` command line utility includes a key rotation
+mechanism. This mechanism will initialize and rotate keys but does not make
+an effort to distribute keys across keystone nodes. The distribution of keys
+across a keystone deployment is best handled through configuration management
+tooling. Use :command:`keystone-manage fernet_rotate` to rotate the key
+repository.
+
+Do fernet tokens still expire?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Yes, fernet tokens can expire just like any other keystone token formats.
+
+Why should I choose fernet tokens over UUID tokens?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Even though fernet tokens operate very similarly to UUID tokens, they do not
+require persistence. The keystone token database no longer suffers bloat as a
+side effect of authentication. Pruning expired tokens from the token database
+is no longer required when using fernet tokens. Because fernet tokens do not
+require persistence, they do not have to be replicated. As long as each
+keystone node shares the same key repository, fernet tokens can be created and
+validated instantly across nodes.
+
+Why should I choose fernet tokens over PKI or PKIZ tokens?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The arguments for using fernet over PKI and PKIZ remain the same as UUID, in
+addition to the fact that fernet tokens are much smaller than PKI and PKIZ
+tokens. PKI and PKIZ tokens still require persistent storage and can sometimes
+cause issues due to their size. This issue is mitigated when switching to
+fernet because fernet tokens are kept under a 250 byte limit. PKI and PKIZ
+tokens typically exceed 1600 bytes in length. The length of a PKI or PKIZ token
+is dependent on the size of the deployment. Bigger service catalogs will result
+in longer token lengths. This pattern does not exist with fernet tokens because
+the contents of the encrypted payload is kept to a minimum.
+
+Should I rotate and distribute keys from the same keystone node every rotation?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+No, but the relationship between rotation and distribution should be lock-step.
+Once you rotate keys on one keystone node, the key repository from that node
+should be distributed to the rest of the cluster. Once you confirm that each
+node has the same key repository state, you could rotate and distribute from
+any other node in the cluster.
+
+If the rotation and distribution are not lock-step, a single keystone node in
+the deployment will create tokens with a primary key that no other node has as
+a staged key. This will cause tokens generated from one keystone node to fail
+validation on other keystone nodes.
+
+How do I add new keystone nodes to a deployment?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The keys used to create fernet tokens should be treated like super secret
+configuration files, similar to an SSL secret key. Before a node is allowed to
+join an existing cluster, issuing and validating tokens, it should have the
+same key repository as the rest of the nodes in the cluster.
+
+How should I approach key distribution?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Remember that key distribution is only required in multi-node keystone
+deployments. If you only have one keystone node serving requests in your
+deployment, key distribution is unnecessary.
+
+Key distribution is a problem best approached from the deployment's current
+configuration management system. Since not all deployments use the same
+configuration management systems, it makes sense to explore options around what
+is already available for managing keys, while keeping the secrecy of the keys
+in mind. Many configuration management tools can leverage something like
+``rsync`` to manage key distribution.
+
+Key rotation is a single operation that promotes the current staged key to
+primary, creates a new staged key, and prunes old secondary keys. It is easiest
+to do this on a single node and verify the rotation took place properly before
+distributing the key repository to the rest of the cluster. The concept behind
+the staged key breaks the expectation that key rotation and key distribution
+have to be done in a single step. With the staged key, we have time to inspect
+the new key repository before syncing state with the rest of the cluster. Key
+distribution should be an operation that can run in succession until it
+succeeds. The following might help illustrate the isolation between key
+rotation and key distribution.
+
+#. Ensure all keystone nodes in the deployment have the same key repository.
+#. Pick a keystone node in the cluster to rotate from.
+#. Rotate keys.
+
+ #. Was it successful?
+
+ #. If no, investigate issues with the particular keystone node you
+ rotated keys on. Fernet keys are small and the operation for
+ rotation is trivial. There should not be much room for error in key
+ rotation. It is possible that the user does not have the ability to
+ write new keys to the key repository. Log output from
+ ``keystone-manage fernet_rotate`` should give more information into
+ specific failures.
+
+ #. If yes, you should see a new staged key. The old staged key should
+ be the new primary. Depending on the ``max_active_keys`` limit you
+ might have secondary keys that were pruned. At this point, the node
+ that you rotated on will be creating fernet tokens with a primary
+ key that all other nodes should have as the staged key. This is why
+ we checked the state of all key repositories in Step one. All other
+ nodes in the cluster should be able to decrypt tokens created with
+ the new primary key. At this point, we are ready to distribute the
+ new key set.
+
+#. Distribute the new key repository.
+
+ #. Was it successful?
+
+ #. If yes, you should be able to confirm that all nodes in the cluster
+ have the same key repository that was introduced in Step 3. All
+ nodes in the cluster will be creating tokens with the primary key
+ that was promoted in Step 3. No further action is required until the
+ next schedule key rotation.
+
+ #. If no, try distributing again. Remember that we already rotated the
+ repository and performing another rotation at this point will
+ result in tokens that cannot be validated across certain hosts.
+ Specifically, the hosts that did not get the latest key set. You
+ should be able to distribute keys until it is successful. If certain
+ nodes have issues syncing, it could be permission or network issues
+ and those should be resolved before subsequent rotations.
+
+How long should I keep my keys around?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The fernet tokens that keystone creates are only secure as the keys creating
+them. With staged keys the penalty of key rotation is low, allowing you to err
+on the side of security and rotate weekly, daily, or even hourly. Ultimately,
+this should be less time than it takes an attacker to break a ``AES256`` key
+and a ``SHA256 HMAC``.
+
+Is a fernet token still a bearer token?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Yes, and they follow exactly the same validation path as UUID tokens, with the
+exception of being written to, and read from, a back end. If someone
+compromises your fernet token, they have the power to do all the operations you
+are allowed to do.
+
+What if I need to revoke all my tokens?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To invalidate every token issued from keystone and start fresh, remove the
+current key repository, create a new key set, and redistribute it to all nodes
+in the cluster. This will render every token issued from keystone as invalid
+regardless if the token has actually expired. When a client goes to
+re-authenticate, the new token will have been created with a new fernet key.
+
+What can an attacker do if they compromise a fernet key in my deployment?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If any key used in the key repository is compromised, an attacker will be able
+to build their own tokens. If they know the ID of an administrator on a
+project, they could generate administrator tokens for the project. They will be
+able to generate their own tokens until the compromised key has been removed
+from from the repository.
+
+I rotated keys and now tokens are invalidating early, what did I do?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using fernet tokens requires some awareness around token expiration and the key
+lifecycle. You do not want to rotate so often that secondary keys are removed
+that might still be needed to decrypt unexpired tokens. If this happens, you
+will not be able to decrypt the token because the key the was used to encrypt
+it is now gone. Only remove keys that you know are not being used to encrypt or
+decrypt tokens.
+
+For example, your token is valid for 24 hours and we want to rotate keys every
+six hours. We will need to make sure tokens that were created at 08:00 AM on
+Monday are still valid at 07:00 AM on Tuesday, assuming they were not
+prematurely revoked. To accomplish this, we will want to make sure we set
+``max_active_keys=6`` in our keystone configuration file. This will allow us to
+hold all keys that might still be required to validate a previous token, but
+keeps the key repository limited to only the keys that are needed.
+
+The number of ``max_active_keys`` for a deployment can be determined by
+dividing the token lifetime, in hours, by the frequency of rotation in hours
+and adding two. Better illustrated as::
+
+ token_expiration = 24
+ rotation_frequency = 6
+ max_active_keys = (token_expiration / rotation_frequency) + 2
+
+The reason for adding two additional keys to the count is to include the staged
+key and a buffer key. This can be shown based on the previous example. We
+initially setup the key repository at 6:00 AM on Monday, and the initial state
+looks like:
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 1 (primary key)
+
+All tokens created after 6:00 AM are encrypted with key ``1``. At 12:00 PM we
+will rotate keys again, resulting in,
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 1 (secondary key)
+ -rw------- 1 keystone keystone 44 2 (primary key)
+
+We are still able to validate tokens created between 6:00 - 11:59 AM because
+the ``1`` key still exists as a secondary key. All tokens issued after 12:00 PM
+will be encrypted with key ``2``. At 6:00 PM we do our next rotation, resulting
+in:
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 1 (secondary key)
+ -rw------- 1 keystone keystone 44 2 (secondary key)
+ -rw------- 1 keystone keystone 44 3 (primary key)
+
+It is still possible to validate tokens issued from 6:00 AM - 5:59 PM because
+keys ``1`` and ``2`` exist as secondary keys. Every token issued until 11:59 PM
+will be encrypted with key ``3``, and at 12:00 AM we do our next rotation:
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 1 (secondary key)
+ -rw------- 1 keystone keystone 44 2 (secondary key)
+ -rw------- 1 keystone keystone 44 3 (secondary key)
+ -rw------- 1 keystone keystone 44 4 (primary key)
+
+Just like before, we can still validate tokens issued from 6:00 AM the previous
+day until 5:59 AM today because keys ``1`` - ``4`` are present. At 6:00 AM,
+tokens issued from the previous day will start to expire and we do our next
+scheduled rotation:
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 1 (secondary key)
+ -rw------- 1 keystone keystone 44 2 (secondary key)
+ -rw------- 1 keystone keystone 44 3 (secondary key)
+ -rw------- 1 keystone keystone 44 4 (secondary key)
+ -rw------- 1 keystone keystone 44 5 (primary key)
+
+Tokens will naturally expire after 6:00 AM, but we will not be able to remove
+key ``1`` until the next rotation because it encrypted all tokens from 6:00 AM
+to 12:00 PM the day before. Once we do our next rotation, which is at 12:00 PM,
+the ``1`` key will be pruned from the repository:
+
+.. code-block:: console
+
+ $ ls -la /etc/keystone/fernet-keys/
+ drwx------ 2 keystone keystone 4096 .
+ drwxr-xr-x 3 keystone keystone 4096 ..
+ -rw------- 1 keystone keystone 44 0 (staged key)
+ -rw------- 1 keystone keystone 44 2 (secondary key)
+ -rw------- 1 keystone keystone 44 3 (secondary key)
+ -rw------- 1 keystone keystone 44 4 (secondary key)
+ -rw------- 1 keystone keystone 44 5 (secondary key)
+ -rw------- 1 keystone keystone 44 6 (primary key)
+
+If keystone were to receive a token that was created between 6:00 AM and 12:00
+PM the day before, encrypted with the ``1`` key, it would not be valid because
+it was already expired. This makes it possible for us to remove the ``1`` key
+from the repository without negative validation side-effects.
diff --git a/doc/source/admin/identity-integrate-with-ldap.rst b/doc/source/admin/identity-integrate-with-ldap.rst
new file mode 100644
index 0000000000..a2ad2fb41d
--- /dev/null
+++ b/doc/source/admin/identity-integrate-with-ldap.rst
@@ -0,0 +1,453 @@
+.. _integrate-identity-with-ldap:
+
+============================
+Integrate Identity with LDAP
+============================
+
+The OpenStack Identity service supports integration with existing LDAP
+directories for authentication and authorization services. LDAP back
+ends require initialization before configuring the OpenStack Identity
+service to work with it. For more information, see `Setting up LDAP
+for use with Keystone `__.
+
+When the OpenStack Identity service is configured to use LDAP back ends,
+you can split authentication (using the *identity* feature) and
+authorization (using the *assignment* feature).
+
+The *identity* feature enables administrators to manage users and groups
+by each domain or the OpenStack Identity service entirely.
+
+The *assignment* feature enables administrators to manage project role
+authorization using the OpenStack Identity service SQL database, while
+providing user authentication through the LDAP directory.
+
+.. _identity_ldap_server_setup:
+
+Identity LDAP server set up
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. important::
+
+ For the OpenStack Identity service to access LDAP servers, you must
+ enable the ``authlogin_nsswitch_use_ldap`` boolean value for SELinux
+ on the server running the OpenStack Identity service. To enable and
+ make the option persistent across reboots, set the following boolean
+ value as the root user:
+
+ .. code-block:: console
+
+ # setsebool -P authlogin_nsswitch_use_ldap on
+
+The Identity configuration is split into two separate back ends; identity
+(back end for users and groups), and assignments (back end for domains,
+projects, roles, role assignments). To configure Identity, set options
+in the ``/etc/keystone/keystone.conf`` file. See
+:ref:`integrate-identity-backend-ldap` for Identity back end configuration
+examples. Modify these examples as needed.
+
+**To define the destination LDAP server**
+
+#. Define the destination LDAP server in the
+ ``/etc/keystone/keystone.conf`` file:
+
+ .. code-block:: ini
+
+ [ldap]
+ url = ldap://localhost
+ user = dc=Manager,dc=example,dc=org
+ password = samplepassword
+ suffix = dc=example,dc=org
+
+**Additional LDAP integration settings**
+
+Set these options in the ``/etc/keystone/keystone.conf`` file for a
+single LDAP server, or ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf``
+files for multiple back ends. Example configurations appear below each
+setting summary:
+
+**Query option**
+
+.. hlist::
+ :columns: 1
+
+ * Use ``query_scope`` to control the scope level of data presented
+ (search only the first level or search an entire sub-tree)
+ through LDAP.
+ * Use ``page_size`` to control the maximum results per page. A value
+ of zero disables paging.
+ * Use ``alias_dereferencing`` to control the LDAP dereferencing
+ option for queries.
+
+.. code-block:: ini
+
+ [ldap]
+ query_scope = sub
+ page_size = 0
+ alias_dereferencing = default
+ chase_referrals =
+
+**Debug**
+
+Use ``debug_level`` to set the LDAP debugging level for LDAP calls.
+A value of zero means that debugging is not enabled.
+
+.. code-block:: ini
+
+ [ldap]
+ debug_level = 0
+
+.. warning::
+
+ This value is a bitmask, consult your LDAP documentation for
+ possible values.
+
+**Connection pooling**
+
+Use ``use_pool`` to enable LDAP connection pooling. Configure the
+connection pool size, maximum retry, reconnect trials, timeout (-1
+indicates indefinite wait) and lifetime in seconds.
+
+.. code-block:: ini
+
+ [ldap]
+ use_pool = true
+ pool_size = 10
+ pool_retry_max = 3
+ pool_retry_delay = 0.1
+ pool_connection_timeout = -1
+ pool_connection_lifetime = 600
+
+**Connection pooling for end user authentication**
+
+Use ``use_auth_pool`` to enable LDAP connection pooling for end user
+authentication. Configure the connection pool size and lifetime in
+seconds.
+
+.. code-block:: ini
+
+ [ldap]
+ use_auth_pool = false
+ auth_pool_size = 100
+ auth_pool_connection_lifetime = 60
+
+When you have finished the configuration, restart the OpenStack Identity
+service.
+
+.. warning::
+
+ During the service restart, authentication and authorization are
+ unavailable.
+
+.. _integrate-identity-backend-ldap:
+
+Integrate Identity back end with LDAP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Identity back end contains information for users, groups, and group
+member lists. Integrating the Identity back end with LDAP allows
+administrators to use users and groups in LDAP.
+
+.. important::
+
+ For OpenStack Identity service to access LDAP servers, you must
+ define the destination LDAP server in the
+ ``/etc/keystone/keystone.conf`` file. For more information,
+ see :ref:`identity_ldap_server_setup`.
+
+**To integrate one Identity back end with LDAP**
+
+#. Enable the LDAP Identity driver in the ``/etc/keystone/keystone.conf``
+ file. This allows LDAP as an identity back end:
+
+ .. code-block:: ini
+
+ [identity]
+ #driver = sql
+ driver = ldap
+
+#. Create the organizational units (OU) in the LDAP directory, and define
+ the corresponding location in the ``/etc/keystone/keystone.conf``
+ file:
+
+ .. code-block:: ini
+
+ [ldap]
+ user_tree_dn = ou=Users,dc=example,dc=org
+ user_objectclass = inetOrgPerson
+
+ group_tree_dn = ou=Groups,dc=example,dc=org
+ group_objectclass = groupOfNames
+
+ .. note::
+
+ These schema attributes are extensible for compatibility with
+ various schemas. For example, this entry maps to the person
+ attribute in Active Directory:
+
+ .. code-block:: ini
+
+ user_objectclass = person
+
+#. A read-only implementation is recommended for LDAP integration. These
+ permissions are applied to object types in the
+ ``/etc/keystone/keystone.conf`` file:
+
+ .. code-block:: ini
+
+ [ldap]
+ user_allow_create = False
+ user_allow_update = False
+ user_allow_delete = False
+
+ group_allow_create = False
+ group_allow_update = False
+ group_allow_delete = False
+
+ Restart the OpenStack Identity service.
+
+ .. warning::
+
+ During service restart, authentication and authorization are
+ unavailable.
+
+**To integrate multiple Identity back ends with LDAP**
+
+#. Set the following options in the ``/etc/keystone/keystone.conf``
+ file:
+
+ #. Enable the LDAP driver:
+
+ .. code-block:: ini
+
+ [identity]
+ #driver = sql
+ driver = ldap
+
+ #. Enable domain-specific drivers:
+
+ .. code-block:: ini
+
+ [identity]
+ domain_specific_drivers_enabled = True
+ domain_config_dir = /etc/keystone/domains
+
+#. Restart the OpenStack Identity service.
+
+ .. warning::
+
+ During service restart, authentication and authorization are
+ unavailable.
+
+#. List the domains using the dashboard, or the OpenStackClient CLI. Refer
+ to the `Command List
+ `__
+ for a list of OpenStackClient commands.
+
+#. Create domains using OpenStack dashboard, or the OpenStackClient CLI.
+
+#. For each domain, create a domain-specific configuration file in the
+ ``/etc/keystone/domains`` directory. Use the file naming convention
+ ``keystone.DOMAIN_NAME.conf``, where DOMAIN\_NAME is the domain name
+ assigned in the previous step.
+
+ .. note::
+
+ The options set in the
+ ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf`` file will
+ override options in the ``/etc/keystone/keystone.conf`` file.
+
+#. Define the destination LDAP server in the
+ ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf`` file. For example:
+
+ .. code-block:: ini
+
+ [ldap]
+ url = ldap://localhost
+ user = dc=Manager,dc=example,dc=org
+ password = samplepassword
+ suffix = dc=example,dc=org
+
+#. Create the organizational units (OU) in the LDAP directories, and define
+ their corresponding locations in the
+ ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf`` file. For example:
+
+ .. code-block:: ini
+
+ [ldap]
+ user_tree_dn = ou=Users,dc=example,dc=org
+ user_objectclass = inetOrgPerson
+
+ group_tree_dn = ou=Groups,dc=example,dc=org
+ group_objectclass = groupOfNames
+
+ .. note::
+
+ These schema attributes are extensible for compatibility with
+ various schemas. For example, this entry maps to the person
+ attribute in Active Directory:
+
+ .. code-block:: ini
+
+ user_objectclass = person
+
+#. A read-only implementation is recommended for LDAP integration. These
+ permissions are applied to object types in the
+ ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf`` file:
+
+ .. code-block:: ini
+
+ [ldap]
+ user_allow_create = False
+ user_allow_update = False
+ user_allow_delete = False
+
+ group_allow_create = False
+ group_allow_update = False
+ group_allow_delete = False
+
+#. Restart the OpenStack Identity service.
+
+ .. warning::
+
+ During service restart, authentication and authorization are
+ unavailable.
+
+**Additional LDAP integration settings**
+
+Set these options in the ``/etc/keystone/keystone.conf`` file for a
+single LDAP server, or ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf``
+files for multiple back ends. Example configurations appear below each
+setting summary:
+
+Filters
+ Use filters to control the scope of data presented through LDAP.
+
+ .. code-block:: ini
+
+ [ldap]
+ user_filter = (memberof=cn=openstack-users,ou=workgroups,dc=example,dc=org)
+ group_filter =
+
+Identity attribute mapping
+ Mask account status values (include any additional attribute
+ mappings) for compatibility with various directory services.
+ Superfluous accounts are filtered with ``user_filter``.
+
+ Setting attribute ignore to list of attributes stripped off on
+ update.
+
+ For example, you can mask Active Directory account status attributes
+ in the ``/etc/keystone/keystone.conf`` file:
+
+ .. code-block:: ini
+
+ [ldap]
+ user_id_attribute = cn
+ user_name_attribute = sn
+ user_mail_attribute = mail
+ user_pass_attribute = userPassword
+ user_enabled_attribute = userAccountControl
+ user_enabled_mask = 2
+ user_enabled_invert = false
+ user_enabled_default = 512
+ user_default_project_id_attribute =
+ user_additional_attribute_mapping =
+
+ group_id_attribute = cn
+ group_name_attribute = ou
+ group_member_attribute = member
+ group_desc_attribute = description
+ group_additional_attribute_mapping =
+
+Enabled emulation
+ An alternative method to determine if a user is enabled or not is by
+ checking if that user is a member of the emulation group.
+
+ Use DN of the group entry to hold enabled user when using enabled
+ emulation.
+
+ .. code-block:: ini
+
+ [ldap]
+ user_enabled_emulation = false
+ user_enabled_emulation_dn = false
+
+When you have finished configuration, restart the OpenStack Identity
+service.
+
+.. warning::
+
+ During service restart, authentication and authorization are
+ unavailable.
+
+Secure the OpenStack Identity service connection to an LDAP back end
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Identity service supports the use of TLS to encrypt LDAP traffic.
+Before configuring this, you must first verify where your certificate
+authority file is located. For more information, see the
+`OpenStack Security Guide SSL introduction `_.
+
+Once you verify the location of your certificate authority file:
+
+**To configure TLS encryption on LDAP traffic**
+
+#. Open the ``/etc/keystone/keystone.conf`` configuration file.
+
+#. Find the ``[ldap]`` section.
+
+#. In the ``[ldap]`` section, set the ``use_tls`` configuration key to
+ ``True``. Doing so will enable TLS.
+
+#. Configure the Identity service to use your certificate authorities file.
+ To do so, set the ``tls_cacertfile`` configuration key in the ``ldap``
+ section to the certificate authorities file's path.
+
+ .. note::
+
+ You can also set the ``tls_cacertdir`` (also in the ``ldap``
+ section) to the directory where all certificate authorities files
+ are kept. If both ``tls_cacertfile`` and ``tls_cacertdir`` are set,
+ then the latter will be ignored.
+
+#. Specify what client certificate checks to perform on incoming TLS
+ sessions from the LDAP server. To do so, set the ``tls_req_cert``
+ configuration key in the ``[ldap]`` section to ``demand``, ``allow``, or
+ ``never``:
+
+ .. hlist::
+ :columns: 1
+
+ * ``demand`` - The LDAP server always receives certificate
+ requests. The session terminates if no certificate
+ is provided, or if the certificate provided cannot be verified
+ against the existing certificate authorities file.
+ * ``allow`` - The LDAP server always receives certificate
+ requests. The session will proceed as normal even if a certificate
+ is not provided. If a certificate is provided but it cannot be
+ verified against the existing certificate authorities file, the
+ certificate will be ignored and the session will proceed as
+ normal.
+ * ``never`` - A certificate will never be requested.
+
+On distributions that include openstack-config, you can configure TLS
+encryption on LDAP traffic by running the following commands instead.
+
+.. code-block:: console
+
+ # openstack-config --set /etc/keystone/keystone.conf \
+ ldap use_tls True
+ # openstack-config --set /etc/keystone/keystone.conf \
+ ldap tls_cacertfile ``CA_FILE``
+ # openstack-config --set /etc/keystone/keystone.conf \
+ ldap tls_req_cert ``CERT_BEHAVIOR``
+
+Where:
+
+- ``CA_FILE`` is the absolute path to the certificate authorities file
+ that should be used to encrypt LDAP traffic.
+
+- ``CERT_BEHAVIOR`` specifies what client certificate checks to perform
+ on an incoming TLS session from the LDAP server (``demand``,
+ ``allow``, or ``never``).
diff --git a/doc/source/admin/identity-keystone-usage-and-features.rst b/doc/source/admin/identity-keystone-usage-and-features.rst
new file mode 100644
index 0000000000..7a71aaac72
--- /dev/null
+++ b/doc/source/admin/identity-keystone-usage-and-features.rst
@@ -0,0 +1,83 @@
+
+Example usage and Identity features
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``openstack`` CLI is used to interact with the Identity service.
+It is set up to expect commands in the general
+form of ``openstack command argument``, followed by flag-like keyword
+arguments to provide additional (often optional) information. For
+example, the :command:`openstack user list` and
+:command:`openstack project create` commands can be invoked as follows:
+
+.. code-block:: bash
+
+ # Using token auth env variables
+ export OS_SERVICE_ENDPOINT=http://127.0.0.1:5000/v2.0/
+ export OS_SERVICE_TOKEN=secrete_token
+ openstack user list
+ openstack project create demo --domain default
+
+ # Using token auth flags
+ openstack --os-token secrete --os-endpoint http://127.0.0.1:5000/v2.0/ user list
+ openstack --os-token secrete --os-endpoint http://127.0.0.1:5000/v2.0/ project create demo
+
+ # Using user + password + project_name env variables
+ export OS_USERNAME=admin
+ export OS_PASSWORD=secrete
+ export OS_PROJECT_NAME=admin
+ openstack user list
+ openstack project create demo --domain default
+
+ # Using user + password + project-name flags
+ openstack --os-username admin --os-password secrete --os-project-name admin user list
+ openstack --os-username admin --os-password secrete --os-project-name admin project create demo
+
+
+Logging
+-------
+
+You configure logging externally to the rest of Identity. The name of
+the file specifying the logging configuration is set using the
+``log_config`` option in the ``[DEFAULT]`` section of the
+``/etc/keystone/keystone.conf`` file. To route logging through syslog,
+set ``use_syslog=true`` in the ``[DEFAULT]`` section.
+
+A sample logging configuration file is available with the project in
+``etc/logging.conf.sample``. Like other OpenStack projects, Identity
+uses the Python logging module, which provides extensive configuration
+options that let you define the output levels and formats.
+
+
+User CRUD
+---------
+
+Identity provides a user CRUD (Create, Read, Update, and Delete) filter that
+Administrators can add to the ``public_api`` pipeline. The user CRUD filter
+enables users to use a HTTP PATCH to change their own password. To enable
+this extension you should define a ``user_crud_extension`` filter, insert
+it after the ``*_body`` middleware and before the ``public_service``
+application in the ``public_api`` WSGI pipeline in
+``keystone-paste.ini``. For example:
+
+.. code-block:: ini
+
+ [filter:user_crud_extension]
+ paste.filter_factory = keystone.contrib.user_crud:CrudExtension.factory
+
+ [pipeline:public_api]
+ pipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension user_crud_extension public_service
+
+Each user can then change their own password with a HTTP PATCH.
+
+.. code-block:: console
+
+ $ curl -X PATCH http://localhost:5000/v2.0/OS-KSCRUD/users/USERID -H "Content-type: application/json" \
+ -H "X_Auth_Token: AUTHTOKENID" -d '{"user": {"password": "ABCD", "original_password": "DCBA"}}'
+
+In addition to changing their password, all current tokens for the user
+are invalidated.
+
+.. note::
+
+ Only use a KVS back end for tokens when testing.
+
diff --git a/doc/source/admin/identity-management.rst b/doc/source/admin/identity-management.rst
new file mode 100644
index 0000000000..3c740b7ca1
--- /dev/null
+++ b/doc/source/admin/identity-management.rst
@@ -0,0 +1,31 @@
+.. _identity_management:
+
+====================
+Administrator Guides
+====================
+
+OpenStack Identity, code-named keystone, is the default Identity
+management system for OpenStack. After you install Identity, you
+configure it through the ``/etc/keystone/keystone.conf``
+configuration file and, possibly, a separate logging configuration
+file. You initialize data into Identity by using the ``keystone``
+command-line client.
+
+.. toctree::
+ :maxdepth: 1
+
+ identity-concepts.rst
+ identity-certificates-for-pki.rst
+ identity-domain-specific-config.rst
+ identity-external-authentication.rst
+ identity-integrate-with-ldap.rst
+ identity-tokens.rst
+ identity-token-binding.rst
+ identity-fernet-token-faq.rst
+ identity-use-trusts.rst
+ identity-caching-layer.rst
+ identity-security-compliance.rst
+ identity-keystone-usage-and-features.rst
+ identity-auth-token-middleware.rst
+ identity-service-api-protection.rst
+ identity-troubleshoot.rst
diff --git a/doc/source/admin/identity-security-compliance.rst b/doc/source/admin/identity-security-compliance.rst
new file mode 100644
index 0000000000..aefce53928
--- /dev/null
+++ b/doc/source/admin/identity-security-compliance.rst
@@ -0,0 +1,167 @@
+.. _identity_security_compliance:
+
+===============================
+Security compliance and PCI-DSS
+===============================
+
+As of the Newton release, the Identity service contains additional security
+compliance features, specifically to satisfy Payment Card Industry -
+Data Security Standard (PCI-DSS) v3.1 requirements. See
+`Security Hardening PCI-DSS`_ for more information on PCI-DSS.
+
+Security compliance features are disabled by default and most of the features
+only apply to the SQL backend for the identity driver. Other identity backends,
+such as LDAP, should implement their own security controls.
+
+Enable these features by changing the configuration settings under the
+``[security_compliance]`` section in ``keystone.conf``.
+
+Setting the account lockout threshold
+-------------------------------------
+
+The account lockout feature limits the number of incorrect password attempts.
+If a user fails to authenticate after the maximum number of attempts, the
+service disables the user. Re-enable the user by explicitly setting the
+enable user attribute with the update user API call, either
+`v2.0`_ or `v3`_.
+
+You set the maximum number of failed authentication attempts by setting
+the ``lockout_failure_attempts``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ lockout_failure_attempts = 6
+
+You set the number of minutes a user would be locked out by setting
+the ``lockout_duration`` in seconds:
+
+.. code-block:: ini
+
+ [security_compliance]
+ lockout_duration = 1800
+
+If you do not set the ``lockout_duration``, users may be locked out
+indefinitely until the user is explicitly enabled via the API.
+
+Disabling inactive users
+------------------------
+
+PCI-DSS 8.1.4 requires that inactive user accounts be removed or disabled
+within 90 days. You can achieve this by setting the
+``disable_user_account_days_inactive``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ disable_user_account_days_inactive = 90
+
+This above example means that users that have not authenticated (inactive) for
+the past 90 days are automatically disabled. Users can be re-enabled by
+explicitly setting the enable user attribute via the API.
+
+Configuring password expiration
+-------------------------------
+
+Passwords can be configured to expire within a certain number of days by
+setting the ``password_expires_days``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ password_expires_days = 90
+
+Once set, any new password changes have an expiration date based on the
+date/time of the password change plus the number of days defined here. Existing
+passwords will not be impacted. If you want existing passwords to have an
+expiration date, you would need to run a SQL script against the password table
+in the database to update the expires_at column.
+
+In addition, you can set it so that passwords never expire for some users by
+adding their user ID to ``password_expires_ignore_user_ids`` list:
+
+.. code-block:: ini
+
+ [security_compliance]
+ password_expires_ignore_user_ids = [3a54353c9dcc44f690975ea768512f6a]
+
+In this example, the password for user ID ``3a54353c9dcc44f690975ea768512f6a``
+would never expire.
+
+Indicating password strength requirements
+-----------------------------------------
+
+You set password strength requirements, such as requiring numbers in passwords
+or setting a minimum password length, by adding a regular expression to the
+``password_regex``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ password_regex = ^(?=.*\d)(?=.*[a-zA-Z]).{7,}$
+
+The above example is a regular expression that requires a password to have
+one letter, one digit, and a minimum length of seven characters.
+
+If you do set the ``password_regex``, you should provide text that
+describes your password strength requirements. You can do this by setting the
+``password_regex_description``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ password_regex_description = Passwords must contain at least 1 letter, 1
+ digit, and be a minimum length of 7
+ characters.
+
+The service returns that description to users to explain why their requested
+password did not meet requirements.
+
+.. note::
+
+ You must ensure the ``password_regex_description`` accurately and
+ completely describes the ``password_regex``. If the two options are out of
+ sync, the help text could inaccurately describe the password requirements
+ being applied to the password. This would lead to poor user experience.
+
+Requiring a unique password history
+-----------------------------------
+
+The password history requirements controls the number of passwords for a user
+that must be unique before an old password can be reused. You can enforce this
+by setting the ``unique_last_password_count``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ unique_last_password_count= 5
+
+The above example does not allow a user to create a new password that is the
+same as any of their last four previous passwords.
+
+Similarly, you can set the number of days that a password must be used before
+the user can change it by setting the ``minimum_password_age``:
+
+.. code-block:: ini
+
+ [security_compliance]
+ minimum_password_age = 1
+
+In the above example, once a user changes their password, they would not be
+able to change it again for one day. This prevents users from changing their
+passwords immediately in order to wipe out their password history and reuse an
+old password.
+
+.. note::
+
+ When you set ``password_expires_days``, the value for the
+ ``minimum_password_age`` should be less than the ``password_expires_days``.
+ Otherwise, users would not be able to change their passwords before they
+ expire.
+
+.. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html
+
+
+.. _v2.0: https://developer.openstack.org/api-ref/identity/v2-admin/index.html?expanded=update-user-admin-endpoint-detail#update-user-admin-endpoint
+
+.. _v3: https://developer.openstack.org/api-ref/identity/v3/index.html#update-user
diff --git a/doc/source/admin/identity-service-api-protection.rst b/doc/source/admin/identity-service-api-protection.rst
new file mode 100644
index 0000000000..99e181ad1b
--- /dev/null
+++ b/doc/source/admin/identity-service-api-protection.rst
@@ -0,0 +1,128 @@
+=============================================================
+Identity API protection with role-based access control (RBAC)
+=============================================================
+
+Like most OpenStack projects, Identity supports the protection of its
+APIs by defining policy rules based on an RBAC approach. Identity stores
+a reference to a policy JSON file in the main Identity configuration
+file, ``/etc/keystone/keystone.conf``. Typically this file is named
+``policy.json``, and contains the rules for which roles have access to
+certain actions in defined services.
+
+Each Identity API v3 call has a line in the policy file that dictates
+which level of governance of access applies.
+
+.. code-block:: none
+
+ API_NAME: RULE_STATEMENT or MATCH_STATEMENT
+
+Where:
+
+``RULE_STATEMENT`` can contain ``RULE_STATEMENT`` or
+``MATCH_STATEMENT``.
+
+``MATCH_STATEMENT`` is a set of identifiers that must match between the
+token provided by the caller of the API and the parameters or target
+entities of the API call in question. For example:
+
+.. code-block:: none
+
+ "identity:create_user": "role:admin and domain_id:%(user.domain_id)s"
+
+Indicates that to create a user, you must have the admin role in your
+token. The ``domain_id`` in your token must match the
+``domain_id`` in the user object that you are trying
+to create, which implies this must be a domain-scoped token.
+In other words, you must have the admin role on the domain
+in which you are creating the user, and the token that you use
+must be scoped to that domain.
+
+Each component of a match statement uses this format:
+
+.. code-block:: none
+
+ ATTRIB_FROM_TOKEN:CONSTANT or ATTRIB_RELATED_TO_API_CALL
+
+The Identity service expects these attributes:
+
+Attributes from token:
+
+- ``user_id``
+- ``domain_id``
+- ``project_id``
+
+The ``project_id`` attribute requirement depends on the scope, and the
+list of roles you have within that scope.
+
+Attributes related to API call:
+
+- ``user.domain_id``
+- Any parameters passed into the API call
+- Any filters specified in the query string
+
+You reference attributes of objects passed with an object.attribute
+syntax (such as, ``user.domain_id``). The target objects of an API are
+also available using a target.object.attribute syntax. For instance:
+
+.. code-block:: none
+
+ "identity:delete_user": "role:admin and domain_id:%(target.user.domain_id)s"
+
+would ensure that Identity only deletes the user object in the same
+domain as the provided token.
+
+Every target object has an ``id`` and a ``name`` available as
+``target.OBJECT.id`` and ``target.OBJECT.name``. Identity retrieves
+other attributes from the database, and the attributes vary between
+object types. The Identity service filters out some database fields,
+such as user passwords.
+
+List of object attributes:
+
+.. code-block:: yaml
+
+ role:
+ target.role.id
+ target.role.name
+
+ user:
+ target.user.default_project_id
+ target.user.description
+ target.user.domain_id
+ target.user.enabled
+ target.user.id
+ target.user.name
+
+ group:
+ target.group.description
+ target.group.domain_id
+ target.group.id
+ target.group.name
+
+ domain:
+ target.domain.enabled
+ target.domain.id
+ target.domain.name
+
+ project:
+ target.project.description
+ target.project.domain_id
+ target.project.enabled
+ target.project.id
+ target.project.name
+
+The default ``policy.json`` file supplied provides a somewhat
+basic example of API protection, and does not assume any particular
+use of domains. Refer to ``policy.v3cloudsample.json`` as an
+example of multi-domain configuration installations where a cloud
+provider wants to delegate administration of the contents of a domain
+to a particular ``admin domain``. This example policy file also
+shows the use of an ``admin_domain`` to allow a cloud provider to
+enable administrators to have wider access across the APIs.
+
+A clean installation could start with the standard policy file, to
+allow creation of the ``admin_domain`` with the first users within
+it. You could then obtain the ``domain_id`` of the admin domain,
+paste the ID into a modified version of
+``policy.v3cloudsample.json``, and then enable it as the main
+``policy file``.
diff --git a/doc/source/admin/identity-token-binding.rst b/doc/source/admin/identity-token-binding.rst
new file mode 100644
index 0000000000..82a7c837ba
--- /dev/null
+++ b/doc/source/admin/identity-token-binding.rst
@@ -0,0 +1,64 @@
+============================================
+Configure Identity service for token binding
+============================================
+
+Token binding embeds information from an external authentication
+mechanism, such as a Kerberos server or X.509 certificate, inside a
+token. By using token binding, a client can enforce the use of a
+specified external authentication mechanism with the token. This
+additional security mechanism ensures that if a token is stolen, for
+example, it is not usable without external authentication.
+
+You configure the authentication types for a token binding in the
+``/etc/keystone/keystone.conf`` file:
+
+.. code-block:: ini
+
+ [token]
+ bind = kerberos
+
+or
+
+.. code-block:: ini
+
+ [token]
+ bind = x509
+
+Currently ``kerberos`` and ``x509`` are supported.
+
+To enforce checking of token binding, set the ``enforce_token_bind``
+option to one of these modes:
+
+- ``disabled``
+ Disables token bind checking.
+
+- ``permissive``
+ Enables bind checking. If a token is bound to an unknown
+ authentication mechanism, the server ignores it. The default is this
+ mode.
+
+- ``strict``
+ Enables bind checking. If a token is bound to an unknown
+ authentication mechanism, the server rejects it.
+
+- ``required``
+ Enables bind checking. Requires use of at least authentication
+ mechanism for tokens.
+
+- ``kerberos``
+ Enables bind checking. Requires use of kerberos as the authentication
+ mechanism for tokens:
+
+ .. code-block:: ini
+
+ [token]
+ enforce_token_bind = kerberos
+
+- ``x509``
+ Enables bind checking. Requires use of X.509 as the authentication
+ mechanism for tokens:
+
+ .. code-block:: ini
+
+ [token]
+ enforce_token_bind = x509
diff --git a/doc/source/admin/identity-tokens.rst b/doc/source/admin/identity-tokens.rst
new file mode 100644
index 0000000000..2932fb3249
--- /dev/null
+++ b/doc/source/admin/identity-tokens.rst
@@ -0,0 +1,108 @@
+===============
+Keystone tokens
+===============
+
+Tokens are used to authenticate and authorize your interactions with the
+various OpenStack APIs. Tokens come in many flavors, representing various
+authorization scopes and sources of identity. There are also several different
+"token providers", each with their own user experience, performance, and
+deployment characteristics.
+
+Authorization scopes
+--------------------
+
+Tokens can express your authorization in different scopes. You likely have
+different sets of roles, in different projects, and in different domains.
+While tokens always express your identity, they may only ever express one set
+of roles in one authorization scope at a time.
+
+Each level of authorization scope is useful for certain types of operations in
+certain OpenStack services, and are not interchangeable.
+
+Unscoped tokens
+~~~~~~~~~~~~~~~
+
+An unscoped token contains neither a service catalog, any roles, a project
+scope, nor a domain scope. Their primary use case is simply to prove your
+identity to keystone at a later time (usually to generate scoped tokens),
+without repeatedly presenting your original credentials.
+
+The following conditions must be met to receive an unscoped token:
+
+* You must not specify an authorization scope in your authentication request
+ (for example, on the command line with arguments such as
+ ``--os-project-name`` or ``--os-domain-id``),
+
+* Your identity must not have a "default project" associated with it that you
+ also have role assignments, and thus authorization, upon.
+
+Project-scoped tokens
+~~~~~~~~~~~~~~~~~~~~~
+
+Project-scoped tokens are the bread and butter of OpenStack. They express your
+authorization to operate in a specific tenancy of the cloud and are useful to
+authenticate yourself when working with most other services.
+
+They contain a service catalog, a set of roles, and details of the project upon
+which you have authorization.
+
+Domain-scoped tokens
+~~~~~~~~~~~~~~~~~~~~
+
+Domain-scoped tokens also have limited use cases in OpenStack. They express
+your authorization to operate a domain-level, above that of the user and
+projects contained therein (typically as a domain-level administrator).
+Depending on Keystone's configuration, they are useful for working with a
+single domain in Keystone.
+
+They contain a limited service catalog (only those services which do not
+explicitly require per-project endpoints), a set of roles, and details of the
+project upon which you have authorization.
+
+They can also be used to work with domain-level concerns in other services,
+such as to configure domain-wide quotas that apply to all users or projects in
+a specific domain.
+
+Token providers
+---------------
+
+The token type issued by keystone is configurable through the
+``/etc/keystone/keystone.conf`` file. Currently, there are four supported
+token types and they include ``UUID``, ``fernet``, ``PKI``, and ``PKIZ``.
+
+UUID tokens
+~~~~~~~~~~~
+
+UUID was the first token type supported and is currently the default token
+provider. UUID tokens are 32 bytes in length and must be persisted in a back
+end. Clients must pass their UUID token to the Identity service in order to
+validate it.
+
+Fernet tokens
+~~~~~~~~~~~~~
+
+The fernet token format was introduced in the OpenStack Kilo release. Unlike
+the other token types mentioned in this document, fernet tokens do not need to
+be persisted in a back end. ``AES256`` encryption is used to protect the
+information stored in the token and integrity is verified with a ``SHA256
+HMAC`` signature. Only the Identity service should have access to the keys used
+to encrypt and decrypt fernet tokens. Like UUID tokens, fernet tokens must be
+passed back to the Identity service in order to validate them. For more
+information on the fernet token type, see the :doc:`identity-fernet-token-faq`.
+
+PKI and PKIZ tokens
+~~~~~~~~~~~~~~~~~~~
+
+PKI tokens are signed documents that contain the authentication context, as
+well as the service catalog. Depending on the size of the OpenStack deployment,
+these tokens can be very long. The Identity service uses public/private key
+pairs and certificates in order to create and validate PKI tokens.
+
+The same concepts from PKI tokens apply to PKIZ tokens. The only difference
+between the two is PKIZ tokens are compressed to help mitigate the size issues
+of PKI. For more information on the certificate setup for PKI and PKIZ tokens,
+see the :doc:`identity-certificates-for-pki`.
+
+.. note::
+
+ PKI and PKIZ tokens are deprecated and not supported in Ocata.
diff --git a/doc/source/admin/identity-troubleshoot.rst b/doc/source/admin/identity-troubleshoot.rst
new file mode 100644
index 0000000000..f8971ef52d
--- /dev/null
+++ b/doc/source/admin/identity-troubleshoot.rst
@@ -0,0 +1,199 @@
+=================================
+Troubleshoot the Identity service
+=================================
+
+To troubleshoot the Identity service, review the logs in the
+``/var/log/keystone/keystone.log`` file.
+
+Use the ``/etc/keystone/logging.conf`` file to configure the
+location of log files.
+
+.. note::
+
+ The ``insecure_debug`` flag is unique to the Identity service.
+ If you enable ``insecure_debug``, error messages from the API change
+ to return security-sensitive information. For example, the error message
+ on failed authentication includes information on why your authentication
+ failed.
+
+The logs show the components that have come in to the WSGI request, and
+ideally show an error that explains why an authorization request failed.
+If you do not see the request in the logs, run keystone with the
+``--debug`` parameter. Pass the ``--debug`` parameter before the
+command parameters.
+
+Debug PKI middleware
+~~~~~~~~~~~~~~~~~~~~
+
+Problem
+-------
+
+If you receive an ``Invalid OpenStack Identity Credentials`` message when
+you accessing and reaching an OpenStack service, it might be caused by
+the changeover from UUID tokens to PKI tokens in the Grizzly release.
+
+The PKI-based token validation scheme relies on certificates from
+Identity that are fetched through HTTP and stored in a local directory.
+The location for this directory is specified by the ``signing_dir``
+configuration option.
+
+Solution
+--------
+
+In your services configuration file, look for a section like this:
+
+.. code-block:: ini
+
+ [keystone_authtoken]
+ signing_dir = /var/cache/glance/api
+ auth_uri = http://controller:5000/v2.0
+ identity_uri = http://controller:35357
+ admin_tenant_name = service
+ admin_user = glance
+
+The first thing to check is that the ``signing_dir`` does, in fact,
+exist. If it does, check for certificate files:
+
+.. code-block:: console
+
+ $ ls -la /var/cache/glance/api/
+
+ total 24
+ drwx------. 2 ayoung root 4096 Jul 22 10:58 .
+ drwxr-xr-x. 4 root root 4096 Nov 7 2012 ..
+ -rw-r-----. 1 ayoung ayoung 1424 Jul 22 10:58 cacert.pem
+ -rw-r-----. 1 ayoung ayoung 15 Jul 22 10:58 revoked.pem
+ -rw-r-----. 1 ayoung ayoung 4518 Jul 22 10:58 signing_cert.pem
+
+This directory contains two certificates and the token revocation list.
+If these files are not present, your service cannot fetch them from
+Identity. To troubleshoot, try to talk to Identity to make sure it
+correctly serves files, as follows:
+
+.. code-block:: console
+
+ $ curl http://localhost:35357/v2.0/certificates/signing
+
+This command fetches the signing certificate:
+
+.. code-block:: yaml
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, ST=Unset, L=Unset, O=Unset, CN=www.example.com
+ Validity
+ Not Before: Jul 22 14:57:31 2013 GMT
+ Not After : Jul 20 14:57:31 2023 GMT
+ Subject: C=US, ST=Unset, O=Unset, CN=www.example.com
+
+Note the expiration dates of the certificate:
+
+.. code-block:: console
+
+ Not Before: Jul 22 14:57:31 2013 GMT
+ Not After : Jul 20 14:57:31 2023 GMT
+
+The token revocation list is updated once a minute, but the certificates
+are not. One possible problem is that the certificates are the wrong
+files or garbage. You can remove these files and run another command
+against your server; they are fetched on demand.
+
+The Identity service log should show the access of the certificate files. You
+might have to turn up your logging levels. Set ``debug = True`` in your
+Identity configuration file and restart the Identity server.
+
+.. code-block:: console
+
+ (keystone.common.wsgi): 2013-07-24 12:18:11,461 DEBUG wsgi __call__
+ arg_dict: {}
+ (access): 2013-07-24 12:18:11,462 INFO core __call__ 127.0.0.1 - - [24/Jul/2013:16:18:11 +0000]
+ "GET http://localhost:35357/v2.0/certificates/signing HTTP/1.0" 200 4518
+
+If the files do not appear in your directory after this, it is likely
+one of the following issues:
+
+* Your service is configured incorrectly and cannot talk to Identity.
+ Check the ``auth_port`` and ``auth_host`` values and make sure that
+ you can talk to that service through cURL, as shown previously.
+
+* Your signing directory is not writable. Use the ``chmod`` command to
+ change its permissions so that the service (POSIX) user can write to
+ it. Verify the change through ``su`` and ``touch`` commands.
+
+* The SELinux policy is denying access to the directory.
+
+SELinux troubles often occur when you use Fedora or RHEL-based packages and
+you choose configuration options that do not match the standard policy.
+Run the ``setenforce permissive`` command. If that makes a difference,
+you should relabel the directory. If you are using a sub-directory of
+the ``/var/cache/`` directory, run the following command:
+
+.. code-block:: console
+
+ # restorecon /var/cache/
+
+If you are not using a ``/var/cache`` sub-directory, you should. Modify
+the ``signing_dir`` configuration option for your service and restart.
+
+Set back to ``setenforce enforcing`` to confirm that your changes solve
+the problem.
+
+If your certificates are fetched on demand, the PKI validation is
+working properly. Most likely, the token from Identity is not valid for
+the operation you are attempting to perform, and your user needs a
+different role for the operation.
+
+Debug signing key file errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Problem
+-------
+
+If an error occurs when the signing key file opens, it is possible that
+the person who ran the :command:`keystone-manage pki_setup` command to
+generate certificates and keys did not use the correct user.
+
+Solution
+--------
+
+When you run the :command:`keystone-manage pki_setup` command, Identity
+generates a set of certificates and keys in ``/etc/keystone/ssl*``, which
+is owned by ``root:root``. This can present a problem when you run the
+Identity daemon under the keystone user account (nologin) when you try
+to run PKI. Unless you run the :command:`chown` command against the
+files ``keystone:keystone``, or run the :command:`keystone-manage pki_setup`
+command with the ``--keystone-user`` and
+``--keystone-group`` parameters, you will get an error.
+For example:
+
+.. code-block:: console
+
+ 2012-07-31 11:10:53 ERROR [keystone.common.cms] Error opening signing key file
+ /etc/keystone/ssl/private/signing_key.pem
+ 140380567730016:error:0200100D:system library:fopen:Permission
+ denied:bss_file.c:398:fopen('/etc/keystone/ssl/private/signing_key.pem','r')
+ 140380567730016:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400:
+ unable to load signing key file
+
+Flush expired tokens from the token database table
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Problem
+-------
+
+As you generate tokens, the token database table on the Identity server
+grows.
+
+Solution
+--------
+
+To clear the token table, an administrative user must run the
+:command:`keystone-manage token_flush` command to flush the tokens. When you
+flush tokens, expired tokens are deleted and traceability is eliminated.
+
+Use ``cron`` to schedule this command to run frequently based on your
+workload. For large workloads, running it every minute is recommended.
+
diff --git a/doc/source/admin/identity-use-trusts.rst b/doc/source/admin/identity-use-trusts.rst
new file mode 100644
index 0000000000..077e2e993c
--- /dev/null
+++ b/doc/source/admin/identity-use-trusts.rst
@@ -0,0 +1,56 @@
+==========
+Use trusts
+==========
+
+OpenStack Identity manages authentication and authorization. A trust is
+an OpenStack Identity extension that enables delegation and, optionally,
+impersonation through ``keystone``. A trust extension defines a
+relationship between:
+
+**Trustor**
+ The user delegating a limited set of their own rights to another user.
+
+**Trustee**
+ The user trust is being delegated to, for a limited time.
+
+ The trust can eventually allow the trustee to impersonate the trustor.
+ For security reasons, some safeties are added. For example, if a trustor
+ loses a given role, any trusts the user issued with that role, and the
+ related tokens, are automatically revoked.
+
+The delegation parameters are:
+
+**User ID**
+ The user IDs for the trustor and trustee.
+
+**Privileges**
+ The delegated privileges are a combination of a project ID and a
+ number of roles that must be a subset of the roles assigned to the
+ trustor.
+
+ If you omit all privileges, nothing is delegated. You cannot
+ delegate everything.
+
+**Delegation depth**
+ Defines whether or not the delegation is recursive. If it is
+ recursive, defines the delegation chain length.
+
+ Specify one of the following values:
+
+ - ``0``. The delegate cannot delegate these permissions further.
+
+ - ``1``. The delegate can delegate the permissions to any set of
+ delegates but the latter cannot delegate further.
+
+ - ``inf``. The delegation is infinitely recursive.
+
+**Endpoints**
+ A list of endpoints associated with the delegation.
+
+ This parameter further restricts the delegation to the specified
+ endpoints only. If you omit the endpoints, the delegation is
+ useless. A special value of ``all_endpoints`` allows the trust to be
+ used by all endpoints associated with the delegated project.
+
+**Duration**
+ (Optional) Comprised of the start time and end time for the trust.
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 1147fbbc2a..75951f43c1 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -85,6 +85,14 @@ the keystone service.
advanced-topics/index.rst
sample_files/index.rst
+Administrator Guides
+~~~~~~~~~~~~~~~~~~~~
+
+.. toctree::
+ :maxdepth: 2
+
+ admin/identity-management.rst
+
API Documentation
~~~~~~~~~~~~~~~~~
An end user can find the specific API documentation here, `OpenStack's Identity API`_.