Consul
JSON Web Token (JWT) Auth Method
1.8.0+: This feature is available in Consul versions 1.8.0 and newer.
The jwt
auth method can be used to authenticate with Consul by providing a
JWT directly. The JWT is
cryptographically verified using locally-provided keys, or, if configured, an
OIDC Discovery service can be used to fetch the appropriate keys.
This page assumes general knowledge of JWTs and the concepts described in the main auth method documentation.
Both the jwt
and the
oidc
auth method types allow additional
processing of the claims data in the JWT.
JWT vs OIDC Auth Methods
Since both the oidc
and jwt
auth methods ultimately operate on JWTs as
bearer tokens, it may be confusing to know which is right for a given use case.
JWT: The user or application performing the Consul login must already be in possession of a valid JWT to begin. There is no browser interaction required. This is ideal for machine-oriented headless login where an operator may have already arranged for a valid JWT to be dropped on a VM or provided to a container.
OIDC: The user performing the Consul login does not have a JWT nor do they even need to know what that means. This is ideal for human-oriented interactive login where an operator or administrator may have deployed SSO widely and doesn't want to have the burden of tracking and distributing Consul ACL tokens to any authorized coworker who may need to have access to a Consul instance. Browser interaction is required. This is only available in Consul Enterprise.
Config Parameters
The following auth method Config
parameters are required to properly configure an auth method of type
jwt
:
JWTValidationPubKeys
(array<string>)
- A list of PEM-encoded public keys to use to authenticate signatures locally.Exactly one of
JWKSURL
JWTValidationPubKeys
, orOIDCDiscoveryURL
is required.OIDCDiscoveryURL
(string: "")
- The OIDC Discovery URL, without any .well-known component (base path).Exactly one of
JWKSURL
JWTValidationPubKeys
, orOIDCDiscoveryURL
is required.OIDCDiscoveryCACert
(string: "")
- PEM encoded CA cert for use by the TLS client used to talk with the OIDC Discovery URL. NOTE: Every line must end with a newline (\n
). If not set, system certificates are used.JWKSURL
(string: "")
- The JWKS URL to use to authenticate signatures.Exactly one of
JWKSURL
JWTValidationPubKeys
, orOIDCDiscoveryURL
is required.JWKSCACert
(string: "")
- PEM encoded CA cert for use by the TLS client used to talk with the JWKS URL. NOTE: Every line must end with a newline (\n
). If not set, system certificates are used.ClaimMappings
(map[string]string)
- Mappings of claims (key) that will be copied to a metadata field (value). Use this if the claim you are capturing is singular (such as an attribute).When mapped, the values can be any of a number, string, or boolean and will all be stringified when returned.
ListClaimMappings
(map[string]string)
- Mappings of claims (key) will be copied to a metadata field (value). Use this if the claim you are capturing is list-like (such as groups).When mapped, the values in each list can be any of a number, string, or boolean and will all be stringified when returned.
JWTSupportedAlgs
(array<string>)
- JWTSupportedAlgs is a list of supported signing algorithms. Defaults toRS256
.BoundAudiences
(array<string>)
- List ofaud
claims that are valid for login; any match is sufficient.BoundIssuer
(string: "")
- The value against which to match theiss
claim in a JWT.ExpirationLeeway
(duration: 0s)
- Duration in seconds of leeway when validating expiration of a token to account for clock skew. Defaults to 150 (2.5 minutes) if set to 0 and can be disabled if set to -1.NotBeforeLeeway
(duration: 0s)
- Duration in seconds of leeway when validating not before values of a token to account for clock skew. Defaults to 150 (2.5 minutes) if set to 0 and can be disabled if set to -1.ClockSkewLeeway
(duration: 0s)
- Duration in seconds of leeway when validating all claims to account for clock skew. Defaults to 60 (1 minute) if set to 0 and can be disabled if set to -1.
Sample Configs
Static Keys
{
"Name": "example-jwt-auth-static-keys",
"Type": "jwt",
"Description": "Example JWT auth method with static keys",
"Config": {
"BoundIssuer": "corp-issuer",
"JWTValidationPubKeys": [
"<public key PEM>"
],
"ClaimMappings": {
"http://example.com/first_name": "first_name",
"http://example.com/last_name": "last_name"
},
"ListClaimMappings": {
"http://example.com/groups": "groups"
}
}
}
JWKS
{
"Name": "example-jwt-auth-jwks",
"Type": "jwt",
"Description": "Example JWT auth method with JWKS",
"Config": {
"JWKSURL": "https://my-corp-jwks-url.example.com/",
"ClaimMappings": {
"http://example.com/first_name": "first_name",
"http://example.com/last_name": "last_name"
},
"ListClaimMappings": {
"http://example.com/groups": "groups"
}
}
}
OIDC Discovery
{
"Name": "example-oidc-auth",
"Type": "oidc",
"Description": "Example OIDC auth method",
"Config": {
"BoundAudiences": [
"V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt"
],
"OIDCDiscoveryURL": "https://my-corp-app-name.auth0.com/",
"ClaimMappings": {
"http://example.com/first_name": "first_name",
"http://example.com/last_name": "last_name"
},
"ListClaimMappings": {
"http://example.com/groups": "groups"
}
}
}
JWT Verification
JWT signatures will be verified against public keys from the issuer. This process can be done one of three ways:
Static Keys - A set of public keys is stored directly in the configuration.
JWKS - A JSON Web Key Set (JWKS) URL (and optional certificate chain) is configured. Keys will be fetched from this endpoint during authentication.
OIDC Discovery - An OIDC Discovery URL (and optional certificate chain) is configured. Keys will be fetched from this URL during authentication. When OIDC Discovery is used, OIDC validation criteria (e.g.
iss
,aud
, etc.) will be applied.
If multiple methods are needed, another auth method of this type may be created with a different name.
Trusted Identity Attributes via Claim Mappings
Data from JWT claims can be returned from the authentication step as trusted identity attributes for use in binding rule selectors and bind name interpolation.
Control of which claims are mapped to which identity attributes is governed by
the ClaimMappings
and
ListClaimMappings
. These are both maps of items to copy
with elements of the form: "<JWT claim>":"<attribute suffix>"
.
The only difference between these two types of mappings is that ClaimMappings
is used to map singular values (such as a name, department, or team) while
ListClaimMappings
is used to map lists of values.
The singular values mapped by ClaimMappings
can be interpolated in a binding
rule, and the lists of values mapped by ListClaimMappings
cannot.
Assume this is your config snippet:
{
"Name": "example-auth-method",
"Type": "<jwt|oidc>",
"Description": "Example auth method",
"Config": {
"ClaimMappings": {
"givenName": "first_name",
"surname": "last_name"
},
"ListClaimMappings": {
"groups": "groups"
}
}
}
This specifies that the values in the JWT claims "givenName"
and "surname"
should be copied to attributes named "value.first_name"
and
"value.last_name"
respectively. Additionally the list of values in the JWT
claim "groups"
should be copied to an attribute named "list.groups"
.
The following table shows the resulting attributes that will be extracted, and the ways they may be used in Rule Bindings:
Attributes | Supported Selector Operations | Can be Interpolated |
---|---|---|
value.first_name | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
value.last_name | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
list.groups | In, Not In, Is Empty, Is Not Empty | no |
Claim Specifications and JSON Pointer
The ClaimMappings
and
ListClaimMappings
fields are used to point to data
within the JWT. If the desired key is at the top of level of the JWT, the name
can be provided directly. If it is nested at a lower level, a JSON Pointer may
be used.
Assume the following JWT claims are decoded:
{
"division": "North America",
"groups": {
"primary": "Engineering",
"secondary": "Software"
},
"iss": "https://my-corp-app-name.auth0.com/",
"sub": "auth0|eiw7OWoh5ieSh7ieyahC3ief0uyuraphaengae9d",
"aud": "V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt",
"iat": 1589224148,
"exp": 1589260148,
"nonce": "eKiihooH3Fah8Ieshah4leeti6ien3"
}
A parameter of "division"
will reference "North America"
, as this is a top
level key. A parameter "/groups/primary"
uses JSON Pointer syntax to
reference "Engineering"
at a lower level. Any valid JSON Pointer can be used
as a selector. Refer to the JSON Pointer
RFC for a full description of the syntax