OAuth
This feature is available in Gloo Gateway Enterprise only. If you are using the open source version of Gloo, these instructions do not work.
Gloo Gateway supports authentication via OpenID Connect (OIDC). OIDC is an identity layer on top of the OAuth 2.0 protocol. In OAuth 2.0 flows, authentication is performed by an external Identity Provider (IdP) which, in case of success, returns an Access Token representing the user identity. The protocol does not define the contents and structure of the Access Token, which greatly reduces the portability of OAuth 2.0 implementations.
The goal of OIDC is to address this ambiguity by additionally requiring Identity Providers to return a well-defined ID Token. OIDC ID tokens follow the JSON Web Token standard and contain specific fields that your applications can expect and handle. This standardization allows you to switch between Identity Providers - or support multiple ones at the same time - with minimal, if any, changes to your downstream services; it also allows you to consistently apply additional security measures like Role-based Access Control (RBAC) based on the identity of your users, i.e. the contents of their ID token (check out this guide for an example of how to use Gloo Gateway to apply RBAC policies to JWTs).
In this guide, we will focus on the format of the Gloo Gateway API for OIDC authentication.
This feature requires Gloo Gateway’s external auth server to communicate with an external OIDC provider/authorization server.
Because of this interaction, the OIDC flow may take longer than the default timeout of 200ms.
You can increase this timeout by setting the requestTimeout
value on external auth settings
.
The external auth settings can be configured on the global Gloo Gateway Settings
object
.
Configuration format
The auth configuration format shown on this page was introduced with Gloo Enterprise, release 0.20.1. If you are using an earlier version, please refer to this page to see which configuration formats are supported by each version.
Following is an example of an AuthConfig
with an OIDC configuration (for more information on AuthConfig
CRDs, see the main page
of the authentication docs):
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
issuerUrl: theissuer.com
appUrl: https://myapp.com
authEndpointQueryParams:
paramKey: paramValue
callbackPath: /my/callback/path/
clientId: myclientid
clientSecretRef:
name: my-oauth-secret
namespace: gloo-system
scopes:
- email
The AuthConfig
consists of a single config
of type oauth
. Let’s go through each of its attributes:
issuer_url
: The url of the OpenID Connect identity provider. Gloo Gateway will automatically discover OpenID Connect configuration by querying the.well-known/openid-configuration
endpoint on theissuer_url
. For example, if you are using Google as an identity provider, Gloo Gateway will expect to find OIDC discovery information athttps://accounts.google.com/.well-known/openid-configuration
.auth_endpoint_query_params
: A map of query parameters appended to the issuer url in the formissuer_url
?paramKey
:paramValue
. These query parameters are sent to the authorization endpoint when Gloo Gateway initiates the OIDC flow. This can be useful when integrating Gloo Gateway with some identity providers that require custom parameters to be sent to the authorization endpoint.app_url
: This is the public URL of your application. It is used in combination with thecallback_path
attribute.callback_path
: The callback path relative to theapp_url
. Once a user has been authenticated, the identity provider will redirect them to this URL. Gloo Gateway will intercept requests with this path, exchange the authorization code received from the Identity Provider for an ID token, place the ID token in a cookie on the request, and forward the request to its original destination.
The callback path must have a matching route in the VirtualService associated with the OIDC settings. For example, you could simply have a /
path-prefix route which would match any callback path. The important part of this callback “catch all” route is that it goes through the routing filters including external auth. Please see the examples for Google, Dex, and Okta.
client_id
: This is the client id that you obtained when you registered your application with the identity provider.client_secret_ref
: This is a reference to a Kubernetes secret containing the client secret that you obtained when you registered your application with the identity provider. The easiest way to create the Kubernetes secret in the expected format is to useglooctl
, but you can usekubectl create secret
orkubectl apply
as well. If you usekubectl create secret
, be sure to annotate the secret with*v1.Secret
so that Gloo Gateway detects the secret.glooctl create secret oauth --namespace gloo-system --name oidc --client-secret <client_secret_value>
kubectl create secret generic oidc --from-literal=client-secret=<client_secret> kubectl annotate secret oidc resource_kind='*v1.Secret' # Important, since gloo does not watch for opaque secrets without this setting
apiVersion: v1 kind: Secret type: extauth.solo.io/oauth metadata: name: oidc namespace: gloo-system data: # The value is a base64 encoding of the following YAML: # client_secret: secretvalue # Gloo Gateway expects OAuth client secrets in this format. client-secret: Y2xpZW50U2VjcmV0OiBzZWNyZXR2YWx1ZQo=
scopes
: scopes to request in addition to theopenid
scope.
Cookie options
Use the cookieOptions field to customize cookie behavior:
- notSecure - Set the cookie to not secure. This is not recommended, but might be useful for demo/testing purposes.
- maxAge - The max age of the cookie in seconds. Leave unset for a default of 30 days (2592000 seconds). To disable cookie expiry, set explicitly to 0.
- path - The path of the cookie. If unset, it defaults to “/”. Set it explicitly to "" to avoid setting a path.
- domain - The domain of the cookie. The default value is empty and matches only the originating request. This is fine for cases where the
VirtualService
matches the host value that is also the redirect target of the IdP. However, this value is critical if the OAuth provider is redirecting the request to another subdomain, for example. Consider a case where aVirtualService
matches requests to*.example.com
and the IdP redirects its auth requests tosubdomain.example.com
. With default settings fordomain
, if a request comes in onother.example.com
, the operation fails. The user is directed to the IdP login as expected but auth fails because the token-bearing cookie is not sent back to the proxy, since the request originates from a different subdomain. However, if thisdomain
property is set toexample.com
, then the operation succeeds because the cookie is sent to any subdomain ofexample.com
.
Example configuration:
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
session:
cookieOptions:
notSecure: true
maxAge: 3600
Logout URL
Gloo also supports specifying a logout url. When specified, accessing this url will trigger a deletion of the user session and revoke the user’s access token. This action returns with an empty 200 HTTP response.
Example configuration:
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
logoutPath: /logout
When this URL is accessed, the user session and cookie are deleted.
The access token on the server is also revoked based on the discovered revocation endpoint.
You can also override the revocation endpoint through the DiscoveryOverride field in AuthConfig
.
If the authorization server has a service error, Gloo logs out the user, but does not retry revoking the access token. Check the logs and your identity provider for errors, and manually revoke the access token.
Front Channel Logout
Gloo also supports Front Channel Logout RFC. Front channel logout is used when the OpenId provider is handling multiple logged in sessions and the logout endpoint should log out of all of them. The endpoint defined in frontChannelLogout.path
is registered with the OP and is called for each application when the user goes to the logoutPath
endpoint.
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
logoutPath: /logout
frontChannelLogout:
path: /front_channel_logout
Sessions in Cookies
You can store the ID token, access token, and other tokens that are returned from your OIDC provider in a cookie on the client side. To do this, you configure your cookie options, such as the keyPrefix
that you want to add to the token name, in the oauth2.oidcAuthorizationCode.session.cookie
section of your authconfig as shown in the following example. After a client successfully authenticates with the OIDC provider, the tokens are stored in the Set-Cookie
response header and sent to the client. If you set a keyPrefix
value in your cookie configuration, the prefix is added to the name of the token before it is sent to the client, such as Set-Cookie: <myprefix>_id-token=<ID_token>
. To prove successful authentication with the OIDC provider in subsequent requests, clients send their tokens in a Cookie
header.
Cookie headers can have a maximum size of 4KB. If you find that your cookie header exceeds this value, you can either limit the size of the cookie header or store the tokens in Redis and send back a Redis session ID instead.
Storing the raw, unencrypted tokens in a cookie header is not a recommended security practice as they can be manipulated through malicious attacks. To encrypt your tokens, see Symmetric cookie encryption. For a more secure setup, store the tokens in a Redis instance and send back a Redis session ID in the cookie header.
Example configuration:
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
session:
cookie:
keyPrefix: "my_cookie_prefix"
Symmetric cookie encryption
By default, the tokens that are sent in the cookie header are not encrypted and can be manipulated through malicious attacks. To encrypt the cookie values, you can add a cipherConfig
section to your session configuration as shown in the following example.
Setting the cipherConfig
attribute is supported in Gloo Gateway version 1.15 and later and can be used only to encrypt cookie sessions. You cannot use this feature to encrypt Redis sessions.
-
Create a secret with your encryption key. Note that the key must be 32 bytes in length.
glooctl create secret encryptionkey --name my-encryption-key --key "an example of an encryption key1"
-
Reference the secret in the
cipherConfig
section of your authconfig.... kind: AuthConfig spec: configs: - oauth2: oidcAuthorizationCode: session: cipherConfig: keyRef: name: my-encryption-key namespace: gloo-system cookie: keyPrefix: "my_cookie_prefix"
Sessions in Redis
By default, the tokens will be saved in a secure client side cookie. Gloo can instead use Redis to save the OIDC tokens, and set a randomly generated session id in the user’s cookie. Going forward in the Gloo Gateway documentation, we will be using examples of OIDC using a redis session.
Example configuration:
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
session:
failOnFetchFailure: true
redis:
cookieName: session
options:
host: redis.gloo-system.svc.cluster.local:6379
Forwarding the ID token upstream
You can configure gloo to forward the id token to the upstream on successful authentication. To do that, set the headers section in the configuration.
Example configuration:
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: oidc-dex
namespace: gloo-system
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: http://localhost:8080/
callbackPath: /callback
clientId: gloo
clientSecretRef:
name: oauth
namespace: gloo-system
issuerUrl: http://dex.gloo-system.svc.cluster.local:32000/
scopes:
- email
headers:
idTokenHeader: "x-token"
Proof Key for Code Exchange (PKCE) for public and untrusted clients
In a traditional OAuth Authorization flow, the client sends a client secret to the authorization server to request an access token. Depending on the type of client that you use, the client secret might be shared across users and devices. Public clients, such as a mobile app, cannot securely store the client secret as it is embedded in the web browser or can be retrieved by decompiling the app. To avoid authorization code injection attacks, you can leverage the Proof Key for Code Exchange (PKCE) OAuth extension.
PKCE builds on top of the OAuth2 protocol. Instead of sending a client secret to the authorization server, the client generates a random value that is called the Code Verifier and hashes the Code Verifier to create the Code Challenge. The Code Challenge is sent to the authorization server where it is stored for later verification. At the same time, the authorization server returns an authorization code that is good for one use. To request an access token, the client now sends the authorization code and the Code Verifier that was generated earlier. The authorization server hashes the Code Verifier and compares the result to the Code Challenge that the client sent earlier. If both values match, the client is authorized and an access token is returned.
With Gloo Gateway, you can implement PKCE-secured OAuth flows by leveraging the authEndpointQueryParams
and tokenEndpointQueryParams
fields in the AuthConfig. For example, to send the code challenge, add the code_challenge
query parameter to the authEndpointQueryParams
field. To request an access token, include the code
and code_verifier
in the tokenEndpointQueryParams
field.
PKCE-secured OAuth flows can be configured for all supported OIDC providers, except for Okta. Support for the Okta OIDC provider is planned to be added in Gloo Gateway Enterprise version 1.15.0.
For more information, see the Auth0 docs.
Examples
We have seen how a sample OIDC AuthConfig
is structured. For complete examples of how to set up an OIDC flow with
Gloo Gateway, check out the following guides:
-
Authenticate with Auth0: Integrating Gloo Gateway and Auth0 for identity management
-
Authenticate with Google: Setup OpenID Connect (OIDC) authentication with the Google identity provider.
-
Authenticate with Okta: Integrating Gloo Gateway and Okta Identity Cloud
-
Authenticate with Dex: Integrating Gloo Gateway and Dex Identity Provider
-
Authenticate with an Access Token: Integrating Gloo Gateway and Access Tokens