Skip to content

Draft: OIDC Step-up auth: Enhanced reauth for admin mode [POC]

  • 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

What does this MR do and why?

  • This MR is intended as a Proof-Of-Concept (POC) and focusses on the main implementation aspects necessary for step-up auth.

This POC includes the following aspects:

  • Proposal for the step-up auth configuration, see related discussion thread
  • Proposal for storing the step-up auth information in the GitLab session, see related discussion thread
  • Proposal for integrating step-up auth in admin mode
  • Proposal for integrating step-up auth in group namespaces

🛠 with at Siemens

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)

Screenshots or screen recordings

The following screencast shows how the step-up authentication would look like for the admin area (admin mode):

  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 wants to go to the admin area and is asked for a reauthentication. This reauthentication can only be achieved through a step-up authentication.
  4. 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.
  5. After a successful step-up authencation, the admin mode for the user is activated and the user can access the admin area.
  6. Then, we adjust the gitlab.yml to still require the acr value gold for accessing the admin area, but we remove the omniauth setting that is necessary to trigger the step-up auth on the IdP side.
  7. This time, when we want to sign in to the admin area, the user is redirected to the IdP without the request param regarding the desired acr values => the IdP checks the user and authenticates the user successfully because no step-up is needed
  8. The IdP redirects back to the GitLab and GitLab identifies that the user does not have the required acr value "gold" (that is required to access the GitLab admin area) => hence, GitLab shows the alert that a higher auth context (acr) is required, see screenshot

https://www.loom.com/share/61b1ec67322241ea9c2daab21dac504f

How to set up and validate locally

The validation steps consist of the following three steps.

Step 1: Prepare OIDC- and ACR-compatible IdP (Keycloak)

  1. Start local keycloak instance using docker compose, see docker-compose.yml in collapsed section
Click to see `docker-compose.yml`
---

services:
  keycloak:
    image: keycloak/keycloak:25.0
    command: start-dev --log-level="org.keycloak.authentication:TRACE"
    environment:
      KEYCLOAK_ADMIN: admin 
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - 8080:8080
    volumes:
      - ./keycloak/data:/opt/keycloak/data
  1. Start the Keycloak docker container
docker compose up --force-recreate
  1. To correctly setup Keycloak, you can import the following Keycloak config: realm-export.json Or if the Keycloak config import does not work, you can manually configure Keycloak with the following steps.
  2. In Keycloak, create a new realm, e.g. step-up-auth-gitlab-realm
  3. In Keycloak, setup the LoA Mapping
Click to see screenshot grafik
6. In Keycloak, setup a custom browser flow for step-up auth
Click to see screenshot grafik
7. In Keycloak, create a client and register GitLab as an OIDC client
Click to see screenshot grafik
8. In Keycloak, add new user to the realm; Note: the user email will be necessary for a following step

Step 2: Prepare GitLab configuration

  1. In the gitlab.yml, add the following omniauth configuation, see collapsed section below
  2. In GitLab, create a new admin user; Note: user email in GitLab and in Keycloak should match
Click to expand the `gitlab.yml`
development:
  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",
          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://127.0.0.1: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: {
            enabled: true,
            documentation_link: "https://openid.net/specs/openid-connect-core-1_0.html#IDToken",
            id_token: {
              required: {
                acr: 'gold' 
              }
            },
            params: {
              claims: { id_token: { acr: { essential: true, values: ['gold'] } } }
            }
          },
          
          group_scope: {
            enabled: true,
            documentation_link: "https://openid.net/specs/openid-connect-core-1_0.html#IDToken",
            id_token: {
              required: {
                acr: 'gold' 
              }
            },
            params: {
              claims: { id_token: { acr: { essential: true, values: ['gold'] } } }
            }
          }
        }
      }
  1. Open the rails console and enable the feature flags :omniauth_step_up_auth_admin_mode and :omniauth_step_up_auth_for_group_scope
Feature.enable(:omniauth_step_up_auth_admin_mode)
Feature.enable(:omniauth_step_up_auth_for_group_scope)

Step 3: Step-up auth for admin mode

  1. Open a private browser window (in order to have a fresh session)
  2. Go to the usual 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 Keycloak sign in interface
  4. In Keycloak, submit the username and password; Note: this is the normal sign in for the user (think of it as the first step)
  5. After a successful sign in, the user will be redirected to it's dashboard
  6. Go to the reauthentication page for the admin area: http://gdk.test:3000/admin/session/new (this should be possible because the user is also an admin)
  7. Sign in with the button "[OIDC] Keycloak"; Note: this is a sepcial omniauth sign in button (as part of this POC) that will trigger the step-up auth => you will be redirected to Keycloak interface
  8. In Keycloak, you will be asked to authenticate for a higher step; Note: this is the additional step that requires higher authentication, i.e. the step-up auth
  9. After the successful second "stepped-up" sign in, the user will be redirected back to GitLab and the admin mode will be enabled

Step 4: Step-up auth for group scope

  1. Open a private browser window (in order to have a fresh session)
  2. Go to the usual 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 Keycloak sign in interface
  4. In Keycloak, submit the username and password; Note: this is the normal sign in for the user (think of it as the first step)
  5. After a successful sign in, you will be redirected to the user's dashboard
  6. Create a new group group-with-step-up-auth
  7. Go the settings of the group in section "Permissions and group features" and to the setting step-up authentication
  8. Choose the option "[OIDC] Keycloak" and save the changes
  9. After the settings are saved, you will be immediately asked to reauthenticate with the step-up requirement
  10. Use the configured Keycloak OIDC omniauth provider to sign in with step-up requirements
  11. In Keycloak, you will be asked to authenticate for a higher step; Note: this is the additional step that requires higher authentication, i.e. the step-up auth
  12. After the successful second "stepped-up" sign in, the user will be redirected back to GitLab and you are now able to access the step-up auth protected group group-with-step-up-auth

Related to #474650

Edited by Gerardo Navarro

Merge request reports

Loading