Module: Gitlab::Auth

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/ldap/user.rb,
lib/gitlab/auth/saml/user.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/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/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/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/user_access_denied_reason.rb,
lib/gitlab/auth/ldap/ldap_connection_error.rb,
lib/gitlab/auth/omniauth_identity_linker_base.rb,
lib/gitlab/auth/otp/strategies/forti_token_cloud.rb,
lib/gitlab/auth/otp/strategies/duo_auth/manual_otp.rb,
lib/gitlab/auth/otp/strategies/forti_authenticator/push_otp.rb,
lib/gitlab/auth/otp/strategies/forti_authenticator/manual_otp.rb,
lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb

Defined Under Namespace

Modules: Atlassian, AuthFinders, Crowd, Database, Devise, Ldap, OAuth, Otp, Saml Classes: Activity, BlockedUserTracker, CurrentUserMode, InsufficientScopeError, IpRateLimiter, KeyStatusChecker, OmniauthIdentityLinkerBase, RequestAuthenticator, Result, ScopeValidator, TooManyIps, TwoFactorAuthVerifier, UniqueIpsLimiter, UserAccessDeniedReason

Constant Summary collapse

MissingPersonalAccessTokenError =
Class.new(StandardError)
IpBlocked =
Class.new(StandardError)
K8S_PROXY_SCOPE =

Scopes used for GitLab internal API (Kubernetes cluster access)

:k8s_proxy
API_SCOPE =

Scopes used for GitLab API access

:api
READ_API_SCOPE =
:read_api
READ_USER_SCOPE =
:read_user
CREATE_RUNNER_SCOPE =
:create_runner
API_SCOPES =
[API_SCOPE, READ_API_SCOPE, READ_USER_SCOPE, CREATE_RUNNER_SCOPE, K8S_PROXY_SCOPE].freeze
AI_FEATURES =

Scopes for Duo

:ai_features
AI_FEATURES_SCOPES =
[AI_FEATURES].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_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
SUDO_SCOPE =

Scopes used for GitLab as admin

:sudo
ADMIN_MODE_SCOPE =
:admin_mode
ADMIN_SCOPES =
[SUDO_SCOPE, ADMIN_MODE_SCOPE].freeze
DEFAULT_SCOPES =

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

[API_SCOPE].freeze
CI_JOB_USER =
'gitlab-ci-token'
AuthenticationError =
Class.new(StandardError)
MissingTokenError =
Class.new(AuthenticationError)
TokenNotFoundError =
Class.new(AuthenticationError)
ExpiredError =
Class.new(AuthenticationError)
RevokedError =
Class.new(AuthenticationError)
ImpersonationDisabled =
Class.new(AuthenticationError)
UnauthorizedError =
Class.new(AuthenticationError)

Class Method Summary collapse

Class Method Details

.all_available_scopesObject



390
391
392
# File 'lib/gitlab/auth.rb', line 390

def all_available_scopes
  non_admin_available_scopes + ADMIN_SCOPES
end

.available_scopes_for(resource) ⇒ Object



386
387
388
# File 'lib/gitlab/auth.rb', line 386

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

.build_authentication_abilitiesObject



344
345
346
347
348
349
350
351
352
# File 'lib/gitlab/auth.rb', line 344

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

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

Raises:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/gitlab/auth.rb', line 63

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

  rate_limiter = Gitlab::Auth::IpRateLimiter.new(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) ||
    oauth_access_token_check(, password) ||
    personal_access_token_check(password, project) ||
    deploy_token_check(, password, project) ||
    user_with_password_for_git(, password) ||
    Gitlab::Auth::Result::EMPTY

  rate_limit!(rate_limiter, success: result.success?, login: )
  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) ⇒ 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.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/gitlab/auth.rb', line 101

def find_with_user_password(, password, increment_failed_attempts: false)
  # 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 = []

    if user
      authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, 'database')

      # Add authenticators for all identities if user is not nil
      user&.identities&.each do |identity|
        authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, identity.provider)
      end
    else
      # If no user is provided, try LDAP.
      #   LDAP users are only authenticated via LDAP
      authenticators << Gitlab::Auth::Ldap::Authentication
    end

    authenticators.compact!

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

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

    authenticated_user
  end
end

.full_authentication_abilitiesObject



380
381
382
383
384
# File 'lib/gitlab/auth.rb', line 380

def full_authentication_abilities
  read_write_authentication_abilities + [
    :admin_container_image
  ]
end

.omniauth_enabled?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/gitlab/auth.rb', line 59

def omniauth_enabled?
  Gitlab.config.omniauth.enabled
end

.optional_scopesObject

Other available scopes



395
396
397
# File 'lib/gitlab/auth.rb', line 395

def optional_scopes
  all_available_scopes + OPENID_SCOPES + PROFILE_SCOPES - DEFAULT_SCOPES
end

.read_only_authentication_abilitiesObject



367
368
369
370
371
# File 'lib/gitlab/auth.rb', line 367

def read_only_authentication_abilities
  read_only_project_authentication_abilities + [
    :read_container_image
  ]
end

.read_only_project_authentication_abilitiesObject



354
355
356
357
358
359
# File 'lib/gitlab/auth.rb', line 354

def read_only_project_authentication_abilities
  [
    :read_project,
    :download_code
  ]
end

.read_write_authentication_abilitiesObject



373
374
375
376
377
378
# File 'lib/gitlab/auth.rb', line 373

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

.read_write_project_authentication_abilitiesObject



361
362
363
364
365
# File 'lib/gitlab/auth.rb', line 361

def read_write_project_authentication_abilities
  read_only_project_authentication_abilities + [
    :push_code
  ]
end

.registry_scopesObject



399
400
401
402
403
# File 'lib/gitlab/auth.rb', line 399

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

  REGISTRY_SCOPES
end

.resource_bot_scopesObject



405
406
407
# File 'lib/gitlab/auth.rb', line 405

def resource_bot_scopes
  non_admin_available_scopes - [READ_USER_SCOPE]
end