Module: Gitlab::Auth

Extended by:
InternalEventsTracking
Defined in:
lib/gitlab/auth.rb,
lib/gitlab/auth/result.rb,
lib/gitlab/auth/ldap/dn.rb,
lib/gitlab/auth/activity.rb,
lib/gitlab/auth/identity.rb,
lib/gitlab/auth/ldap/user.rb,
lib/gitlab/auth/saml/user.rb,
lib/gitlab/auth/dpop_token.rb,
lib/gitlab/auth/ip_blocked.rb,
lib/gitlab/auth/ldap/access.rb,
lib/gitlab/auth/ldap/config.rb,
lib/gitlab/auth/ldap/person.rb,
lib/gitlab/auth/o_auth/user.rb,
lib/gitlab/auth/saml/config.rb,
lib/gitlab/auth/auth_finders.rb,
lib/gitlab/auth/ldap/adapter.rb,
lib/gitlab/auth/otp/duo_auth.rb,
lib/gitlab/auth/otp/fortinet.rb,
lib/gitlab/auth/too_many_ips.rb,
lib/gitlab/auth/atlassian/user.rb,
lib/gitlab/auth/ldap/auth_hash.rb,
lib/gitlab/auth/saml/auth_hash.rb,
lib/gitlab/auth/dpop_token_user.rb,
lib/gitlab/auth/ip_rate_limiter.rb,
lib/gitlab/auth/o_auth/provider.rb,
lib/gitlab/auth/scope_validator.rb,
lib/gitlab/auth/o_auth/auth_hash.rb,
lib/gitlab/auth/visitor_location.rb,
lib/gitlab/auth/current_user_mode.rb,
lib/gitlab/auth/key_status_checker.rb,
lib/gitlab/auth/unique_ips_limiter.rb,
lib/gitlab/auth/atlassian/auth_hash.rb,
lib/gitlab/auth/jwt/identity_linker.rb,
lib/gitlab/auth/ldap/authentication.rb,
lib/gitlab/auth/otp/strategies/base.rb,
lib/gitlab/auth/blocked_user_tracker.rb,
lib/gitlab/auth/crowd/authentication.rb,
lib/gitlab/auth/saml/identity_linker.rb,
lib/gitlab/auth/o_auth/authentication.rb,
lib/gitlab/auth/otp/strategies/devise.rb,
lib/gitlab/auth/request_authenticator.rb,
lib/gitlab/auth/saml/origin_validator.rb,
lib/gitlab/auth/o_auth/identity_linker.rb,
lib/gitlab/auth/database/authentication.rb,
lib/gitlab/auth/two_factor_auth_verifier.rb,
lib/gitlab/auth/atlassian/identity_linker.rb,
lib/gitlab/auth/atlassian/token_refresher.rb,
lib/gitlab/auth/user_access_denied_reason.rb,
lib/gitlab/auth/ldap/ldap_connection_error.rb,
lib/gitlab/auth/external_username_sanitizer.rb,
lib/gitlab/auth/oidc/step_up_authentication.rb,
lib/gitlab/auth/omniauth_identity_linker_base.rb,
lib/gitlab/auth/oidc/step_up_authentication_flow.rb,
lib/gitlab/auth/otp/strategies/forti_token_cloud.rb,
lib/gitlab/auth/session_expire_from_init_enforcer.rb,
lib/gitlab/auth/otp/strategies/duo_auth/manual_otp.rb,
lib/gitlab/auth/oidc/step_up_auth_before_request_phase.rb,
lib/gitlab/auth/oidc/step_up_auth_expiration_validator.rb,
lib/gitlab/auth/editor_extensions/language_server_client.rb,
lib/gitlab/auth/otp/strategies/forti_authenticator/push_otp.rb,
lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver.rb,
lib/gitlab/auth/otp/strategies/forti_authenticator/manual_otp.rb,
lib/gitlab/auth/editor_extensions/language_server_client_verifier.rb,
lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb,
lib/gitlab/auth/o_auth/before_request_phase_oauth_login_counter_increment.rb

Defined Under Namespace

Modules: Atlassian, AuthFinders, Crowd, Database, Devise, EditorExtensions, Jwt, Ldap, OAuth, Oidc, Otp, Saml Classes: Activity, BlockedUserTracker, CurrentUserMode, DpopToken, DpopTokenUser, DpopValidationError, ExternalUsernameSanitizer, Identity, InsufficientScopeError, IpBlocked, IpRateLimiter, KeyStatusChecker, OmniauthIdentityLinkerBase, RequestAuthenticator, RestrictedLanguageServerClientError, Result, ScopeValidator, SessionExpireFromInitEnforcer, TooManyIps, TwoFactorAuthVerifier, UniqueIpsLimiter, UserAccessDeniedReason, VisitorLocation

Constant Summary collapse

MissingPersonalAccessTokenError =
Class.new(StandardError)
K8S_PROXY_SCOPE =

Scopes used for GitLab internal API (Kubernetes cluster access)

:k8s_proxy
SELF_ROTATE_SCOPE =

Scopes used for token allowed to rotate themselves

:self_rotate
API_SCOPE =

Scopes used for GitLab API access

:api
READ_API_SCOPE =
:read_api
READ_USER_SCOPE =
:read_user
CREATE_RUNNER_SCOPE =
:create_runner
MANAGE_RUNNER_SCOPE =
:manage_runner
MCP_SCOPE =
:mcp
GRANULAR_SCOPE =
:granular
API_SCOPES =
[
  API_SCOPE, READ_API_SCOPE,
  READ_USER_SCOPE,
  CREATE_RUNNER_SCOPE, MANAGE_RUNNER_SCOPE,
  K8S_PROXY_SCOPE,
  SELF_ROTATE_SCOPE,
  MCP_SCOPE,
  GRANULAR_SCOPE
].freeze
AI_FEATURES =

Scopes for Duo

:ai_features
AI_FEATURES_SCOPES =
[AI_FEATURES].freeze
AI_WORKFLOW =
:ai_workflows
AI_WORKFLOW_SCOPES =
[AI_WORKFLOW].freeze
DYNAMIC_USER =
:"user:*"
DYNAMIC_SCOPES =
[DYNAMIC_USER].freeze
PROFILE_SCOPE =
:profile
EMAIL_SCOPE =
:email
OPENID_SCOPE =
:openid
OPENID_SCOPES =

Scopes used for OpenID Connect

[OPENID_SCOPE].freeze
PROFILE_SCOPES =

OpenID Connect profile scopes

[PROFILE_SCOPE, EMAIL_SCOPE].freeze
READ_REPOSITORY_SCOPE =

Scopes used for GitLab Repository access

:read_repository
WRITE_REPOSITORY_SCOPE =
:write_repository
REPOSITORY_SCOPES =
[READ_REPOSITORY_SCOPE, WRITE_REPOSITORY_SCOPE].freeze
READ_REGISTRY_SCOPE =

Scopes used for GitLab Docker Registry access

:read_registry
WRITE_REGISTRY_SCOPE =
:write_registry
REGISTRY_SCOPES =
[READ_REGISTRY_SCOPE, WRITE_REGISTRY_SCOPE].freeze
READ_VIRTUAL_REGISTRY_SCOPE =

Scopes used for Virtual Registry access

:read_virtual_registry
WRITE_VIRTUAL_REGISTRY_SCOPE =
:write_virtual_registry
VIRTUAL_REGISTRY_SCOPES =
[
  READ_VIRTUAL_REGISTRY_SCOPE, WRITE_VIRTUAL_REGISTRY_SCOPE
].freeze
READ_OBSERVABILITY_SCOPE =

Scopes used for GitLab Observability access which is outside of the GitLab app itself. Hence the lack of ability mapping in abilities_for_scopes.

:read_observability
WRITE_OBSERVABILITY_SCOPE =
:write_observability
OBSERVABILITY_SCOPES =
[READ_OBSERVABILITY_SCOPE, WRITE_OBSERVABILITY_SCOPE].freeze
READ_SERVICE_PING_SCOPE =

Scopes for Monitor access

:read_service_ping
SUDO_SCOPE =

Scopes used for GitLab as admin

:sudo
ADMIN_MODE_SCOPE =
:admin_mode
ADMIN_SCOPES =
[SUDO_SCOPE, ADMIN_MODE_SCOPE, READ_SERVICE_PING_SCOPE].freeze
Q_SCOPES =
[API_SCOPE, REPOSITORY_SCOPES].flatten.freeze
DEFAULT_SCOPES =

Default scopes for OAuth applications that don’t define their own

[API_SCOPE].freeze
UI_SCOPES_ORDERED_BY_PERMISSION =

Scopes ordered by permission level, from lowest to highest. This is used to determine the order of scopes in the UI. If the scope is not present in this list, it won’t appear in the UI.

[
  READ_SERVICE_PING_SCOPE,
  READ_USER_SCOPE,
  READ_REPOSITORY_SCOPE,
  READ_OBSERVABILITY_SCOPE,
  READ_VIRTUAL_REGISTRY_SCOPE,
  READ_REGISTRY_SCOPE,
  READ_API_SCOPE,
  SELF_ROTATE_SCOPE,
  WRITE_REPOSITORY_SCOPE,
  WRITE_OBSERVABILITY_SCOPE,
  WRITE_VIRTUAL_REGISTRY_SCOPE,
  WRITE_REGISTRY_SCOPE,
  API_SCOPE,
  AI_FEATURES,
  CREATE_RUNNER_SCOPE,
  MANAGE_RUNNER_SCOPE,
  K8S_PROXY_SCOPE,
  ADMIN_MODE_SCOPE,
  SUDO_SCOPE
].freeze
CI_JOB_USER =
'gitlab-ci-token'
AuthenticationError =
Class.new(StandardError)
MissingTokenError =
Class.new(AuthenticationError)
InvalidTokenError =
Class.new(AuthenticationError)
TokenNotFoundError =
Class.new(AuthenticationError)
ExpiredError =
Class.new(AuthenticationError)
RevokedError =
Class.new(AuthenticationError)
ImpersonationDisabled =
Class.new(AuthenticationError)
UnauthorizedError =
Class.new(AuthenticationError)
GranularPermissionsError =
Class.new(AuthenticationError)

Class Method Summary collapse

Methods included from InternalEventsTracking

track_internal_event

Class Method Details

.all_available_scopesObject



477
478
479
# File 'lib/gitlab/auth.rb', line 477

def all_available_scopes
  non_admin_available_scopes + ADMIN_SCOPES
end

.available_scopes_for(resource) ⇒ Object



473
474
475
# File 'lib/gitlab/auth.rb', line 473

def available_scopes_for(resource)
  available_scopes_for_resource(resource) - unavailable_scopes_for_resource(resource)
end

.build_authentication_abilitiesObject



430
431
432
433
434
435
436
437
438
439
# File 'lib/gitlab/auth.rb', line 430

def build_authentication_abilities
  [
    :read_project,
    :build_download_code,
    :build_push_code,
    :build_read_container_image,
    :build_create_container_image,
    :build_destroy_container_image
  ]
end

.find_for_git_client(login, password, project:, request:) ⇒ Object

Raises:



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/gitlab/auth.rb', line 119

def find_for_git_client(, password, project:, request:)
  raise "Must provide an IP for rate limiting" if request.ip.nil?

  rate_limiter = Gitlab::Auth::IpRateLimiter.new(request.ip)

  raise IpBlocked if !skip_rate_limit?(login: ) && rate_limiter.banned?

  # `user_with_password_for_git` should be the last check
  # because it's the most expensive, especially when LDAP
  # is enabled.
  result =
    service_request_check(, password, project) ||
    build_access_token_check(, password) ||
    lfs_token_check(, password, project, request) ||
    oauth_access_token_check(password) ||
    personal_access_token_check(password, project) ||
    deploy_token_check(, password, project) ||
    user_with_password_for_git(, password, request: request) ||
    Gitlab::Auth::Result::EMPTY

  rate_limit!(rate_limiter, success: result.success?, login: , request: request)
  look_to_limit_user(result.actor)

  return result if result.success? || authenticate_using_internal_or_ldap_password?

  # If sign-in is disabled and LDAP is not configured, recommend a
  # personal access token on failed auth attempts
  raise Gitlab::Auth::MissingPersonalAccessTokenError
end

.find_with_user_password(login, password, increment_failed_attempts: false, request: nil) ⇒ Object

Find and return a user if the provided password is valid for various authenticators (OAuth, LDAP, Local Database).

Specify ‘increment_failed_attempts: true` to increment Devise failed_attempts. CAUTION: Avoid incrementing failed attempts when authentication falls through different mechanisms, as in .find_for_git_client. This may lead to unwanted access locks when the value provided for password was actually a PAT, deploy token, etc.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/gitlab/auth.rb', line 157

def find_with_user_password(, password, increment_failed_attempts: false, request: nil)
  # Avoid resource intensive checks if login credentials are not provided
  return unless .present? && password.present?

  # Nothing to do here if internal auth is disabled and LDAP is
  # not configured
  return unless authenticate_using_internal_or_ldap_password?

  Gitlab::Auth::UniqueIpsLimiter.limit_user! do
    user = User.()

    break if user && !user.

    authenticators = password_authenticators_for_user(user)

    # return found user that was authenticated first for given login credentials
    authenticated_user, authenticator = authenticators.find do |authenticator|
      authenticated_user = authenticator.(, password)
      break authenticated_user, authenticator if authenticated_user
    end

    user_auth_attempt!(user, success: !!authenticated_user) if increment_failed_attempts

    # Increase our visibility of authentication methods
    if !!authenticated_user
      # To mitigate the risk of large log volume we will log
      # only when request is present, and use a Feature Flag with
      # the request actor.
      if request.present? && Feature.enabled?(:log_find_with_user_password, Feature.current_request)
        log_authentication('Gitlab::Auth find_with_user_password succeeded', authenticated_user, authenticator, request: request)
      end
    end

    authenticated_user
  end
end

.full_authentication_abilitiesObject



467
468
469
470
471
# File 'lib/gitlab/auth.rb', line 467

def full_authentication_abilities
  read_write_authentication_abilities + [
    :admin_container_image
  ]
end

.omniauth_enabled?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/gitlab/auth.rb', line 115

def omniauth_enabled?
  Gitlab.config.omniauth.enabled
end

.optional_scopesObject

Other available scopes



482
483
484
485
# File 'lib/gitlab/auth.rb', line 482

def optional_scopes
  all_available_scopes + OPENID_SCOPES + PROFILE_SCOPES + AI_WORKFLOW_SCOPES + DYNAMIC_SCOPES - DEFAULT_SCOPES -
    [GRANULAR_SCOPE]
end

.read_only_authentication_abilitiesObject



454
455
456
457
458
# File 'lib/gitlab/auth.rb', line 454

def read_only_authentication_abilities
  read_only_project_authentication_abilities + [
    :read_container_image
  ]
end

.read_only_project_authentication_abilitiesObject



441
442
443
444
445
446
# File 'lib/gitlab/auth.rb', line 441

def read_only_project_authentication_abilities
  [
    :read_project,
    :download_code
  ]
end

.read_write_authentication_abilitiesObject



460
461
462
463
464
465
# File 'lib/gitlab/auth.rb', line 460

def read_write_authentication_abilities
  read_only_authentication_abilities + [
    :push_code,
    :create_container_image
  ]
end

.read_write_project_authentication_abilitiesObject



448
449
450
451
452
# File 'lib/gitlab/auth.rb', line 448

def read_write_project_authentication_abilities
  read_only_project_authentication_abilities + [
    :push_code
  ]
end

.registry_scopesObject



487
488
489
490
491
# File 'lib/gitlab/auth.rb', line 487

def registry_scopes
  return [] unless Gitlab.config.registry.enabled

  REGISTRY_SCOPES
end

.resource_bot_scopesObject



499
500
501
# File 'lib/gitlab/auth.rb', line 499

def resource_bot_scopes
  non_admin_available_scopes - [READ_USER_SCOPE]
end

.virtual_registry_scopesObject



493
494
495
496
497
# File 'lib/gitlab/auth.rb', line 493

def virtual_registry_scopes
  return [] unless Gitlab.config.dependency_proxy.enabled

  VIRTUAL_REGISTRY_SCOPES
end