Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
Register now

Step-up auth: Add configurable session expiration

Problem Statement / Context

GitLab's step-up authentication correctly implements session expiration based on the OpenID Connect ID Token exp claim, as introduced in #545965. This is the standard-compliant approach for token expiration handling.

However, in enterprise environments, the team operating a self-hosted GitLab instance often does not control the Identity Provider (IdP) configuration. The IdP may be managed by a separate security or IT team, and modifying token expiration settings specifically for GitLab may not be possible or permitted.

When the IdP returns short-lived tokens (e.g., 10 minutes), step-up authentication sessions expire quickly, requiring frequent re-authentication:

Example scenario:

  1. User completes step-up authentication
  2. Session stores exp_timestamp from IdP token (e.g., 10 minutes)
  3. User works on protected resources
  4. Token expires after 10 minutes
  5. User must re-authenticate with IdP
  6. Cycle repeats throughout the working session

This creates a poor user experience for long working sessions when the GitLab operator cannot adjust IdP token lifetimes.

Proposal

Add a configurable option to control step-up authentication session expiration behavior via gitlab.yml. This follows the existing pattern where all step-up auth configuration is defined within the OmniAuth provider configuration in gitlab.yml.

The configuration will allow administrators to:

  • Enable expiration (default): Step-up auth expires based on IdP token exp claim (~10 minutes) - maintains current security behavior
  • Disable expiration: Step-up auth is valid for the entire user session (until logout/session expiry) - improves user experience

This is a security feature, so expiration will be enabled by default to maintain the current secure behavior. Administrators who want improved user experience can explicitly disable it.

🛠️ with ❤️ at Siemens

Proposed Solution

Add a new session_expiration_enabled configuration option within the step_up_auth block of OmniAuth provider configuration:

production: &base
  omniauth:
    providers:
    - { name: 'openid_connect',
        label: 'Provider name',
        args: {
          name: 'openid_connect',
          allow_authorize_params: ["claims"],
        },
        step_up_auth: {
          session_expiration_enabled: false,  # NEW: Disable expiration for better UX
          admin_mode: {
            id_token: {
              required: { acr: 'gold' }
            },
            params: { ... }
          },
          namespace: {
            id_token: {
              required: { acr: 'gold' }
            },
            params: { ... }
          }
        }
      }

Configuration behavior:

session_expiration_enabled Behavior
true (default) Step-up auth expires based on IdP token exp claim (~10 minutes). Current behavior preserved.
false Step-up auth is valid for the entire session. No re-authentication until logout.

Alternatives Considered

Several approaches were evaluated for controlling step-up auth session expiration:

Approach Effort Runtime Changeable Admin UI Per-Group Best Use Case
gitlab.yml (chosen) Low No (restart) No No Permanent instance config
Feature Flag Low Yes No Yes Rollouts, A/B testing
Application Setting Medium Yes Yes No Admin-controlled settings
Environment Variable Low No (restart) No No Ops-controlled deployments
Per-Group Setting High Yes Yes Yes Multi-tenant/SaaS
Detailed comparison of alternatives

1. Feature Flag

  • Pros: Quick to implement, can target specific users/groups, standard pattern for rollouts
  • Cons: Intended for temporary use, becomes tech debt if left indefinitely, requires Rails console access
  • Best for: Initial rollout and testing, not permanent configuration

2. Application Setting (Admin UI)

  • Pros: Accessible via Admin Area, runtime changeable, self-documenting
  • Cons: Requires database migration, more implementation effort, single global setting
  • Best for: Settings that admins frequently adjust

3. Environment Variable

  • Pros: Simple, follows 12-factor app pattern, ops-controlled
  • Cons: Requires restart, no Admin UI visibility, cannot change at runtime
  • Best for: Infrastructure-level decisions

4. Per-Group/Namespace Setting

  • Pros: Granular control, group owners can configure, different policies per group
  • Cons: Most complex implementation, requires UI work, inheritance complexity
  • Best for: GitLab.com SaaS, enterprises with varied security policies

Why gitlab.yml was chosen:

  • All step-up auth configuration is already stored in gitlab.yml within the OmniAuth provider config
  • Maintains consistency with existing patterns
  • No database changes required
  • Restart requirement is acceptable for security configuration changes
  • Low implementation effort

Related Resources

  • Parent issue: Step-up auth alignment with 2FA enforcement patterns
  • OpenID Connect Core 1.0 - ID Token exp claim
  • Step-up authentication documentation
  • Current implementation files:
    • lib/gitlab/auth/oidc/step_up_authentication_flow.rb
    • lib/gitlab/auth/oidc/step_up_auth_expiration_validator.rb

Implementation plan

  • Add session_expiration_enabled? method to StepUpAuthenticationFlow
  • Modify expired? method to check configuration before checking expiration
  • Add unit tests for both session_expiration_enabled: true and false scenarios
  • Update OIDC documentation with configuration examples
  • Add configuration example to gitlab.yml.example (optional)
  • Test with actual OmniAuth provider configuration
Edited Feb 04, 2026 by Bogdan Denkovych
Assignee Loading
Time tracking Loading