Module: Gitlab::Auth::Oidc::StepUpAuthentication

Defined in:
lib/gitlab/auth/oidc/step_up_authentication.rb

Overview

Handles step-up authentication configuration and validation for OAuth providers

This module manages the configuration and validation of step-up authentication requirements for OAuth providers, particularly focusing on admin mode access.

Constant Summary collapse

SESSION_STORE_KEY =
'omniauth_step_up_auth'
SCOPE_ADMIN_MODE =
:admin_mode
SCOPE_NAMESPACE =
:namespace
ALLOWED_SCOPES =
[
  SCOPE_ADMIN_MODE,
  SCOPE_NAMESPACE
].freeze

Class Method Summary collapse

Class Method Details

.build_flow(provider:, session:, scope: SCOPE_ADMIN_MODE) ⇒ Object



82
83
84
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 82

def build_flow(provider:, session:, scope: SCOPE_ADMIN_MODE)
  Gitlab::Auth::Oidc::StepUpAuthenticationFlow.new(provider: provider, scope: scope, session: session)
end

.conditions_fulfilled?(oauth_extra_metadata:, provider:, scope: SCOPE_ADMIN_MODE) ⇒ Boolean

Validates if all step-up authentication conditions are met

Parameters:

  • oauth (OAuth2::AccessToken)

    the OAuth object to validate

  • scope (Symbol) (defaults to: SCOPE_ADMIN_MODE)

    the scope to validate conditions for (default: :admin_mode)

Returns:

  • (Boolean)

    true if all conditions are fulfilled



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 66

def conditions_fulfilled?(oauth_extra_metadata:, provider:, scope: SCOPE_ADMIN_MODE)
  conditions = []

  if has_required_claims?(provider, scope)
    conditions << required_conditions_fulfilled?(oauth_extra_metadata: ,
      provider: provider, scope: scope)
  end

  if has_included_claims?(provider, scope)
    conditions << included_conditions_fulfilled?(oauth_extra_metadata: ,
      provider: provider, scope: scope)
  end

  conditions.present? && conditions.all?
end

.disable_step_up_authentication!(session:, scope: SCOPE_ADMIN_MODE) ⇒ Object



104
105
106
107
108
109
110
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 104

def disable_step_up_authentication!(session:, scope: SCOPE_ADMIN_MODE)
  omniauth_step_up_auth_session_data(session)
            &.to_h
            &.each_value do |step_up_auth_object|
              step_up_auth_object.delete(scope.to_s)
            end
end

.enabled_by_config?(scope: SCOPE_ADMIN_MODE) ⇒ Boolean

Checks if step-up authentication is enabled for the step-up auth scope ‘admin_mode’

Returns:

  • (Boolean)

    true if any OAuth provider requires step-up auth for admin mode



25
26
27
28
29
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 25

def enabled_by_config?(scope: SCOPE_ADMIN_MODE)
  oauth_providers.any? do |provider|
    enabled_for_provider?(provider_name: provider, scope: scope)
  end
end

.enabled_for_provider?(provider_name:, scope: SCOPE_ADMIN_MODE) ⇒ Boolean

Checks if step-up authentication configuration exists for a provider name

Parameters:

  • oauth_provider_name (String)

    the name of the OAuth provider

  • scope (Symbol) (defaults to: SCOPE_ADMIN_MODE)

    the scope to check configuration for (default: :admin_mode)

Returns:

  • (Boolean)

    true if configuration exists



36
37
38
39
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 36

def enabled_for_provider?(provider_name:, scope: SCOPE_ADMIN_MODE)
  has_required_claims?(provider_name, scope) ||
    has_included_claims?(provider_name, scope)
end

.enabled_providers(scope: SCOPE_ADMIN_MODE) ⇒ Object



41
42
43
44
45
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 41

def enabled_providers(scope: SCOPE_ADMIN_MODE)
  oauth_providers.select do |provider|
    enabled_for_provider?(provider_name: provider, scope: scope)
  end
end

.failed_step_up_auth_flows(session, scope: SCOPE_ADMIN_MODE) ⇒ Array<StepUpAuthenticationFlow>

Returns step-up authentication flows that have failed

Parameters:

  • session (Hash)

    the session hash containing authentication state

  • scope (Symbol) (defaults to: SCOPE_ADMIN_MODE)

    the scope to check (default: :admin_mode)

Returns:



117
118
119
120
121
122
123
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 117

def failed_step_up_auth_flows(session, scope: SCOPE_ADMIN_MODE)
  (step_up_auth_flows(session) || []).select do |flow|
    flow.enabled_by_config? &&
      flow.failed? &&
      flow.scope.to_s == scope.to_s
  end
end

.omniauth_step_up_auth_session_data(session) ⇒ Object



100
101
102
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 100

def omniauth_step_up_auth_session_data(session)
  Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY, session)
end

.slice_relevant_id_token_claims(oauth_raw_info:, provider:, scope: SCOPE_ADMIN_MODE) ⇒ Hash

Slices the relevant ID token claims from the provided OAuth raw information.

Parameters:

  • oauth_raw_info (Hash)

    The raw information received from the OAuth provider.

  • provider (String)

    The name of the OAuth provider.

  • scope (String) (defaults to: SCOPE_ADMIN_MODE)

    The scope of the authentication request, default is SCOPE_ADMIN_MODE.

Returns:

  • (Hash)

    A hash containing only the relevant ID token claims.



92
93
94
95
96
97
98
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 92

def slice_relevant_id_token_claims(oauth_raw_info:, provider:, scope: SCOPE_ADMIN_MODE)
  relevant_id_token_claims = [
    *get_id_token_claims_required_conditions(provider, scope)&.keys,
    *get_id_token_claims_included_conditions(provider, scope)&.keys
  ]
  oauth_raw_info.slice(*relevant_id_token_claims, 'exp')
end

.step_up_session_expired?(session, scope: SCOPE_ADMIN_MODE) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
130
131
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 125

def step_up_session_expired?(session, scope: SCOPE_ADMIN_MODE)
  (step_up_auth_flows(session) || []).any? do |flow|
    flow.enabled_by_config? &&
      flow.expired? &&
      flow.scope.to_s == scope.to_s
  end
end

.succeeded?(session, scope: SCOPE_ADMIN_MODE) ⇒ Boolean

Verifies if step-up authentication has succeeded for any provider with the step-up auth scope ‘admin_mode’

Parameters:

  • session (Hash)

    the session hash containing authentication state

Returns:

  • (Boolean)

    true if step-up authentication is authenticated and not expired



52
53
54
55
56
57
58
59
# File 'lib/gitlab/auth/oidc/step_up_authentication.rb', line 52

def succeeded?(session, scope: SCOPE_ADMIN_MODE)
  step_up_auth_flows(session)
    .select do |step_up_auth_flow|
      step_up_auth_flow.scope.to_s == scope.to_s
    end
    .select(&:enabled_by_config?)
    .any?(&:succeeded?)
end