Step-up auth: Require oauth provider for groups [PART 2.0]
-
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 merge request extends the existing step-up authentication functionality for admin mode to support namespace (group) scope. It implements Part 2.0 of the step-up authentication feature for groups, allowing administrators to require additional authentication before users can access certain group resources or perform specific actions within a group.
The motivation for this change is described in the issue. TLDR: Organizations require fine-grained access control where certain group resources or operations demand higher authentication assurance.
This feature enables:
- Enhanced security for sensitive groups: Administrators can enforce step-up authentication for groups containing sensitive projects or data
- Compliance requirements: Meet regulatory requirements that mandate additional authentication for accessing certain resources
- Flexible security policies: Allow different authentication requirements for different groups based on their security classification
- The implementation follows the same pattern as the existing admin mode step-up authentication but extends it to the namespace/group level, providing a consistent user experience across different security contexts.
References
- Step-up auth: Group-based OIDC Step-up Authenti... (#556943)
- Current step-up auth implementation for admin mode as the foundation for this MR => Step-up auth: Add omniauth step-up auth for adm... (!171643 - merged)
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 merge request performance guidelines -
Conforms to the style guides -
Conforms to the javascript style guides -
Conforms to the database guides -
Ensure that only public groups are able to set the required step-up oauth provider
Screenshots or screen recordings
Scenario: Successful step-up auth challenge
2025-07-23-step-up-auth-for-groups-successful-scenario
This scenario shows what happens when the step-up auth challenge is successful:
- The screencast starts with a clean session in a private browser window.
- The user performs a normal sign in via the OIDC omniauth provider (this is not the step-up auth).
- After the "normal" sign in, the user goes to a step-up auth unprotected group; GitLab behaves as usual and allows the user to access the group and its resources
- Now, the user tries to access a step-up auth protected group and is asked for a reauthentication. This reauthentication can only be achieved through a step-up authentication.
- The use clicks on the button "OpenID Connect" and is redirected to the IdP server (Keycloak) to perform a step-up authentication. Note: In case of this screencast, the step-up auth method is configured to be a second password prompt, but in production, it would be a more secure auth method, e.g. fingerprint, device trust, etc.
- Successful step-up auth challenge implemenation
👍 - Now, the user is able to access the group's resources
Click to expand the step-up auth config in `config/gitlab.yml`
- { name: "openid_connect",
# ...
args: {
name: "openid_connect",
# ...
},
step_up_auth: {
namespace: {
id_token: {
required: {
acr: 'gold'
}
},
params: {
claims: {
id_token: {
acr: {
essential: true,
values: ['gold']
}
}
}
}
}
}
}
Scenario: Rejected step-up auth challenge
This scenario shows what happens when the step-up auth challenge is rejected because the user is not able to fulfill the step-up auth criteria , i.e. the required acr
value must be gold
, but the authorization parameters wants Keycloak to authenticate the user with the acr
value silver
2025-07-24-step-up-auth-rejected
This scenario shows what happens when the step-up auth challenge is successful:
- We adjust the
gitlab.yml
in a way to still require theacr
valuegold
for accessing groups, but we also adjust the step-up auth params and request the acr levelsilver
. This means that the idp will authenticate the user, but only to acr levelsilver
(which is lower than acr levelgold
). - Then we restart the rails server
- Again, the user access the step-up auth protected group and and get lap shows that step up authentication is required.
- The user clicks on the button "OpenID Connect" to trigger the step up authentication flow. Note: The IdP checks the user and authenticates the user successfully because the requested acr value
silver
is the default permission in the test keycloak instance. - User is be directed back to get lap, but without having reached the required ACR value
gold
.💥
Click to expand the step-up auth config in `config/gitlab.yml`
- { name: "openid_connect",
# ...
args: {
name: "openid_connect",
# ...
},
step_up_auth: {
namespace: {
id_token: {
required: {
acr: 'gold'
}
},
params: {
claims: {
id_token: {
acr: {
essential: true,
values: ['silver']
}
}
}
}
}
}
}
How to set up and validate locally
Part 1: Configure step-up auth in Keycloak
- Please follow the steps described in a previous MR .
Part 2: 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. Also create a subproject that we use for testing purposes.
- Set the attribute
step_up_auth_required_oauth_provider
in the group namespace setting to the valueopenid_connect
(<= the name of the provider we have set up in the gitlab config)Group.find(<recently_created_group_ip>).namespace_settings.update(step_up_auth_required_oauth_provider: 'openid_connect')
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: {
# ...
},
namespace {
id_token: {
required: {
acr: 'gold'
}
},
params: {
claims: {
id_token: {
acr: {
essential: true,
values: ['gold']
}
}
}
}
},
}
}
Part 3: Test the step-up auth for group
- Open a private browser window (fresh session)
- Go to the usual sign in page: http://gdk.test:3000/users/sign_in
- Use the configured Keycloak OIDC omniauth provider to sign in; you will be redirected to Keycloak sign in interface
- In Keycloak, submit the username and password; Note: this is the normal sign in for the user (think of it as the first step and not the step-up auth)
- After a successful sign in, the user will be redirected to it's dashboard
- Go to the step-up auth protected group (created in before).
- You should be redirected to an authentication page where you are asked to select
- Sign in with the button "[OIDC] Keycloak"; Note: this is a special omniauth sign-in button that will trigger the step-up auth on the side of the IdP
- In Keycloak, you will be asked to authenticate for a higher step (acr level
gold
); Note: this is the additional step that requires higher authentication, i.e. the step-up auth - After the successful second "stepped-up" sign in, the user will be redirected back to the step-up auth protected group and is able to access all aspects of the group