Application Credentials

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.

Managing Application Credentials

Create an application credential using python-keystoneclient:

>>> 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:

>>> 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:

>>> 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.

>>> 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:

>>> 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.

>>> 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:

[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:

[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:

  1. 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.
  2. 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.
  3. When your application is fully set up with the new application credential, delete the old one.
Creative Commons Attribution 3.0 License

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.