A Vault secrets engine for generating and validating arbitrary JWTs.
-
Register the plugin via Vault's plugin system
-
Enable the engine:
$ vault secrets enable -path=jwt vault-plugin-secrets-jwt Success! Enabled the vault-plugin-secrets-jwt secrets engine at: jwt/
-
Configure a role. You must specify two fields:
alg
: The signing algorithm to use. Allowed values:RS256
,RS384
,RS512
,HS256
,HS384
,HS512
,ES256
,ES384
,ES512
. This is case-insensitive.exp
: The amount of time before a JWT expires. Unlike in an actual JWT, this is the duration that the JWT should live. This can be either an integer indicating a number of seconds, or use a suffix notation such as1h
If you do not specify the
key
field, a key will be generated automatically by Vault. If you do specify a key, it must match the signing method specified inalg
.You may specify any arbitrary key/value pairs you wish.
$ vault write jwt/roles/myrole/config alg=RS512 exp=1h foo=bar bar=baz Success! Data written to: jwt/roles/myrole/config
-
Generate a JWT
$ vault read jwt/roles/myrole/generate Key Value --- ----- token eyJhbGciOiJSUzUxM <shortened for brevity> oN6s7FfP4NuFc-K1yg
-
Validate a JWT
$ vault write jwt/roles/myrole/validate token="${TOKEN}" Key Value --- ----- claims map[bar:baz exp:1605829718 foo:bar iat:1605826118 iss:vault/myrole jti:34e888e2-22f1-4f96-f22e-8ef1894aed42]
Configures a JWT role. Generates an RSA key by default.
Allows user to specify any key/value pairs to include in the JWT.
When read, only the public key will be returned (or the key redacted if a symmetric key). This is to protect the key from access by users who shouldn't be able to see it. Key-exporting is not supported. If you need the key outside of this engine, generate it and provide it rather than having the engine generate one.
Generates a JWT & returns it as a secret.
Validates a provided JWT against the role specified
- ✅ Certain fields will need to be explicitly specified types:
exp
- Duration (creation + this value => JWT expiration)
- ✅ Validation of key/value pairs against default types
- ✅ Not allowed:
jti
(JWT ID)iat
(Issued At)
- ✅ Defaults:
iss
-"vault/{name}"
where{name}
is the name of the role?
- ✅ Not allowed:
- ✅ Allow user to provide key
- ✅ Generate keys when one isn't provided
- ✅ RSA
- ✅ HMAC
- ✅ ECDSA
- ✅ Supported key types
- ✅ RSA (RS256, RS384, RS512)
- ✅ HMAC (HS256, HS384, HS512)
- ✅ ECDSA (ES256, ES384, ES512)
- ❌ Logging?
- ❌ Key lifecycle
- ❌ Replace an existing key
- ❌ Allow validation with an old key for a configurable amount of time?
- ❌ Allow for time skewing
- This one is potentially problematic with the library I'm using here since it is configured with a global TimeFunc variable.
- Allow generation-time claims?
nbf
comes to mind, but possibly allow other fields? This would allow JWTs to be configurable during generation. We would probably need to have some protections that the operator can specify on what fields can be specified & maybe what values in each field can be used. - Allow users to invalidate specific JWTs based on the JWT ID field (
jti
) - An endpoint that returns the role name of the provided JWT
- Templating within fields. Ex:
{.RoleName}
for the name of the role in Vault