Add JWS token provider documentation

Add documentation that advertise support for JWS tokens.

bp json-web-tokens

Change-Id: If1700c53674ad98b54f572a73b5d4350c7837ab6
This commit is contained in:
Lance Bragstad 2019-01-29 21:35:53 +00:00 committed by Morgan Fainberg
parent 96adccd0ec
commit 950e7d1f6d
6 changed files with 139 additions and 2 deletions

View File

@ -0,0 +1,72 @@
================
JWS key rotation
================
The JWS token provider issues tokens using asymmetric signing. This document
attempts to describe how to manage key pairs in a deployment of keystone nodes
that need to validate tokens issued by one another.
The inherent benefit of using asymmetric keys is that each keystone server
generates it's own key pair. The private key is used to sign tokens. Anyone
with access to the public key has the ability to verify the token signature.
This is a critical step in validating tokens across a cluster of keystone
nodes.
It is necessary for operators to sync public keys across all keystone nodes in
the deployment. Each keystone server will need a corresponding public key for
every node. This only applies to public keys. Private keys should never leave
the server they are generated from.
Initial setup
-------------
Before a deployment of keystone servers can issue JWT tokens, each server must
set ``keystone.conf [token] provider = jws``. Additionally, each API server
must have its own asymmetric key pair either generated manually or using
``keystone-manage create_jws_keypair``. If you're generating the key pairs
manually, they must be usable with the ``ES256`` JSON Web Algorithm (`JWA`_). It
is worth noting that the ``keystone-manage create_jws_keypair`` command line
utility will create an appropriate key pair, but it will not automatically
deploy it to the key repository locations defined in ``keystone.conf
[jwt_tokens]``. It is up to operators to move these files accordingly and
resolve possible file name conflicts.
After generating a key pair, the public key from each API server must be shared
with every other API server in the deployment. Ensure the private key used to
sign JWS tokens is readable by the process running keystone and available in
the ``keystone.conf [jwt_tokens] jws_private_key_repository`` location.
Keystone will automatically use a key named ``private.pem`` to sign tokens and
ignore all other keys in the repository. To validate tokens, keystone will
iterate all available public keys in ``keystone.conf [jwt_tokens]
jws_public_key_repository``. At a minimum, this repository needs to have the
corresponding public key to the ``private.pem`` key found in ``keystone.conf
[jwt_tokens] jws_private_key_repository``.
.. _`JWA`: https://tools.ietf.org/html/rfc7518
Continued operations
--------------------
Depending on the security requirements for your deployment, you might need to
rotate out an existing key pair. To do so without prematurely invalidating
tokens, follow these steps:
1. Generate a new asymmetric key pair for a given keystone API server (see
``keystone-manage create_jws_keypair`` for more details)
2. Copy or sync the newly generated public key to the public key repositories
of all other keystone API servers, the public key should be placed in
``keystone.conf [jwt_tokens] jws_public_key_repository``
3. Copy the new private key to the private key repository on the API server
you're performing the rotation on and make sure it's named ``private.pem``,
at this point the server will start signing tokens with the new private key
and all other keystone API servers will be able to validate those tokens
since they already have a copy of the public key from step #2
4. At this point, you must wait until the last tokens signed with the old
private key have expired before you can remove the old corresponding public
keys from each keystone API server, note this should be a minimum of
``keystone.conf [token] expiration``
5. Once you're confident all tokens signed with the old private key are
expired, it is safe to remove the old corresponding public key from each API
server in the deployment, which is important in case the original private
key was compromised and prevents attackers from using it craft their own
tokens

View File

@ -31,3 +31,16 @@ Fernet
Fernet tokens are bearer tokens. They must be protected from unnecessary
disclosure to prevent unauthorized access.
JWS
``jws`` tokens do not need to be persisted at all, but require that you
configure an asymmetric key pair to sign and validate tokens. The key pair can
be generated using ``keystone-manage create_jws_keypair`` or it can be
generated out-of-band manually so long as it is compatible with the JWT
``ES256`` Elliptic Curve Digital Signature Algorithm (ECDSA) using a P-256
curve and a SHA-256 hash algorithm.
.. warning::
JWS tokens are bearer tokens. They must be protected from unnecessary
disclosure to prevent unauthorized access.

View File

@ -56,6 +56,7 @@
# drivers should maintain their own equivalent document, and merge it with this
# when their code merges into core.
driver-impl-fernet=Fernet tokens
driver-impl-jws=JWS tokens
[operation.create_unscoped_token]
title=Create unscoped token
@ -65,6 +66,7 @@ notes=All token providers must be capable of issuing tokens without an explicit
cli=openstack --os-username=<username> --os-user-domain-name=<domain>
--os-password=<password> token issue
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.create_system_token]
title=Create system-scoped token
@ -73,6 +75,7 @@ notes=All token providers must be capable of issuing system-scoped tokens.
cli=openstack --os-username=<username> --os-user-domain-name=<domain>
--os-system-scope all token issue
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.create_project_scoped_token]
title=Create project-scoped token
@ -82,6 +85,7 @@ cli=openstack --os-username=<username> --os-user-domain-name=<domain>
--os-password=<password> --os-project-name=<project>
--os-project-domain-name=<domain> token issue
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.create_domain_scoped_token]
title=Create domain-scoped token
@ -91,6 +95,7 @@ notes=Domain-scoped tokens are not required for all use cases, and for some use
cli=openstack --os-username=<username> --os-user-domain-name=<domain>
--os-password=<password> --os-domain-name=<domain> token issue
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.create_trust_scoped_token]
title=Create trust-scoped token
@ -100,6 +105,7 @@ notes=Tokens scoped to a trust convey only the user impersonation and
cli=openstack --os-username=<username> --os-user-domain-name=<domain>
--os-password=<password> --os-trust-id=<trust> token issue
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.create_token_using_oauth]
title=Create a token given an OAuth access token
@ -107,6 +113,7 @@ status=optional
notes=OAuth access tokens can be exchanged for keystone tokens.
cli=
driver-impl-fernet=complete
driver-impl-jws=complete
[operation.revoke_token]
title=Revoke a token
@ -117,6 +124,7 @@ notes=Tokens may be individually revoked, such as when a user logs out of
revoked token was previously used to create additional tokens).
cli=openstack token revoke
driver-impl-fernet=complete
driver-impl-jws=complete
[feature.online_validation]
title=Online validation
@ -125,6 +133,7 @@ notes=Keystone must be able to validate the tokens that it issues when
presented with a token that it previously issued.
cli=
driver-impl-fernet=complete
driver-impl-jws=complete
[feature.offline_validation]
title=Offline validation
@ -134,6 +143,7 @@ notes=Services using Keystone for authentication may want to validate tokens
performance and scalability.
cli=
driver-impl-fernet=missing
driver-impl-jws=missing
[feature.non_persistent]
title=Non-persistent
@ -144,3 +154,4 @@ notes=If a token format does not require persistence (such as to a SQL
operations such as `keystone-manage token_flush`.
cli=
driver-impl-fernet=complete
driver-impl-jws=complete

View File

@ -77,8 +77,8 @@ Token providers
---------------
The token type issued by keystone is configurable through the
``/etc/keystone/keystone.conf`` file. Currently, the only supported token
provider is ``fernet``.
``/etc/keystone/keystone.conf`` file. Currently, there are two supported token
providers, ``fernet`` and ``jws``.
Fernet tokens
~~~~~~~~~~~~~
@ -93,4 +93,36 @@ 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:`fernet-token-faq`.
A deployment might consider using the fernet provider as opposed to JWS tokens
if they are concerned about public expose of the payload used to build tokens.
JWS tokens
~~~~~~~~~~
The JSON Web Signature (JWS) token format is a type of JSON Web Token (JWT) and
it was implemented in the Stein release. JWS tokens are signed, meaning the
information used to build the token ID is not opaque to users and can it can be
decoded by anyone. JWS tokens are ephemeral, or non-persistent, which means
they won't bloat the database or require replication across nodes. Since the
JWS token provider uses asymmetric keys, the tokens are signed with private
keys and validated with public keys. The JWS token provider implementation
only supports the ``ES256`` JSON Web Algorithm (JWA), which is an Elliptic
Curve Digital Signature Algorithm (ECDSA) using the P-256 curve and a SHA-256
hash algorithm.
A deployment might consider using JWS tokens as opposed to fernet tokens if
there are security concerns about sharing symmetric encryption keys across
hosts. Note that a major difference between the two providers is that JWS
tokens are not opaque and can be decoded by anyone with the token ID. Fernet
tokens are opaque in that the token ID is ciphertext. Despite the JWS token
payload being readable by anyone, keystone reserves the right to make backwards
incompatible changes to the token payload itself, which is not an API contract.
We only recommend validating the token against keystone's authentication API to
inspect its associated metadata. We strongly discourage relying on decoded
payloads for information about tokens.
More information about JWTs can be found in the `specification`_.
.. _`specification`: https://tools.ietf.org/html/rfc7519
.. support_matrix:: token-support-matrix.ini

View File

@ -9,4 +9,5 @@ Everything you need to know about keystone tokens.
tokens-overview
fernet-token-faq
jws-key-rotation
token-provider

View File

@ -0,0 +1,8 @@
---
features:
- |
[`blueprint json-web-tokens <https://blueprints.launchpad.net/keystone/+spec/json-web-tokens>`_]
Keystone now supports a JSON Web Signature (JWS) token provider in addition
to fernet tokens. Fernet token remain the default token provider. Full
details can be found in the `specification
<http://specs.openstack.org/openstack/keystone-specs/specs/keystone/stein/json-web-tokens.html>`_.