Keep your users logged in: Enable session renewal for IBM Cloud ALB OAuth Proxy Add-On

9 May 2023

4 min read

ALB OAuth Proxy now offers the usage of refresh tokens for session lifetime extension

If you were using ALB OAuth Proxy Add-On in IBM Cloud® Kubernetes Service before, you may be familiar with the limitation where sessions have a static lifetime and require your users to reauthenticate periodically. With the recent introduction of support for refresh tokens in the add-on, you can enable automatic session renewal up to 90 days without compromising security.

As of 13 April 2023, a new configuration option has been introduced for ALB OAuth Proxy that enables the usage of refresh tokens for session lifetime extension.

What are refresh tokens?

In order to understand refresh tokens, we should get familiar with access tokens. Access tokens are required to access the backend resources themselves. These are issued by an authentication server and stored on the client side. The client then uses this token when they need to reach protected resources. Access tokens have an expiration time, and after they expire, the token is considered invalid, and access will be refused to the bearer of the token.

In contrast, refresh tokens cannot be used to authenticate backend services to access protected resources; instead, they can be used to issue access tokens without requiring the user to sign in interactively.

When enabled, users receive a refresh token after successful logins, and access tokens will be automatically renewed for them using their refresh token whenever they need it. Refresh tokens are automatically saved in cookies along with the access tokens, allowing users to stay signed in as long as the refresh token is valid.

IBM Cloud App ID can issue access and refresh tokens, but OAuth2-Proxy does not rely on these by default. If the authentication succeeds, OAuth2-Proxy creates a session cookie that is valid for a fixed period of time. As long as the cookie is valid, the user can access protected resources. However, once the cookie expires, the user will need to sign-in again.

With the recent changes introduced in ALB OAuth Proxy, it is now possible to configure OAuth2-Proxy to rely on the access and refresh tokens. Users with valid access tokens will be able to access protected resources, and OAuth2-Proxy will be able to renew access tokens on-demand as long as the refresh token is valid. Users will need to reauthenticate only when their refresh token expires (or the cookie containing the refresh token is removed from their browser).

Using refresh tokens (with short-lived access tokens) is generally more secure. Unlike long-living access tokens, which are validated by the backend application directly, these refresh tokens are controlled and validated by App ID. This allows revocation of refresh tokens when a user logs out, gets deleted or their permission is revoked in some other ways.

Configuring token refresh for App ID integration with IBM Cloud Kubernetes Service

Users can enable the feature in the following three steps. This guide assumes that you already have a working ALB OAuth Proxy Add-On set up for your IBM Cloud Kubernetes Service cluster. If you do not, check out our official guide on how to set it up.

Step 1: Enable refresh tokens in App ID

In order to use refresh tokens, you have to enable them in App ID first. By default, this feature is turned off:

  1. Navigate to the management console of your App ID instance.
  2. In the IBM Cloud App ID management console, go to Manage Authentication.
  3. Select the Authentication Settings tab.
  4. Under Sign-in Expiration, enable the refresh tokens by clicking on the switch on the right side.
  5. The expiration setting for refresh tokens should be available now. You can change it to your desired value: 
  6. Click Save.

Step 2: Update your Ingress resources

When using refresh tokens for session renewal, the cookie maintained by OAuth2 Proxy can be larger than 4 kB. Most browsers do not handle cookies above this size, so OAuth2 Proxy splits the session cookie into two pieces. In order to let OAuth2 Proxy access both cookies properly, the following configuration snippet must be added to the Ingress resources that use authentication:

annotations:
  nginx.ingress.kubernetes.io/configuration-snippet: |
    auth_request_set $_oauth2_<App_ID_service_instance_name>_upstream_1 $upstream_cookie__oauth2_<App_ID_service_instance_name>_1;
    access_by_lua_block {
      if ngx.var._oauth2_<App_ID_service_instance_name>_upstream_1 ~= "" then
      ngx.header["Set-Cookie"] = "_oauth2_<App_ID_service_instance_name>_1=" .. ngx.var._oauth2_<App_ID_service_instance_name>_upstream_1 .. ngx.var.auth_cookie:match("(; .*)")
      end
    }

Note: Kubernetes Ingress Controllers (ALBs) on clusters created on or after 31 January 2022 do not process Ingress resources that have snippet annotations (e.g., nginx.ingress.kubernetes.io/configuration-snippet ) by default as all new clusters are deployed with the allow-snippet-annotations: "false"  configuration in the ALB’s ConfigMap. This is a safe default introduced as a mitigation of CVE-2021-25742 . You can find more information of this on our security bulletin. Because this configuration requires you to use configuration snippets, you need to edit the ALB’s ConfigMap (kube-system/ibm-k8s-controller-config) and change to allow-snippet-annotations: "false" to allow-snippet-annotations: "true"

If you were previously using the nginx.ingress.kubernetes.io/configuration-snippet  annotation in your Ingress configuration, you may have to merge the previous snippet with your config. See our official documentation for more examples.

Step 3: Configure cookie_refresh for OAuth2-Proxy deployed by ALB OAuth Proxy Add-On

The final step is to enable using the refresh token on the OAuth2 Proxy side. To achieve this, the cookie_refresh  value must be configured to a valid duration in the Kubernetes ConfigMap that describes custom OAuth2-Proxy settings.

By default, this ConfigMap does not exist—if you have not customized the default behavior of OAuth2-Proxy before, you may have to create it. The following is an example for creating such a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: oauth2-<App_ID_service_instance_name>
  namespace: <ingress_resource_namespace>
data:
  cookie_refresh: "58m"

The value of cookie_refresh determines the age of the access token, after which OAuth2-Proxy requests a new token from App ID. It is recommended to set this value a few minutes shorter than the expiration of your access token defined in App ID.

 

More information

For more information, check out our official documentation about configuring App ID authentication or learn more about App ID in general on this YouTube channel (link resides outside ibm.com).

To learn more about refresh and access tokens in general, you may be interested in RFC6749 (link resides outside ibm.com).

Contact us

If you have questions, join the discussion in the #general channel on our public IBM Cloud Kubernetes Service Slack (link resides outside ibm.com).

Author

Marcell Pünkösd

IBM Cloud Kubernetes Service Engineer

Attila Fábián

Software Engineer, IBM Cloud Kubernetes Service