Step-up auth: Group protection (final integration and testing) [4/4]

What does this MR do and why?

This MR completes the step-up authentication enforcement system by integrating it into both group routes and project routes, ensuring comprehensive protection across the entire namespace hierarchy.

Step-up authentication is a security feature that requires additional verification for accessing sensitive data or performing critical actions. In a previous MR, we introduced step-up authentication for admin mode. We then built the frontend authentication flow for groups.

This MR extends step-up authentication to protect all group routes and all underlying resources within a group, including projects, issues, merge requests, and other group-owned entities. When a group requires step-up authentication, users must re-authenticate before accessing the group or any of its descendant resources.

Enforcement mechanism

The implementation checks three critical scenarios:

  1. Direct group access: Validates the group's authentication requirements when accessing group routes
  2. Existing project access: Checks the parent namespace (project.namespace) when accessing project routes
  3. New project creation: Validates namespace_id from parameters to ensure proper authentication before creating projects in protected groups

This ensures comprehensive protection across the entire group hierarchy, preventing unauthorized access to any group-owned resource without proper re-authentication.

Technical implementation

  • Added enforcement to Groups::ApplicationController for all group routes
  • Added enforcement to Projects::ApplicationController for project routes
  • Enhanced EnforcesStepUpAuthenticationForNamespace concern to support both group and project namespace checks
  • Special handling for project creation flow (checks parent namespace from parameters)
  • Skips enforcement in StepUpAuthsController to prevent redirect loops
  • Added type checking to ensure namespace is a Group before validation

The feature is guarded by feature flag :omniauth_step_up_auth_for_namespace and requires explicit namespace actor when checking feature enablement.

This is the final merge request implementing step-up authentication with OIDC for group-scoped operations, completing the implementation series described in #556943.

Closes #556943

Changelog: added

🛠️ with ❤️ at Siemens

References

Screenshots or screen recordings

Scenario: Successful step-up auth challenge

2025-07-23-step-up-auth-for-groups-successful-scenario

This scenario demonstrates a successful step-up authentication flow:

  1. The screencast starts with a clean session in a private browser window
  2. The user performs a normal sign in via the OIDC omniauth provider (this is not the step-up auth)
  3. After the normal sign in, the user accesses an unprotected group; GitLab behaves as usual and allows access to the group and its resources
  4. The user then attempts to access a step-up auth protected group and is prompted for re-authentication
  5. The user clicks on the "OpenID Connect" button and is redirected to the IdP server (Keycloak) to perform step-up authentication. Note: In this screencast, the step-up auth method is configured as a second password prompt, but in production, it would be a more secure method such as biometric authentication, device trust verification, etc.
  6. After successful step-up authentication, the user is able to access the protected group and all its 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

2025-07-24-step-up-auth-rejected

This scenario demonstrates what happens when the step-up auth challenge is rejected because the user cannot fulfill the step-up authentication criteria. The required acr value is gold, but the authorization parameters request Keycloak to authenticate the user with the acr value silver.

  1. We adjust the gitlab.yml to require the acr value gold for accessing groups, but configure the step-up auth params to request the acr level silver. This means the IdP will authenticate the user, but only to acr level silver (which is lower than the required acr level gold)
  2. The Rails server is restarted to apply the configuration changes
  3. The user attempts to access the step-up auth protected group and is prompted for step-up authentication
  4. The user clicks on the "OpenID Connect" button to trigger the step-up authentication flow
  5. The IdP authenticates the user successfully with the requested acr value silver (the default permission in the test Keycloak instance)
  6. The user is redirected back to GitLab, but without having achieved the required ACR value gold, access is denied
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: Prepare your local GitLab gdk instance

Follow the steps described here

Part 2: Test the step-up auth for group

  1. Open a private browser window (fresh session)
  2. Navigate to the sign in page: http://gdk.test:3000/users/sign_in
  3. Use the configured Keycloak OIDC omniauth provider to sign in. You will be redirected to the Keycloak sign in interface
  4. In Keycloak, submit the username and password. Note: this is the normal sign in for the user, not the step-up auth
  5. After successful sign in, you will be redirected to your dashboard
  6. Navigate to the step-up auth protected group (created in Part 2)
  7. You should be redirected to an authentication page prompting you to re-authenticate
  8. Click the "[OIDC] Keycloak" button. Note: this is a special omniauth sign-in button that triggers step-up auth on the IdP side
  9. In Keycloak, you will be prompted to authenticate for a higher security level (acr level gold). Note: this is the additional step that requires higher authentication - the step-up auth
  10. After successful step-up authentication, you will be redirected back to the protected group and can access all aspects of the group

Part 3: Test step-up auth for projects within protected groups

  1. While still authenticated (from Part 3), navigate to a project within the step-up auth protected group
  2. You should have access to the project without additional authentication (since you already completed step-up auth for the parent group)
  3. Try creating a new project within the protected group
  4. The system should validate your step-up authentication status before allowing project creation
  5. If your step-up auth session has expired, you will be prompted to re-authenticate before creating the project

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.

MR Checklist (@gerardo-navarro)

Related to #474650

Edited by Gerardo Navarro

Merge request reports

Loading