Step-up auth: Group protection (OIDC backend support) [2/4]
-
Please check this box if this contribution uses AI-generated content (including content generated by GitLab Duo features) as outlined in the GitLab DCO & CLA. As a benefit of being a GitLab Community Contributor, you receive complimentary access to GitLab Duo.
What does this MR do and why?
This MR introduces the foundational OIDC backend changes needed to support step-up authentication at the namespace/group level. It extends the existing OIDC step-up authentication classes to handle a new namespace
scope alongside the existing admin_mode
scope.
Context: This MR builds upon the step-up authentication foundation that was first introduced for admin mode in !171643 (merged), and extends the model and UI settings added for group-based step-up auth in !199423 (merged). GitLab needs to provide enhanced security for sensitive group/namespace operations by requiring additional authentication verification (step-up authentication) through OIDC providers.
This MR (2/4) includes:
- Extended OIDC step-up authentication flow to support namespace scope
- Updated OAuth callback handling to process namespace step-up auth requests
- Added proper scope separation between admin_mode and namespace contexts
- Enhanced session management for namespace step-up authentication
- Comprehensive test coverage for all new namespace scope scenarios
Technical changes:
-
lib/gitlab/auth/oidc/step_up_auth_before_request_phase.rb
: Extended request phase handler to support namespace scope with feature flag isolation -
lib/gitlab/auth/oidc/step_up_authentication_flow.rb
: Added namespace scope support to authentication flow management -
app/controllers/omniauth_callbacks_controller.rb
: Updated OAuth callback to handle both admin_mode and namespace scopes independently - Comprehensive test coverage with 288+ lines of new tests ensuring proper isolation and functionality
This MR implements Phase 2: OIDC Backend Extensions of the group-based OIDC step-up authentication feature, building upon the model and UI settings from Phase 1 (!199423 (merged)).
All changes are protected by the omniauth_step_up_auth_for_namespace
feature flag and maintain full backward compatibility with existing admin_mode step-up authentication.
- All changes are behind the
omniauth_step_up_auth_for_namespace
feature flag (disabled by default) - This MR only adds backend authentication flow support - no enforcement logic is included
- The actual enforcement of step-up authentication will be implemented in future phases
- No user-facing changes or disruptions will occur until the complete feature is enabled
- Existing authentication flows remain completely unaffected
References
- Related to Step-up auth: Group-based OIDC Step-up Authenti... (#556943)
- Builds on !199423 (merged) - Step-up auth: Group protection (Model and UI settings) [PART 1]
- Related to !171643 (merged) - Original step-up authentication for admin mode implementation
- Part of the MR split strategy documented in the project devspace
Screenshots or screen recordings
N/A - Backend changes only, no UI modifications in this MR.
How to set up and validate locally
Part 1: Prepare your local GitLab gdk instance
- In your local gdk instance, add the following omniauth configuation to the
config/gitlab.yml
, see collapsed section below - Enable the feature flag
:omniauth_step_up_auth_for_namespace
via the rails consoleFeature.enable(:omniauth_step_up_auth_for_namespace)
- Create a simple GitLab group that we want to protect with step-up auth.
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: {
namespace: {
id_token: {
required: {
acr: 'gold'
}
},
params: {
claims: {
id_token: {
acr: {
essential: true,
values: ['gold']
}
}
}
}
},
}
}
Part 2: Manual Testing via Rails Console
Since this MR only adds backend support without enforcement, you can validate the OIDC backend changes directly via Rails console:
# Quick validation in Rails console
session = {}
provider = 'openid_connect'
# Test namespace scope flow
namespace_flow = Gitlab::Auth::Oidc::StepUpAuthenticationFlow.new(
session: session,
provider: provider,
scope: 'namespace'
)
# Simulate step-up auth flow
namespace_flow.request!
puts "Requested: #{namespace_flow.requested?}" # Should be true
namespace_flow.succeed!
puts "Succeeded: #{namespace_flow.succeeded?}" # Should be true
# Check session isolation
puts session.inspect
# Should show: {"omniauth_step_up_auth"=>{"openid_connect"=>{"namespace"=>{"state"=>"succeeded"}}}}
# Test scope isolation with admin_mode
admin_flow = Gitlab::Auth::Oidc::StepUpAuthenticationFlow.new(
session: session,
provider: provider,
scope: 'admin_mode'
)
admin_flow.request!
# Both scopes should coexist in session
puts session['omniauth_step_up_auth']['openid_connect'].keys
# Should show: ["namespace", "admin_mode"]
Part 3: Run the automated tests
- Run the comprehensive test suite to verify all functionality:
# Run OIDC-specific tests for namespace scope bundle exec rspec spec/lib/gitlab/auth/oidc # Verify OAuth callback handling for step-up auth bundle exec rspec spec/controllers/omniauth_callbacks_controller_spec.rb -e "step-up"
Part 4: Further checks
- Verify that existing admin_mode step-up authentication continues to work normally
- Test that namespace scope requests are properly handled when the feature flag is enabled
- Confirm feature flag isolation - namespace flag should not affect admin_mode and vice versa
- Test OAuth provider configuration loading for namespace scope
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
MR Checklist (@gerardo-navarro)
-
Changelog entry added, if necessary -
Documentation created/updated via this MR -
Documentation reviewed by technical writer or follow-up review issue created -
Tests added for this feature/bug -
Tested in all supported browsers -
Conforms to the code review guidelines -
Conforms to the style guides -
Conforms to the javascript style guides -
Conforms to the database guides -
Conforms to the merge request performance guidelines