diff options
Diffstat (limited to 'app/models/ci/job_token/scope.rb')
-rw-r--r-- | app/models/ci/job_token/scope.rb | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/app/models/ci/job_token/scope.rb b/app/models/ci/job_token/scope.rb index 1aa49b95201..e320c0f92d1 100644 --- a/app/models/ci/job_token/scope.rb +++ b/app/models/ci/job_token/scope.rb @@ -1,49 +1,58 @@ # frozen_string_literal: true -# This model represents the surface where a CI_JOB_TOKEN can be used. -# A Scope is initialized with the project that the job token belongs to, -# and indicates what are all the other projects that the token could access. +# This model represents the scope of access for a CI_JOB_TOKEN. # -# By default a job token can only access its own project, which is the same -# project that defines the scope. -# By adding ScopeLinks to the scope we can allow other projects to be accessed -# by the job token. This works as an allowlist of projects for a job token. +# A scope is initialized with a project. +# +# Projects can be added to the scope by adding ScopeLinks to +# create an allowlist of projects in either access direction (inbound, outbound). +# +# Currently, projects in the outbound allowlist can be accessed via the token +# in the source project. +# +# TODO(Issue #346298) Projects in the inbound allowlist can use their token to access +# the source project. +# +# CI_JOB_TOKEN should be considered untrusted without these features enabled. # -# If a project is not included in the scope we should not allow the job user -# to access it since operations using CI_JOB_TOKEN should be considered untrusted. module Ci module JobToken class Scope - attr_reader :source_project + attr_reader :current_project - def initialize(project) - @source_project = project + def initialize(current_project) + @current_project = current_project end - def includes?(target_project) - # if the setting is disabled any project is considered to be in scope. - return true unless source_project.ci_outbound_job_token_scope_enabled? + def allows?(accessed_project) + self_referential?(accessed_project) || outbound_allows?(accessed_project) + end - target_project.id == source_project.id || - Ci::JobToken::ProjectScopeLink.from_project(source_project).to_project(target_project).exists? + def outbound_projects + outbound_allowlist.projects end + # Deprecated: use outbound_projects, TODO(Issue #346298) remove references to all_project def all_projects - Project.from_union(target_projects, remove_duplicates: false) + outbound_projects end private - def target_project_ids - Ci::JobToken::ProjectScopeLink.from_project(source_project).pluck(:target_project_id) + def outbound_allows?(accessed_project) + # if the setting is disabled any project is considered to be in scope. + return true unless @current_project.ci_outbound_job_token_scope_enabled? + + outbound_allowlist.includes?(accessed_project) + end + + def outbound_allowlist + Ci::JobToken::Allowlist.new(@current_project, direction: :outbound) end - def target_projects - [ - Project.id_in(source_project), - Project.id_in(target_project_ids) - ] + def self_referential?(accessed_project) + @current_project.id == accessed_project.id end end end |