diff --git a/doc/source/api_curl_examples.rst b/doc/source/api_curl_examples.rst index 9ad16156da..450e91cf58 100644 --- a/doc/source/api_curl_examples.rst +++ b/doc/source/api_curl_examples.rst @@ -22,6 +22,13 @@ API Examples using Curl v3 API Examples Using Curl -------------------------- +.. note:: + + Following are some API examples using curl. Note that these examples are not + automatically generated. They can be outdated as things change and are subject + to regular updates and changes. + + GET / ===== diff --git a/doc/source/user/application_credentials.rst b/doc/source/user/application_credentials.rst new file mode 100644 index 0000000000..422329efde --- /dev/null +++ b/doc/source/user/application_credentials.rst @@ -0,0 +1,252 @@ +.. + Copyright 2018 SUSE Linux GmbH + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +======================= +Application Credentials +======================= + +Users can create application credentials to allow their applications to +authenticate to keystone. Users can delegate a subset of their role assignments +on a project to an application credential, granting the application the same or +restricted authorization to a project. With application credentials, +applications authenticate with the application credential ID and a secret string +which is not the user's password. This way, the user's password is not embedded +in the application's configuration, which is especially important for users +whose identities are managed by an external system such as LDAP or a +single-signon system. + +See the `Identity API reference`_ for more information on authenticating with +and managing application credentials. + +.. _`Identity API reference`: https://developer.openstack.org/api-ref/identity/v3/index.html#application-credentials + +Managing Application Credentials +================================ + +Create an application credential using python-keystoneclient: + +.. code-block:: python + + >>> keystone = client.Client(session=mysession) + >>> app_cred = keystone.application_credentials.create( + ... name='monitoring' + ... ) + >>> pprint.pprint(app_cred.to_dict()) + {u'description': None, + u'expires_at': None, + u'id': u'aa809205ed614a0e854bac92c0768bb9', + u'links': {u'self': u'http://192.168.122.247/identity/v3/users/1d1b5c244ee64c6e9356947322570120/application_credentials/aa809205ed614a0e854bac92c0768bb9'}, + u'name': u'monitoring', + u'project_id': u'73cd55a3f3f7446d8256889339e7f02f', + u'roles': [{u'domain_id': None, + u'id': u'cdfd5fd0b0844bfa81b177a986e31063', + u'name': u'Member'}, + {u'domain_id': None, + u'id': u'e82e7f3ad839443ab4d1ead88a8c267d', + u'name': u'anotherrole'}], + u'secret': u'oKce6DOC_WcZoE13l3eXspfxhjO0VlO2n5SG_XNdXVZTDZVFF163a5p03pei56DhJxkd62x-zX-hEQ8VyWmYnA', + u'unrestricted': False} + +The only required parameter is a name. The application credential is created for +the project to which the user is currently scoped with the same role assignments +the user has on that project. Keystone will automatically generate a secret +string that will be revealed once at creation time. You can also provide your +own secret, if desired: + +.. code-block:: python + + >>> keystone = client.Client(session=mysession) + >>> app_cred = keystone.application_credentials.create( + ... name='monitoring', + ... secret='securesecret' + ... ) + >>> pprint.pprint(app_cred.to_dict()) + {u'description': None, + u'expires_at': None, + u'id': u'63022d09c923497887f44d33b1ab61e8', + u'links': {u'self': u'http://192.168.122.247/identity/v3/users/1d1b5c244ee64c6e9356947322570120/application_credentials/63022d09c923497887f44d33b1ab61e8'}, + u'name': u'monitoring', + u'project_id': u'73cd55a3f3f7446d8256889339e7f02f', + u'roles': [{u'domain_id': None, + u'id': u'e82e7f3ad839443ab4d1ead88a8c267d', + u'name': u'anotherrole'}, + {u'domain_id': None, + u'id': u'cdfd5fd0b0844bfa81b177a986e31063', + u'name': u'Member'}], + u'secret': u'securesecret', + u'unrestricted': False} + +The secret is hashed before it is stored, so the original secret is not +retrievable after creation. If the secret is lost, a new application credential +must be created. + +If none are provided, the application credential is created with the same role +assignments on the project that the user has. You can find out what role +assignments you have on a project by examining your token or your keystoneauth +session: + +.. code-block:: python + + >>> mysession.auth.auth_ref.role_names + [u'anotherrole', u'Member'] + +If you have more than one role assignment on a project, you can grant your +application credential only a subset of your role assignments if desired. This +is useful if you have administrator privileges on a project but only want the +application to have basic membership privileges, or if you have basic membership +privileges but want the application to only have read-only privileges. You +cannot grant the application a role assignment that your user does not already +have; for instance, if you are an admin on a project, and you want your +application to have read-only access to the project, you must acquire a +read-only role assignment on that project yourself before you can delegate it to +the application credential. Removing a user's role assignment on a project will +invalidate the user's application credentials for that project. + +.. code-block:: python + + >>> app_cred = keystone.application_credentials.create( + ... name='monitoring', + ... roles=[{'name': 'Member'}] + ... ) + >>> pprint.pprint(app_cred.to_dict()) + {u'description': None, + u'expires_at': None, + u'id': u'7f293ac53f4e47a6826dc42f6a6a66d9', + u'links': {u'self': u'http://192.168.122.247/identity/v3/users/1d1b5c244ee64c6e9356947322570120/application_credentials/7f293ac53f4e47a6826dc42f6a6a66d9'}, + u'name': u'monitoring', + u'project_id': u'73cd55a3f3f7446d8256889339e7f02f', + u'roles': [{u'domain_id': None, + u'id': u'cdfd5fd0b0844bfa81b177a986e31063', + u'name': u'Member'}], + u'secret': u'6Oq8MrvaaeNb3GRBX79Svj1ALgAJwwbr9ECQYOyTWUidg8yDOgvJL4Yvtnm3p17XND8sYaQVYQPR-M8WdrbPbg', + u'unrestricted': False} + +You can provide an expiration date for application credentials: + +.. code-block:: python + + >>> expires = datetime.datetime.utcnow() + datetime.timedelta(days=365) + >>> app_cred = keystone.application_credentials.create( + ... name='monitoring', + ... expires_at=expires + ... ) + >>> pprint.pprint(app_cred.to_dict()) + {u'description': None, + u'expires_at': u'2019-02-12T20:52:43.895274', + u'id': u'888c5b30428349d7af19d0e9e05229fd', + u'links': {u'self': u'http://192.168.122.247/identity/v3/users/1d1b5c244ee64c6e9356947322570120/application_credentials/888c5b30428349d7af19d0e9e05229fd'}, + u'name': u'monitoring', + u'project_id': u'73cd55a3f3f7446d8256889339e7f02f', + u'roles': [{u'domain_id': None, + u'id': u'e82e7f3ad839443ab4d1ead88a8c267d', + u'name': u'anotherrole'}, + {u'domain_id': None, + u'id': u'cdfd5fd0b0844bfa81b177a986e31063', + u'name': u'Member'}], + u'secret': u'PXyLkmBSz9TbCS4G32kNqQIFpnJx2euFR7RIBmM5g97ZhH8KvECEmCU1BIdmD8NuKrUfh77nugwKjlUbP1mD6g', + u'unrestricted': False} + +By default, application credentials are restricted from creating or deleting +other application credentials and from creating or deleting trusts. If your +application needs to be able to perform these actions and you accept the risks +involved, you can disable this protection: + +.. warning:: + + Restrictions on these Identity operations are deliberately imposed as a + safeguard to prevent a compromised application credential from regenerating + itself. Disabling this restriction poses an inherent added risk. + +.. code-block:: python + + >>> keystone = client.Client(session=mysession) + >>> app_cred = keystone.application_credentials.create( + ... name='monitoring', + ... unrestricted=True + ... ) + >>> pprint.pprint(app_cred.to_dict()) + {u'description': None, + u'expires_at': None, + u'id': u'aa809205ed614a0e854bac92c0768bb9', + u'links': {u'self': u'http://192.168.122.247/identity/v3/users/1d1b5c244ee64c6e9356947322570120/application_credentials/aa809205ed614a0e854bac92c0768bb9'}, + u'name': u'monitoring', + u'project_id': u'73cd55a3f3f7446d8256889339e7f02f', + u'roles': [{u'domain_id': None, + u'id': u'cdfd5fd0b0844bfa81b177a986e31063', + u'name': u'Member'}, + {u'domain_id': None, + u'id': u'e82e7f3ad839443ab4d1ead88a8c267d', + u'name': u'anotherrole'}], + u'secret': u'oKce6DOC_WcZoE13l3eXspfxhjO0VlO2n5SG_XNdXVZTDZVFF163a5p03pei56DhJxkd62x-zX-hEQ8VyWmYnA', + u'unrestricted': True} + +Using Application Credentials +============================= + +Applications can authenticate using the application_credential auth method. For +a service using keystonemiddleware to authenticate with keystone, the +auth section would look like this: + +.. code-block:: ini + + [keystone_authtoken] + auth_url = https://keystone.server/identity/v3 + auth_type = v3applicationcredential + application_credential_id = 6cb5fa6a13184e6fab65ba2108adf50c + application_credential_secret= glance_secret + +You can also identify your application credential with its name and the name or +ID of its owner. For example: + +.. code-block:: ini + + [keystone_authtoken] + auth_url = https://keystone.server/identity/v3 + auth_type = v3applicationcredential + username = glance + user_domain_name = Default + application_credential_name = glance_cred + application_credential_secret = glance_secret + +Rotating Application Credentials +================================ + +A user can create multiple application credentials with the same role +assignments on the same project. This allows the application credential to be +gracefully rotated with minimal or no downtime for your application. In +contrast, changing a service user's password results in immediate downtime for +any application using that password until the application can be updated with +the new password. + +.. note:: + + Rotating application credentials is essential if a team member who has + knowledge of the application credential identifier and secret leaves the team + for any reason. Rotating application credentials is also recommended as part + of regular application maintenance. + +Rotating an application credential is a simple process: + +#. Create a new application credential. Application credential names must be + unique within the user's set of application credentials, so this new + application credential must not have the same name as the old one. + +#. Update your application's configuration to use the new ID (or name and user + identifier) and the new secret. For a distributed application, this can be + done one node at a time. + +#. When your application is fully set up with the new application credential, + delete the old one. diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst index 5e3bf62340..7677e83896 100644 --- a/doc/source/user/index.rst +++ b/doc/source/user/index.rst @@ -22,13 +22,8 @@ An end user can find the specific API documentation here, `OpenStack's Identity .. _`OpenStack's Identity API`: https://developer.openstack.org/api-ref/identity/v3 -.. note:: - - Following are some API examples using curl. Note that these examples are not - automatically generated. They can be outdated as things change and are subject - to regular updates and changes. - .. toctree:: - :maxdepth: 2 + :maxdepth: 1 + application_credentials.rst ../api_curl_examples.rst