Revise the :read_job_artifacts capability in the build_policy to depend solely on the job artifacts accessibility attribute.
This issue is a blocker for Rollout of non_public_aritfacts - #294503 (comment 1608645832)
The feature flag non_public_artifacts is disabled on SaaS for the non-performant reason.
We made the following improvements:
- MR - Persist artifacts:public to Ci::JobArtifact table
- MR - Fix artifacts:public accessiblity parameter
The main goal of improvements is to persist aritfacts:public in DB and avoid expensive deep calls to options in order to read the expected access level.
Retaining the 'read_job_artifacts' policy on the build/job level still allows for resource-intensive deep calls and blocks non_public_artifacts rollout.
All the references for :read_job_artifacts on build/job level:
We have the following references for the BuildPolicy on :read_job_artifacts ability in our codebase:
expose :artifact, if: -> (*) { can?(current_user, :read_job_artifacts, build) } do
expose :download_path
...
expose :browse_path
...
expose :keep_path
...
expose :expire_at
...
expose :expired
...
expose :locked
...
end
BuildDetailsEntity serializer used only in one place:
represented:
format.json do
Gitlab::PollingInterval.set_header(response, interval: 10_000)
render json: Ci::JobSerializer
.new(project: @project, current_user: @current_user)
.represent(@build.present(current_user: current_user), {}, BuildDetailsEntity)
end
-
get ':id/jobs/artifacts/:ref_name/download', urgency: :low, requirements: { ref_name: /.+/ } do authorize_download_artifacts! latest_build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name]) authorize_read_job_artifacts!(latest_build) ... endget ':id/jobs/artifacts/:ref_name/raw/*artifact_path', urgency: :low, format: false, requirements: { ref_name: /.+/ } do authorize_download_artifacts! build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name]) authorize_read_job_artifacts!(build) ...get ':id/jobs/:job_id/artifacts', urgency: :low do authorize_download_artifacts! build = find_build!(params[:job_id]) authorize_read_job_artifacts!(build) present_artifacts_file!(build.artifacts_file) endget ':id/jobs/:job_id/artifacts/*artifact_path', urgency: :low, format: false do authorize_download_artifacts! build = find_build!(params[:job_id]) authorize_read_job_artifacts!(build) ...
For every API request where we still have authorize_read_job_artifacts
def authorize_read_job_artifacts!(build)
authorize! :read_job_artifacts, build
end