Skip to content

Step-up auth: Expiration validation - Basic core and UI [PART 1]

What does this MR do and why?

Step-up auth: Add basic OIDC expiration validation

Currently, step-up authentication sessions do not validate OIDC token expiration claims. This means that sessions can remain active even after the underlying OIDC ID token has expired, leading to potential security issues.

This commit introduces basic expiration validation. It implements extraction and validation of OIDC token expiration claims to ensure step-up sessions respect Identity Provider timeframes.

  • Extract exp claim from OIDC ID tokens during authentication flow
  • Store expiration timestamps in step-up session data
  • Add expiry validator to check session validity
  • Provide comprehensive test coverage for expiration scenarios

Changelog: other

🛠️ with ❤️ at Siemens

References

Screenshots or screen recordings

Scenario: Step-up auth session expires after 15 seconds

Screen_Recording_2025-08-08_at_08.47.12

The screencast demonstrates the following authentication flow:

  1. Keycloack configuration: Show the key confguration settings for testing the expiration date, e.g. Max Age setting in the browser auth flow, Access Token Lifespan in the realm settings is set to 15 seconds => these are important for the local testing guide below
  2. Step-up auth sign in: After the initial sign in, the user wants to access the admin mode and is redirected to the IdP (Keycloak) in order to perform the step up auth challenge
  3. Admin mode / area during the lifespan: After the step-up auth challenge has succeeded, the user has 15 seconds to access in the admin area (watch the timer 😉 )
  4. Step-up auth session expires: After the 15 seconds, the user is "kicked out" of the admin area and receives the notice that the step-up auth session has expired, see screenshot below.
  5. Expiration Validation • After reloading the page • User should be logged out or required to re-authenticate • This occurs because the step-up authentication has expired

image

How to set up and validate locally

Part 1: Configure step-up auth in Keycloak

  1. Follow the steps to set up step-up authentication in Keycloak; Note: Usually the default expiration time for a Keycloak is set to 5 Min. But, this is too long for testing.
  2. For testing purposes, we want to reduce the expiration time to 15 - 30 seconds for easier testing (so that we do not need to wait that long).. We can do this in Keycloak by navigating to the realm settings, going to the tab Tokens and ther you will find the setting Access Token Lifespan. Set it to 15 seconds. See screenshot below.
  3. Ensure the in the broswer auth flow, the "Max Age" for the step-up auth condition is set to 10 (=> which means that step-up authentiocatoin weill be triggered shortly after in keycloak)

image

Part 2: Prepare your local GitLab gdk instance

  1. Please follow the steps described in another MR to enable admin mode, create an admin user, enable feature flag and configure the step-up auth setting properly in the gitlab.yml.
  2. As part of this MR, I recommend using the step up of configuration from the collapse section below.
Click to expand the `config/gitlab.yml`
development:
  <<: *base
  omniauth:
    allow_bypass_two_factor:  ["openid_connect"]
    allow_single_sign_on: ["openid_connect"]
    auto_link_ldap_user: null
    auto_link_saml_user: null
    auto_link_user: ["openid_connect"]
    auto_sign_in_with_provider: 
    block_auto_created_users: false
    external_providers: []

    providers:
    - { name: "openid_connect",
        label: "[OIDC] Keycloak",
        args: {
          name: "openid_connect",
          # strategy_class: "OmniAuth::Strategies::OpenIDConnect",
          scope: ["openid", "profile", "email"],
          response_type: "code",
          issuer: "http://localhost:8080/realms/step-up-auth-gitlab-realm",
          client_auth_method: "query",
          discovery: false,
          uid_field: "preferred_username",
          pkce: true,
          allow_authorize_params: ["claims"],
          client_options: {
            host: "localhost",
            scheme: "http",
            port: "8080",
            identifier: "step-up-auth-gitlab-client",
            secret: "C6S2b1ZkifZa6BI8Jy5K3lz2Eglb4JuQ",
            redirect_uri: "http://gdk.test:3000/users/auth/openid_connect/callback",
            authorization_endpoint: "/realms/step-up-auth-gitlab-realm/protocol/openid-connect/auth",
            token_endpoint: "/realms/step-up-auth-gitlab-realm/protocol/openid-connect/token",
            userinfo_endpoint: "/realms/step-up-auth-gitlab-realm/protocol/openid-connect/userinfo",
            jwks_uri: "http://localhost:8080/realms/step-up-auth-gitlab-realm/protocol/openid-connect/certs",
            end_session_endpoint: "/realms/step-up-auth-gitlab-realm/protocol/openid-connect/logout"
          }
        },
        step_up_auth: {
          admin_mode: {
            enabled: true,
            documentation_link: "https://openid.net/specs/openid-connect-core-1_0.html#IDToken",
            id_token: {
              required: {
                acr: 'gold' 
              }
            },
            params: {
              claims: { 
                id_token: { 
                  acr: { 
                    essential: true, 
                    values: ['gold'] 
                  } 
                } 
              }
            }
          },          
        }
      }

Part 3: Test the expriation validation

  1. Access admin area: Sign in and navigate to admin area - you'll be redirected to Keycloak for step-up auth, then back to GitLab.
  2. Test expiration validation:
    • Stay in the admin area and wait 15+ seconds for the token to expire (Note: We have set up the 15 second lifespan as part of a previous step)
    • Refresh the page or navigate to another admin page
    • Expected: You should be logged out from the admin area with an expiration notice (as shown in the screencast)
  3. Verify expiration behavior:
    • Sessions expire after configured time (15 seconds)
    • Users see expiration notice and are redirected
    • Non-admin areas remain accessible after step-up expiration
    • Re-authentication works properly after expiration

The core validation is that the StepUpSessionExpiryValidator correctly detects expired OIDC tokens and transitions step-up sessions to expired state, forcing re-authentication for protected areas.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #545965

Edited by Gerardo Navarro

Merge request reports

Loading