OpenID Connect (OIDC) Auth Method
Enterprise
This feature requires version 1.8.0+ of self-managed Consul Enterprise. Refer to the enterprise feature matrix for additional information.
The oidc auth method can be used to authenticate with Consul using
OIDC. This method allows
authentication via a configured OIDC provider using the user's web browser.
This method may be initiated from the Consul UI or the command line.
This page assumes general knowledge of OIDC concepts 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
oidc:
OIDCDiscoveryURL(string: <required>)- The OIDC Discovery URL, without any .well-known component (base path).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.OIDCClientID(string: <required>)- The OAuth Client ID configured with your OIDC provider.OIDCClientSecret(string: <required>)- The OAuth Client Secret configured with your OIDC provider.EnableServiceDCR(bool: false)- Selects this auth method as the cluster identity provider for dynamic client registration. Set it toEnterprisetrueon exactly oneoidcauth method in the cluster. That method must setOIDCDiscoveryURL,OIDCClientID, andOIDCClientSecret.OIDCClientAssertioncannot replaceOIDCClientSecretfor dynamic client registration. Consul rejects the method for registration when the secret is empty. SetJWTSupportedAlgsto["ES256"]. IBM Verify signs tokens with ES256, and this field defaults to RS256. Consul uses that client as the bootstrap client when it registers services whoseai.roleisai-agentormcp-server. You can omitAllowedRedirectURIswhen this field istrue. Refer to Configure OAuth clients for AI agents and MCP servers.OIDCClientAssertion(OIDCClientAssertion)- Send a signed JWT as a client assertion to the OIDC provider. This enables "private key JWT" authentication for OIDC clients. This field is optional. You can set only one ofOIDCClientSecretorOIDCClientAssertion, and setting both fields results in a configuration error. The JWT for the client assertion is signed using the RS256 algorithm.Audience(array<string>)- The URL that processes the assertion. Defaults to theOIDCDiscoveryURLin the parent ACLAuthMethodConfig.PrivateKey(OIDCClientAssertionKey)- External key material to sign the JWT.PemKey(string)- An RSA private key, in pem format to use for signing the JWT.
OIDCClientUsePKCE(bool: true)- Enables Proof Key for Code Exchange (PKCE) in the OIDC authentication flow. Defaults totrue. PKCE is an additional security mechanism for OAuth 2.0 authorization code grants, designed to protect against authorization code interception attacks. When enabled, Consul will use PKCE for OIDC logins, which is recommended for all public clients and browser-based authentication. We recommend PKCE unless your OIDC provider does not support PKCE.AllowedRedirectURIs(array<string>)- A list of allowed values forredirect_uri. Must be non-empty for browser and CLI login. You can omit this field whenEnableServiceDCRistrueand the auth method registers service OAuth clients.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.
OIDCScopes(array<string>)- A list of OIDC scopes.OIDCACRValues(array<string>)- A list of Authentication Context Class Reference values to use for the authentication request. See OIDC reference for more info on this parameter. Added in v1.11.0.JWTSupportedAlgs(array<string>)- JWTSupportedAlgs is a list of supported signing algorithms. Defaults toRS256. (Available algorithms)BoundAudiences(array<string>)- List ofaudclaims that are valid for login; any match is sufficient.VerboseOIDCLogging(bool: false)- Log received OIDC tokens and claims when debug-level logging is active. Not recommended in production since sensitive information may be present in OIDC responses.OIDCLogoutURL(string: "")- The identity provider's relying party (RP) initiated logout endpoint, as defined in OpenID Connect RP-Initiated Logout 1.0. By default, Consul uses theend_session_endpointfrom the provider's discovery document. Set this parameter when your provider supports RP-initiated logout but does not advertiseend_session_endpoint. If you set this parameter, Consul uses it instead of the discovered endpoint. The value must be anhttpsURL that includes a host. Refer to OIDC logout for details.OIDCPostLogoutRedirectURIs(array<string>)- URIs that the identity provider can redirect the user to after logout. Consul sends the first entry as thepost_logout_redirect_uriparameter. Each entry must be anhttpsURL that includes a host, and you must also register it with your provider. If you do not set this parameter, the provider decides where to send the user after logout.
Example configuration with client secret
{
"Name": "example-oidc-auth",
"Type": "oidc",
"Description": "Example OIDC auth method",
"Config": {
"AllowedRedirectURIs": [
"http://localhost:8550/oidc/callback",
"http://localhost:8500/ui/oidc/callback"
],
"BoundAudiences": [
"V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt"
],
"ClaimMappings": {
"http://example.com/first_name": "first_name",
"http://example.com/last_name": "last_name"
},
"ListClaimMappings": {
"http://consul.com/groups": "groups"
},
"OIDCClientID": "V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt",
"OIDCClientSecret": "...(omitted)...",
"OIDCDiscoveryURL": "https://my-corp-app-name.auth0.com/"
}
}
Example configuration with JWT as client assertion
The following example enables an OIDC auth method that sets a JWT signed with an RSA private key as the client assertion sent to the OIDC provider.
{
"Name": "example-oidc-auth",
"Type": "oidc",
"Description": "Example OIDC auth method",
"Config": {
"AllowedRedirectURIs": [
"http://localhost:8550/oidc/callback",
"http://localhost:8500/ui/oidc/callback"
],
"BoundAudiences": [
"V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt"
],
"ClaimMappings": {
"http://example.com/first_name": "first_name",
"http://example.com/last_name": "last_name"
},
"ListClaimMappings": {
"http://consul.com/groups": "groups"
},
"OIDCClientID": "V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt",
"OIDCClientAssertion": {
"PrivateKey": {
"PemKey": "-----BEGIN PRIVATE KEY-----\n...(omitted)...\n-----END PRIVATE KEY-----\n"
}
},
"OIDCDiscoveryURL": "https://my-corp-app-name.auth0.com/"
}
}
Example configuration for service client registration
The following example selects this auth method as the single cluster identity provider for dynamic client registration. The example omits AllowedRedirectURIs because the method does not handle browser login.
{
"Name": "service-dcr",
"Type": "oidc",
"MaxTokenTTL": "1h",
"Description": "Bootstrap client for AI service registration",
"Config": {
"EnableServiceDCR": true,
"OIDCClientID": "bootstrap-client-id",
"OIDCClientSecret": "...(omitted)...",
"OIDCDiscoveryURL": "https://tenant.verify.ibm.com/oidc/endpoint/default",
"JWTSupportedAlgs": ["ES256"]
}
}
Example configuration with IdP logout
The following example configures the identity provider logout endpoint for a
provider that does not advertise end_session_endpoint in its discovery
document, and sends the user back to the Consul UI after logout:
{
"Name": "example-oidc-auth",
"Type": "oidc",
"Description": "Example OIDC auth method with IdP logout",
"Config": {
"AllowedRedirectURIs": [
"http://localhost:8550/oidc/callback",
"https://consul.example.com/ui/oidc/callback"
],
"BoundAudiences": [
"V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt"
],
"OIDCClientID": "V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt",
"OIDCClientSecret": "...(omitted)...",
"OIDCDiscoveryURL": "https://idp.example.com/",
"OIDCLogoutURL": "https://idp.example.com/oidc/logout",
"OIDCPostLogoutRedirectURIs": [
"https://consul.example.com/ui/"
]
}
}
JWT verification
JWT signatures will be verified against public keys from the issuer via OIDC
discovery. Keys will be fetched from the OIDC Discovery URL during
authentication and OIDC validation criteria (e.g. iss, aud, etc.) will be
applied.
OIDC authentication
Consul includes two built-in OIDC login flows: the Consul UI, and the CLI using
consul login.
Redirect URIs
An important part of OIDC auth method configuration is properly setting
redirect URIs. This must be done both in Consul and with the OIDC provider, and
these configurations must align. The redirect URIs are specified for an auth
method with the AllowedRedirectURIs parameter. There
are different redirect URIs to configure the Consul UI and CLI flows, so one or
both will need to be set up depending on the installation.
Consul UI redirect URI
Logging in via the Consul UI requires a redirect URI of the form:
http://localhost:8500/ui/oidc/callback or
https://{host:port}/ui/oidc/callback
The "host:port" must be correct for the Consul agent serving the Consul UI.
CLI redirect URI
If you plan to support authentication via consul login -type=oidc -method=<name>, a localhost redirect URI must be set (usually this is
http://localhost:8550/oidc/callback). Logins via the CLI may specify a
different host and/or listening port if needed, and a URI with this host/port
must match one of the configured redirected URIs. These same "localhost" URIs
must be added to the provider as well.
OIDC login
Log in to the Consul UI
- Click the "Log in" link at the top right of the menu bar.
- Click one of the "Continue with..." buttons for your OIDC auth method of choice.
- Complete the authentication with the configured provider.
Log in with the CLI
$ consul login -method=oidc -type=oidc -token-sink-file=consul.token
Complete the login via your OIDC provider. Launching browser to:
https://myco.auth0.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8550%2Foidc%2Fcallback&client_id=r3qXc2bix9eF...
The browser will open to the generated URL to complete the provider's login. The URL may be entered manually if the browser cannot be automatically opened.
The callback listener may be customized with the following optional parameters. These are typically not required to be set:
The callback listener defaults to listen on localhost:8550. If you want to
customize that use the optional flag
-oidc-callback-listen-addr=<host:port>.
OIDC logout
When a user logs out of a token created by an oidc auth method, Consul can
also end the user's session at the identity provider by using
OpenID Connect RP-Initiated Logout 1.0.
Without it, the provider session stays active, and the next Consul login can
complete without asking for credentials.
Identity provider (IdP) logout is available when one of the following is true:
- The provider advertises an
end_session_endpointin its discovery document. - You set
OIDCLogoutURLon the auth method.
The logout endpoint must be an https URL that includes a host, because the
logout URL contains the user's ID token. If the endpoint does not meet this
requirement, logout only destroys the Consul token.
When the user logs in, Consul builds the provider logout URL from the logout
endpoint, the user's ID token as the id_token_hint parameter, and the first
OIDCPostLogoutRedirectURIs entry as the
post_logout_redirect_uri parameter, if set. Consul returns the URL to the
client that logged in and does not store it on the Consul servers.
The provider session is tied to the user's browser, so the user must open the logout URL in that browser. Consul servers do not call the provider to log the user out.
Log out of the Consul UI
If you logged in to the Consul UI with the auth method, logging out of the UI also opens the provider logout URL in a new browser tab.
Log out with the CLI
When you log in with consul login -type=oidc, Consul saves the provider
logout URL in a file next to the token sink file, with .oidc-logout appended
to its name. For example, -token-sink-file=consul.token creates
consul.token.oidc-logout. Only the file owner can read it.
To log out, run consul logout with the same token
file. Pass the file with the -token-file flag or the CONSUL_HTTP_TOKEN_FILE
environment variable. Consul destroys the token, prints the provider logout URL,
and deletes the .oidc-logout file.
Open the URL in a browser to end the provider session. To open it automatically
in your default browser, add the -open-browser
flag or set the CONSUL_LOGOUT_OPEN_BROWSER environment variable to true.
The following example destroys the token and opens the provider logout URL in the default browser:
$ consul logout -token-file=consul.token -open-browser
To also end your identity provider session, open the following URL in a browser:
https://idp.example.com/oidc/logout?id_token_hint=ID_TOKEN&post_logout_redirect_uri=https%3A%2F%2Fconsul.example.com%2Fui%2F
Opened the identity provider logout URL in your default browser.
If the Consul token has expired or no longer exists, consul logout reports the
error and still prints the provider logout URL. If you pass the token with the
-token flag or only the CONSUL_HTTP_TOKEN environment variable, Consul
destroys the token but does not print the provider logout URL.
OIDC configuration troubleshooting
The amount of configuration required for OIDC is relatively small, but it can be tricky to debug why things aren't working. Some tips for setting up OIDC:
Monitor the log output for the Consul servers. Important information about OIDC validation failures will be emitted.
Ensure Redirect URIs are correct in Consul and on the provider. They need to match exactly. Check: http/https, 127.0.0.1/localhost, port numbers, whether trailing slashes are present.
BoundAudiencesis optional and typically not required. OIDC providers will use theclient_idas the audience and OIDC validation expects this.Check your provider for what scopes are required in order to receive all of the information you need. The scopes "profile" and "groups" often need to be requested, and can be added by setting
[OIDCScopes](#oidcscopes)="profile,groups"on the auth method.If you find claim-related errors in logs, review the provider's documentation to learn how the provider names and structures its claims. Depending on the provider, you may be able to construct a simple
curlimplicit grant request to obtain a JWT that you can inspect. An example of how to decode the JWT (in this case located in theaccess_tokenfield of a JSON response):jq --raw-output '.access_token / "." | .[1] | @base64d' jwt.jsonIf logging out does not end the provider session, check the Consul server logs for an
INFOmessage that containsskipping IdP logout: no OIDCLogoutURL configuredwhen the user logs in. This message means that the provider does not advertise anend_session_endpointand the auth method does not setOIDCLogoutURL. SetOIDCLogoutURLto the provider's logout endpoint. For CLI logins, runconsul logoutwith the token file fromconsul login.If the Consul server logs contain a
WARNmessage that containsOIDC logout endpoint is not a valid https URLwhen the user logs in, the provider advertises anend_session_endpointthat is not anhttpsURL with a host. SetOIDCLogoutURLto the provider'shttpslogout endpoint.The
VerboseOIDCLoggingoption is available which will log the received OIDC token if debug level logging is enabled. This can be helpful when debugging provider setup and verifying that the received claims are what you expect. Since claims data is logged verbatim and may contain sensitive information, this option should not be used in production.
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