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:
- User completes step-up authentication
- Session stores
exp_timestampfrom IdP token (e.g., 10 minutes) - User works on protected resources
- Token expires after 10 minutes
- User must re-authenticate with IdP
- 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
expclaim (~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.
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
expclaim - Step-up authentication documentation
- Current implementation files:
lib/gitlab/auth/oidc/step_up_authentication_flow.rblib/gitlab/auth/oidc/step_up_auth_expiration_validator.rb
Implementation plan
-
Add
session_expiration_enabled?method toStepUpAuthenticationFlow -
Modify
expired?method to check configuration before checking expiration -
Add unit tests for both
session_expiration_enabled: trueandfalsescenarios - Update OIDC documentation with configuration examples
-
Add configuration example to
gitlab.yml.example(optional) - Test with actual OmniAuth provider configuration