From ae92ff770c180ef1787d9675ad84cf702f3f6e48 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Fri, 8 Nov 2024 00:27:00 -1000 Subject: [PATCH 01/14] Add jobTokenPolicies to GraphQL root query --- .../job_token_policy_category_type.rb | 19 ++ .../job_token_scope/job_token_policy_type.rb | 19 ++ .../types/ci/job_token_scope/policies_enum.rb | 4 +- .../job_token_scope/policy_categories_enum.rb | 16 ++ .../ci/job_token_scope/policy_types_enum.rb | 15 ++ app/graphql/types/query_type.rb | 8 + .../json_schemas/ci_job_token_policies.json | 47 ++--- doc/api/graphql/reference/index.md | 111 ++++++++---- lib/ci/job_token/policies.rb | 162 +++++++++++++----- .../job_token_policy_category_type_spec.rb | 8 + .../job_token_policy_type_spec.rb | 8 + .../ci/job_token_scope/policies_enum_spec.rb | 51 ++---- .../policy_categories_enum_spec.rb | 18 ++ .../job_token_scope/policy_types_enum_spec.rb | 12 ++ spec/graphql/types/query_type_spec.rb | 8 + 15 files changed, 358 insertions(+), 148 deletions(-) create mode 100644 app/graphql/types/ci/job_token_scope/job_token_policy_category_type.rb create mode 100644 app/graphql/types/ci/job_token_scope/job_token_policy_type.rb create mode 100644 app/graphql/types/ci/job_token_scope/policy_categories_enum.rb create mode 100644 app/graphql/types/ci/job_token_scope/policy_types_enum.rb create mode 100644 spec/graphql/types/ci/job_token_scope/job_token_policy_category_type_spec.rb create mode 100644 spec/graphql/types/ci/job_token_scope/job_token_policy_type_spec.rb create mode 100644 spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb create mode 100644 spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb diff --git a/app/graphql/types/ci/job_token_scope/job_token_policy_category_type.rb b/app/graphql/types/ci/job_token_scope/job_token_policy_category_type.rb new file mode 100644 index 00000000000000..31a013f8888d34 --- /dev/null +++ b/app/graphql/types/ci/job_token_scope/job_token_policy_category_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + module Ci + module JobTokenScope + # rubocop: disable Graphql/AuthorizeTypes -- this is static data + class JobTokenPolicyCategoryType < BaseObject + graphql_name 'JobTokenPolicyCategory' + description 'Job token policy category type' + + field :description, GraphQL::Types::String, description: 'Description of the category.' + field :policies, [Types::Ci::JobTokenScope::JobTokenPolicyType], description: 'Policies of the category.' + field :text, GraphQL::Types::String, description: 'Display text of the category.' + field :value, Types::Ci::JobTokenScope::PolicyCategoriesEnum, description: 'Value of the category.' + end + # rubocop: enable Graphql/AuthorizeTypes + end + end +end diff --git a/app/graphql/types/ci/job_token_scope/job_token_policy_type.rb b/app/graphql/types/ci/job_token_scope/job_token_policy_type.rb new file mode 100644 index 00000000000000..b31255550ff4a6 --- /dev/null +++ b/app/graphql/types/ci/job_token_scope/job_token_policy_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + module Ci + module JobTokenScope + # rubocop: disable Graphql/AuthorizeTypes -- this is static data + class JobTokenPolicyType < BaseObject + graphql_name 'JobTokenPolicy' + description 'Job token policy' + + field :description, GraphQL::Types::String, description: 'Description of the job token policy.' + field :text, GraphQL::Types::String, description: 'Display text of the job token policy.' + field :type, Types::Ci::JobTokenScope::PolicyTypesEnum, description: 'Job token policy type.' + field :value, Types::Ci::JobTokenScope::PoliciesEnum, description: 'Value of the job token policy.' + end + # rubocop: enable Graphql/AuthorizeTypes + end + end +end diff --git a/app/graphql/types/ci/job_token_scope/policies_enum.rb b/app/graphql/types/ci/job_token_scope/policies_enum.rb index 88ed8612f54d4f..be4abc61d5a71f 100644 --- a/app/graphql/types/ci/job_token_scope/policies_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policies_enum.rb @@ -7,8 +7,8 @@ class PoliciesEnum < BaseEnum graphql_name 'CiJobTokenScopePolicies' description 'CI_JOB_TOKEN policy' - ::Ci::JobToken::Policies.all_values.each do |policy| - value policy.upcase, value: policy, description: policy.titleize + ::Ci::JobToken::Policies.all_policies.each do |policy| + value policy[:value].to_s.upcase, value: policy[:value], description: policy[:description] end end end diff --git a/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb new file mode 100644 index 00000000000000..c5c75876c1670a --- /dev/null +++ b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module Ci + module JobTokenScope + class PolicyCategoriesEnum < BaseEnum + graphql_name 'CiJobTokenScopePolicyCategoriesTypes' + description 'CI_JOB_TOKEN policy category type' + + ::Ci::JobToken::Policies.policy_categories.each do |category| + value category[:value].to_s.upcase, value: category[:value], description: category[:description] + end + end + end + end +end diff --git a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb new file mode 100644 index 00000000000000..110db2cd82f965 --- /dev/null +++ b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ci + module JobTokenScope + class PolicyTypesEnum < BaseEnum + graphql_name 'CiJobTokenScopePolicyTypes' + description 'CI_JOB_TOKEN policy type' + + value 'READ', value: :read, description: 'Read only access to resource.' + value 'ADMIN', value: :admin, description: 'Admin access access to resource.' + end + end + end +end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 781da8778513ef..0cce3dd5aabd38 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -245,6 +245,10 @@ class QueryType < ::Types::BaseObject description: 'Check if a feature flag is enabled', resolver: Resolvers::FeatureFlagResolver + field :job_token_policies, [::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType], + description: 'List of job token policies for use with fine-grained permissions on CI/CD job allowlist.', + experiment: { milestone: '17.6' } + def design_management DesignManagementObject.new(nil) end @@ -298,6 +302,10 @@ def ci_pipeline_stage(id:) stage end + + def job_token_policies + ::Ci::JobToken::Policies.policy_categories + end end end diff --git a/app/validators/json_schemas/ci_job_token_policies.json b/app/validators/json_schemas/ci_job_token_policies.json index 3da0d8b309ac55..b5d2d37aa267c6 100644 --- a/app/validators/json_schemas/ci_job_token_policies.json +++ b/app/validators/json_schemas/ci_job_token_policies.json @@ -5,41 +5,22 @@ "items": { "type": "string", "enum": [ - "admin_container_image", - "admin_secure_files", - "admin_terraform_state", - "build_create_container_image", - "build_destroy_container_image", - "build_download_code", - "build_push_code", - "build_read_container_image", - "create_deployment", - "create_environment", - "create_on_demand_dast_scan", - "create_package", - "create_release", - "destroy_container_image", - "destroy_deployment", - "destroy_environment", - "destroy_package", - "destroy_release", - "read_build", - "read_container_image", - "read_deployment", - "read_environment", - "read_group", - "read_job_artifacts", - "read_package", - "read_pipeline", - "read_project", - "read_release", + "read_containers", + "admin_containers", + "read_deployments", + "admin_deployments", + "read_environments", + "admin_environments", + "read_jobs", + "admin_jobs", + "read_packages", + "admin_packages", + "read_releases", + "admin_releases", "read_secure_files", + "admin_secure_files", "read_terraform_state", - "stop_environment", - "update_deployment", - "update_environment", - "update_pipeline", - "update_release" + "admin_terraform_state" ] }, "uniqueItems": true, diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 004652f747cafa..4c91ffd9ce6f9e 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -725,6 +725,16 @@ Returns [`Iteration`](#iteration). | ---- | ---- | ----------- | | `id` | [`IterationID!`](#iterationid) | Find an iteration by its ID. | +### `Query.jobTokenPolicies` + +List of job token policies for use with fine-grained permissions on CI/CD job allowlist. + +DETAILS: +**Introduced** in GitLab 17.6. +**Status**: Experiment. + +Returns [`[JobTokenPolicyCategory!]`](#jobtokenpolicycategory). + ### `Query.jobs` All jobs on this GitLab instance. Returns an empty result for users without administrator access. @@ -26798,6 +26808,32 @@ Represents the Geo replication and verification state of a job_artifact. | `readJobArtifacts` | [`Boolean!`](#boolean) | If `true`, the user can perform `read_job_artifacts` on this resource. | | `updateBuild` | [`Boolean!`](#boolean) | If `true`, the user can perform `update_build` on this resource. | +### `JobTokenPolicy` + +Job token policy. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `description` | [`String`](#string) | Description of the job token policy. | +| `text` | [`String`](#string) | Display text of the job token policy. | +| `type` | [`CiJobTokenScopePolicyTypes`](#cijobtokenscopepolicytypes) | Job token policy type. | +| `value` | [`CiJobTokenScopePolicies`](#cijobtokenscopepolicies) | Value of the job token policy. | + +### `JobTokenPolicyCategory` + +Job token policy category type. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `description` | [`String`](#string) | Description of the category. | +| `policies` | [`[JobTokenPolicy!]`](#jobtokenpolicy) | Policies of the category. | +| `text` | [`String`](#string) | Display text of the category. | +| `value` | [`CiJobTokenScopePolicyCategoriesTypes`](#cijobtokenscopepolicycategoriestypes) | Value of the category. | + ### `Kas` #### Fields @@ -37879,41 +37915,46 @@ CI_JOB_TOKEN policy. | Value | Description | | ----- | ----------- | -| `ADMIN_CONTAINER_IMAGE` | Admin Container Image. | -| `ADMIN_SECURE_FILES` | Admin Secure Files. | -| `ADMIN_TERRAFORM_STATE` | Admin Terraform State. | -| `BUILD_CREATE_CONTAINER_IMAGE` | Build Create Container Image. | -| `BUILD_DESTROY_CONTAINER_IMAGE` | Build Destroy Container Image. | -| `BUILD_DOWNLOAD_CODE` | Build Download Code. | -| `BUILD_PUSH_CODE` | Build Push Code. | -| `BUILD_READ_CONTAINER_IMAGE` | Build Read Container Image. | -| `CREATE_DEPLOYMENT` | Create Deployment. | -| `CREATE_ENVIRONMENT` | Create Environment. | -| `CREATE_ON_DEMAND_DAST_SCAN` | Create On Demand Dast Scan. | -| `CREATE_PACKAGE` | Create Package. | -| `CREATE_RELEASE` | Create Release. | -| `DESTROY_CONTAINER_IMAGE` | Destroy Container Image. | -| `DESTROY_DEPLOYMENT` | Destroy Deployment. | -| `DESTROY_ENVIRONMENT` | Destroy Environment. | -| `DESTROY_PACKAGE` | Destroy Package. | -| `DESTROY_RELEASE` | Destroy Release. | -| `READ_BUILD` | Read Build. | -| `READ_CONTAINER_IMAGE` | Read Container Image. | -| `READ_DEPLOYMENT` | Read Deployment. | -| `READ_ENVIRONMENT` | Read Environment. | -| `READ_GROUP` | Read Group. | -| `READ_JOB_ARTIFACTS` | Read Job Artifacts. | -| `READ_PACKAGE` | Read Package. | -| `READ_PIPELINE` | Read Pipeline. | -| `READ_PROJECT` | Read Project. | -| `READ_RELEASE` | Read Release. | -| `READ_SECURE_FILES` | Read Secure Files. | -| `READ_TERRAFORM_STATE` | Read Terraform State. | -| `STOP_ENVIRONMENT` | Stop Environment. | -| `UPDATE_DEPLOYMENT` | Update Deployment. | -| `UPDATE_ENVIRONMENT` | Update Environment. | -| `UPDATE_PIPELINE` | Update Pipeline. | -| `UPDATE_RELEASE` | Update Release. | +| `ADMIN_CONTAINERS` | CRUD all container images in a project. | +| `ADMIN_DEPLOYMENTS` | Admin deployments. | +| `ADMIN_ENVIRONMENTS` | CRUD + Stop all environments in a project. | +| `ADMIN_JOBS` | Read all job metadata, upload artifacts and update the pipeline status. | +| `ADMIN_PACKAGES` | Admin packages. | +| `ADMIN_RELEASES` | CRUD all releases in a project. | +| `ADMIN_SECURE_FILES` | CRUD all secure files in a project. | +| `ADMIN_TERRAFORM_STATE` | CRUD all terraform state files/versions. | +| `READ_CONTAINERS` | Read all container images in a project. | +| `READ_DEPLOYMENTS` | Read all deployments in a project. | +| `READ_ENVIRONMENTS` | Read all environments in a project. | +| `READ_JOBS` | Read all job metadata and artifacts. | +| `READ_PACKAGES` | Read, create and delete packages. | +| `READ_RELEASES` | Read all releases in a project. | +| `READ_SECURE_FILES` | Read all secure files in a project. | +| `READ_TERRAFORM_STATE` | Read all terraform state files/version. | + +### `CiJobTokenScopePolicyCategoriesTypes` + +CI_JOB_TOKEN policy category type. + +| Value | Description | +| ----- | ----------- | +| `CONTAINERS` | Containers category. | +| `DEPLOYMENTS` | Deployments category. | +| `ENVIRONMENTS` | Environments category. | +| `JOBS` | Jobs category. | +| `PACKAGES` | Packages category. | +| `RELEASES` | Releases category. | +| `SECURE_FILES` | Secure files category. | +| `TERRAFORM_STATE` | Terraform state category. | + +### `CiJobTokenScopePolicyTypes` + +CI_JOB_TOKEN policy type. + +| Value | Description | +| ----- | ----------- | +| `ADMIN` | Admin access access to resource. | +| `READ` | Read only access to resource. | ### `CiRunnerAccessLevel` diff --git a/lib/ci/job_token/policies.rb b/lib/ci/job_token/policies.rb index b48926cd7555db..0a588cf8440121 100644 --- a/lib/ci/job_token/policies.rb +++ b/lib/ci/job_token/policies.rb @@ -3,52 +3,128 @@ module Ci module JobToken module Policies - # policies that every CI job token needs - FIXED = [ - :build_create_container_image, - :build_destroy_container_image, - :build_download_code, - :build_push_code, - :build_read_container_image, - :read_project - ].freeze - - # policies that can be assigned to a CI job token - ALLOWED = [ - :admin_container_image, - :admin_secure_files, - :admin_terraform_state, - :create_deployment, - :create_environment, - :create_on_demand_dast_scan, - :create_package, - :create_release, - :destroy_container_image, - :destroy_deployment, - :destroy_environment, - :destroy_package, - :destroy_release, - :read_build, - :read_container_image, - :read_deployment, - :read_environment, - :read_group, - :read_job_artifacts, - :read_package, - :read_pipeline, - :read_release, - :read_secure_files, - :read_terraform_state, - :stop_environment, - :update_deployment, - :update_environment, - :update_pipeline, - :update_release + POLICIES = [ + { + value: :containers, + text: 'Containers', + description: 'Containers category', + policies: [ + { + value: :read_containers, + type: :read, + text: 'Read', + description: 'Read all container images in a project' + }, + { + value: :admin_containers, + type: :admin, + text: 'Read and write', + description: 'CRUD all container images in a project' + } + ] + }, + { + value: :deployments, + text: 'Deployments', + description: 'Deployments category', + policies: [ + { value: :read_deployments, type: :read, text: 'Read', description: 'Read all deployments in a project' }, + { value: :admin_deployments, type: :admin, text: 'Read and write', description: 'Admin deployments' } + ] + }, + { + value: :environments, + text: 'Environments', + description: 'Environments category', + policies: [ + { value: :read_environments, type: :read, text: 'Read', description: 'Read all environments in a project' }, + { + value: :admin_environments, + type: :admin, + text: 'Read and write', + description: 'CRUD + Stop all environments in a project' + } + ] + }, + { + value: :jobs, + text: 'Jobs', + description: 'Jobs category', + policies: [ + { value: :read_jobs, type: :read, text: 'Read', description: 'Read all job metadata and artifacts' }, + { + value: :admin_jobs, + type: :admin, + text: 'Read and write', + description: 'Read all job metadata, upload artifacts and update the pipeline status' + } + ] + }, + { + value: :packages, + text: 'Packages', + description: 'Packages category', + policies: [ + { value: :read_packages, type: :read, text: 'Read', description: 'Read, create and delete packages' }, + { value: :admin_packages, type: :admin, text: 'Read and write', description: 'Admin packages' } + ] + }, + { + value: :releases, + text: 'Releases', + description: 'Releases category', + policies: [ + { value: :read_releases, type: :read, text: 'Read', description: 'Read all releases in a project' }, + { + value: :admin_releases, + type: :admin, + text: 'Read and write', + description: 'CRUD all releases in a project' + } + ] + }, + { + value: :secure_files, + text: 'Secure files', + description: 'Secure files category', + policies: [ + { value: :read_secure_files, type: :read, text: 'Read', description: 'Read all secure files in a project' }, + { + value: :admin_secure_files, + type: :admin, + text: 'Read and write', + description: 'CRUD all secure files in a project' + } + ] + }, + { + value: :terraform_state, + text: 'Terraform state', + description: 'Terraform state category', + policies: [ + { + value: :read_terraform_state, + type: :read, + text: 'Read', + description: 'Read all terraform state files/version' + }, + { + value: :admin_terraform_state, + type: :admin, + text: 'Read and write', + description: 'CRUD all terraform state files/versions' + } + ] + } ].freeze class << self - def all_values - (FIXED + ALLOWED).map(&:to_s) + def policy_categories + POLICIES + end + + def all_policies + POLICIES.flat_map { |category| category[:policies] } end end end diff --git a/spec/graphql/types/ci/job_token_scope/job_token_policy_category_type_spec.rb b/spec/graphql/types/ci/job_token_scope/job_token_policy_category_type_spec.rb new file mode 100644 index 00000000000000..80be69d715bbe0 --- /dev/null +++ b/spec/graphql/types/ci/job_token_scope/job_token_policy_category_type_spec.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType, feature_category: :secrets_management do + specify { expect(described_class.graphql_name).to eq('JobTokenPolicyCategory') } + specify { expect(described_class).to have_graphql_fields(%i[text value description policies]) } +end diff --git a/spec/graphql/types/ci/job_token_scope/job_token_policy_type_spec.rb b/spec/graphql/types/ci/job_token_scope/job_token_policy_type_spec.rb new file mode 100644 index 00000000000000..717ea0753b22f4 --- /dev/null +++ b/spec/graphql/types/ci/job_token_scope/job_token_policy_type_spec.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Types::Ci::JobTokenScope::JobTokenPolicyType, feature_category: :secrets_management do + specify { expect(described_class.graphql_name).to eq('JobTokenPolicy') } + specify { expect(described_class).to have_graphql_fields(%i[text value type description]) } +end diff --git a/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb index 17e56e7f5d243b..f5875836cd0ee2 100644 --- a/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb @@ -2,44 +2,25 @@ require 'spec_helper' -RSpec.describe GitlabSchema.types['CiJobTokenScopePolicies'], feature_category: :secrets_management do +RSpec.describe ::Types::Ci::JobTokenScope::PoliciesEnum, feature_category: :secrets_management do it 'exposes all policies' do - expect(described_class.values.keys).to contain_exactly(*%w[ - ADMIN_CONTAINER_IMAGE - ADMIN_SECURE_FILES - ADMIN_TERRAFORM_STATE - BUILD_CREATE_CONTAINER_IMAGE - BUILD_DESTROY_CONTAINER_IMAGE - BUILD_DOWNLOAD_CODE - BUILD_PUSH_CODE - BUILD_READ_CONTAINER_IMAGE - CREATE_DEPLOYMENT - CREATE_ENVIRONMENT - CREATE_ON_DEMAND_DAST_SCAN - CREATE_PACKAGE - CREATE_RELEASE - DESTROY_CONTAINER_IMAGE - DESTROY_DEPLOYMENT - DESTROY_ENVIRONMENT - DESTROY_PACKAGE - DESTROY_RELEASE - READ_BUILD - READ_CONTAINER_IMAGE - READ_DEPLOYMENT - READ_ENVIRONMENT - READ_GROUP - READ_JOB_ARTIFACTS - READ_PACKAGE - READ_PIPELINE - READ_PROJECT - READ_RELEASE + expect(described_class.values.keys).to match_array(*%w[ + READ_CONTAINERS + ADMIN_CONTAINERS + READ_DEPLOYMENTS + ADMIN_DEPLOYMENTS + READ_ENVIRONMENTS + ADMIN_ENVIRONMENTS + READ_JOBS + ADMIN_JOBS + READ_PACKAGES + ADMIN_PACKAGES + READ_RELEASES + ADMIN_RELEASES READ_SECURE_FILES + ADMIN_SECURE_FILES READ_TERRAFORM_STATE - STOP_ENVIRONMENT - UPDATE_DEPLOYMENT - UPDATE_ENVIRONMENT - UPDATE_PIPELINE - UPDATE_RELEASE + ADMIN_TERRAFORM_STATE ]) end end diff --git a/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb new file mode 100644 index 00000000000000..5ba6883ed70564 --- /dev/null +++ b/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Types::Ci::JobTokenScope::PolicyCategoriesEnum, feature_category: :secrets_management do + it 'exposes all categories' do + expect(described_class.values.keys).to match_array(*%w[ + CONTAINERS + DEPLOYMENTS + ENVIRONMENTS + JOBS + PACKAGES + RELEASES + SECURE_FILES + TERRAFORM_STATE + ]) + end +end diff --git a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb new file mode 100644 index 00000000000000..2248bb9f6114df --- /dev/null +++ b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Types::Ci::JobTokenScope::PolicyTypesEnum, feature_category: :secrets_management do + it 'the correct enum members' do + expect(described_class.values).to match( + 'READ' => have_attributes(value: :read, description: 'Read only access to resource.'), + 'ADMIN' => have_attributes(value: :admin, description: 'Admin access access to resource.') + ) + end +end diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index 74e9522c16c7cd..bab3c4c8132cca 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -177,4 +177,12 @@ is_expected.to have_graphql_resolver(Resolvers::FeatureFlagResolver) end end + + describe 'jobTokenPolicyCategories field' do + subject { described_class.fields['jobTokenPolicies'] } + + it 'returns job token policies', :aggregate_failures do + is_expected.to have_graphql_type(::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType) + end + end end -- GitLab From 8861bbd0b04f60e932d27f600cdf2ef9a9cc048a Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Thu, 14 Nov 2024 16:18:53 -1000 Subject: [PATCH 02/14] Fix broken tests --- spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb | 2 +- .../types/ci/job_token_scope/policy_categories_enum_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb index f5875836cd0ee2..1dd215a18074fe 100644 --- a/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policies_enum_spec.rb @@ -4,7 +4,7 @@ RSpec.describe ::Types::Ci::JobTokenScope::PoliciesEnum, feature_category: :secrets_management do it 'exposes all policies' do - expect(described_class.values.keys).to match_array(*%w[ + expect(described_class.values.keys).to match_array(%w[ READ_CONTAINERS ADMIN_CONTAINERS READ_DEPLOYMENTS diff --git a/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb index 5ba6883ed70564..4166254311168e 100644 --- a/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policy_categories_enum_spec.rb @@ -4,7 +4,7 @@ RSpec.describe ::Types::Ci::JobTokenScope::PolicyCategoriesEnum, feature_category: :secrets_management do it 'exposes all categories' do - expect(described_class.values.keys).to match_array(*%w[ + expect(described_class.values.keys).to match_array(%w[ CONTAINERS DEPLOYMENTS ENVIRONMENTS -- GitLab From 8954315374aec27e9348224e1a6a38f70e46b755 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Thu, 14 Nov 2024 16:29:41 -1000 Subject: [PATCH 03/14] Update policy descriptions --- .../job_token_scope/policy_categories_enum.rb | 2 +- .../ci/job_token_scope/policy_types_enum.rb | 2 +- app/graphql/types/query_type.rb | 2 +- doc/api/graphql/reference/index.md | 30 ++++++------- lib/ci/job_token/policies.rb | 42 +++++++++---------- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb index c5c75876c1670a..967eeb4b373f4a 100644 --- a/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb @@ -7,7 +7,7 @@ class PolicyCategoriesEnum < BaseEnum graphql_name 'CiJobTokenScopePolicyCategoriesTypes' description 'CI_JOB_TOKEN policy category type' - ::Ci::JobToken::Policies.policy_categories.each do |category| + ::Ci::JobToken::Policies::POLICIES.each do |category| value category[:value].to_s.upcase, value: category[:value], description: category[:description] end end diff --git a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb index 110db2cd82f965..b6a241e0c74e82 100644 --- a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb @@ -8,7 +8,7 @@ class PolicyTypesEnum < BaseEnum description 'CI_JOB_TOKEN policy type' value 'READ', value: :read, description: 'Read only access to resource.' - value 'ADMIN', value: :admin, description: 'Admin access access to resource.' + value 'ADMIN', value: :admin, description: 'Admin access to resource.' end end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 0cce3dd5aabd38..ed58a104d3e4a9 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -304,7 +304,7 @@ def ci_pipeline_stage(id:) end def job_token_policies - ::Ci::JobToken::Policies.policy_categories + ::Ci::JobToken::Policies::POLICIES end end end diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 4c91ffd9ce6f9e..9a93370a5165ce 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -37915,22 +37915,22 @@ CI_JOB_TOKEN policy. | Value | Description | | ----- | ----------- | -| `ADMIN_CONTAINERS` | CRUD all container images in a project. | -| `ADMIN_DEPLOYMENTS` | Admin deployments. | -| `ADMIN_ENVIRONMENTS` | CRUD + Stop all environments in a project. | -| `ADMIN_JOBS` | Read all job metadata, upload artifacts and update the pipeline status. | +| `ADMIN_CONTAINERS` | Admin container images in a project. | +| `ADMIN_DEPLOYMENTS` | Admin deployments in a project. | +| `ADMIN_ENVIRONMENTS` | Admin + Stop environments in a project. | +| `ADMIN_JOBS` | Read job metadata, upload artifacts and update the pipeline status. | | `ADMIN_PACKAGES` | Admin packages. | -| `ADMIN_RELEASES` | CRUD all releases in a project. | -| `ADMIN_SECURE_FILES` | CRUD all secure files in a project. | -| `ADMIN_TERRAFORM_STATE` | CRUD all terraform state files/versions. | -| `READ_CONTAINERS` | Read all container images in a project. | -| `READ_DEPLOYMENTS` | Read all deployments in a project. | -| `READ_ENVIRONMENTS` | Read all environments in a project. | -| `READ_JOBS` | Read all job metadata and artifacts. | +| `ADMIN_RELEASES` | Admin releases in a project. | +| `ADMIN_SECURE_FILES` | Admin secure files in a project. | +| `ADMIN_TERRAFORM_STATE` | Admin terraform state files/versions. | +| `READ_CONTAINERS` | Read container images in a project. | +| `READ_DEPLOYMENTS` | Read deployments in a project. | +| `READ_ENVIRONMENTS` | Read environments in a project. | +| `READ_JOBS` | Read job metadata and artifacts. | | `READ_PACKAGES` | Read, create and delete packages. | -| `READ_RELEASES` | Read all releases in a project. | -| `READ_SECURE_FILES` | Read all secure files in a project. | -| `READ_TERRAFORM_STATE` | Read all terraform state files/version. | +| `READ_RELEASES` | Read releases in a project. | +| `READ_SECURE_FILES` | Read secure files in a project. | +| `READ_TERRAFORM_STATE` | Read terraform state files/version. | ### `CiJobTokenScopePolicyCategoriesTypes` @@ -37953,7 +37953,7 @@ CI_JOB_TOKEN policy type. | Value | Description | | ----- | ----------- | -| `ADMIN` | Admin access access to resource. | +| `ADMIN` | Admin access to resource. | | `READ` | Read only access to resource. | ### `CiRunnerAccessLevel` diff --git a/lib/ci/job_token/policies.rb b/lib/ci/job_token/policies.rb index 0a588cf8440121..97fb61df2c1f0f 100644 --- a/lib/ci/job_token/policies.rb +++ b/lib/ci/job_token/policies.rb @@ -13,13 +13,13 @@ module Policies value: :read_containers, type: :read, text: 'Read', - description: 'Read all container images in a project' + description: 'Read container images in a project' }, { value: :admin_containers, type: :admin, text: 'Read and write', - description: 'CRUD all container images in a project' + description: 'Admin container images in a project' } ] }, @@ -28,8 +28,13 @@ module Policies text: 'Deployments', description: 'Deployments category', policies: [ - { value: :read_deployments, type: :read, text: 'Read', description: 'Read all deployments in a project' }, - { value: :admin_deployments, type: :admin, text: 'Read and write', description: 'Admin deployments' } + { value: :read_deployments, type: :read, text: 'Read', description: 'Read deployments in a project' }, + { + value: :admin_deployments, + type: :admin, + text: 'Read and write', + description: 'Admin deployments in a project' + } ] }, { @@ -37,12 +42,12 @@ module Policies text: 'Environments', description: 'Environments category', policies: [ - { value: :read_environments, type: :read, text: 'Read', description: 'Read all environments in a project' }, + { value: :read_environments, type: :read, text: 'Read', description: 'Read environments in a project' }, { value: :admin_environments, type: :admin, text: 'Read and write', - description: 'CRUD + Stop all environments in a project' + description: 'Admin + Stop environments in a project' } ] }, @@ -51,12 +56,12 @@ module Policies text: 'Jobs', description: 'Jobs category', policies: [ - { value: :read_jobs, type: :read, text: 'Read', description: 'Read all job metadata and artifacts' }, + { value: :read_jobs, type: :read, text: 'Read', description: 'Read job metadata and artifacts' }, { value: :admin_jobs, type: :admin, text: 'Read and write', - description: 'Read all job metadata, upload artifacts and update the pipeline status' + description: 'Read job metadata, upload artifacts and update the pipeline status' } ] }, @@ -74,13 +79,8 @@ module Policies text: 'Releases', description: 'Releases category', policies: [ - { value: :read_releases, type: :read, text: 'Read', description: 'Read all releases in a project' }, - { - value: :admin_releases, - type: :admin, - text: 'Read and write', - description: 'CRUD all releases in a project' - } + { value: :read_releases, type: :read, text: 'Read', description: 'Read releases in a project' }, + { value: :admin_releases, type: :admin, text: 'Read and write', description: 'Admin releases in a project' } ] }, { @@ -88,12 +88,12 @@ module Policies text: 'Secure files', description: 'Secure files category', policies: [ - { value: :read_secure_files, type: :read, text: 'Read', description: 'Read all secure files in a project' }, + { value: :read_secure_files, type: :read, text: 'Read', description: 'Read secure files in a project' }, { value: :admin_secure_files, type: :admin, text: 'Read and write', - description: 'CRUD all secure files in a project' + description: 'Admin secure files in a project' } ] }, @@ -106,23 +106,19 @@ module Policies value: :read_terraform_state, type: :read, text: 'Read', - description: 'Read all terraform state files/version' + description: 'Read terraform state files/version' }, { value: :admin_terraform_state, type: :admin, text: 'Read and write', - description: 'CRUD all terraform state files/versions' + description: 'Admin terraform state files/versions' } ] } ].freeze class << self - def policy_categories - POLICIES - end - def all_policies POLICIES.flat_map { |category| category[:policies] } end -- GitLab From 2238a457cc1a4593e1fcdace675c7e2614757e36 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Thu, 14 Nov 2024 23:03:44 -1000 Subject: [PATCH 04/14] Fix policy_types_enum_spec.rb --- spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb index 2248bb9f6114df..c9646f0796bf2c 100644 --- a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb @@ -6,7 +6,7 @@ it 'the correct enum members' do expect(described_class.values).to match( 'READ' => have_attributes(value: :read, description: 'Read only access to resource.'), - 'ADMIN' => have_attributes(value: :admin, description: 'Admin access access to resource.') + 'ADMIN' => have_attributes(value: :admin, description: 'Admin access to resource.') ) end end -- GitLab From ee8b17665e16899bb019c37b52d7d8c871e2ab96 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Fri, 15 Nov 2024 16:25:46 -1000 Subject: [PATCH 05/14] Fix all job token policies in specs --- .../job_token_scope/add_group_or_project_spec.rb | 6 +++--- .../ci/job_token_scope/add_project_spec.rb | 2 +- .../ci/job_token_scope/remove_group_spec.rb | 4 ++-- .../ci/job_token_scope/remove_project_spec.rb | 4 ++-- .../ci/job_token_scope/add_group_service_spec.rb | 4 ++-- .../job_token_scope/add_project_service_spec.rb | 4 ++-- .../job_token_scope/remove_group_service_spec.rb | 4 ++-- .../remove_project_service_spec.rb | 4 ++-- .../update_policies_service_spec.rb | 6 +++--- .../job_token_scope/add_group_or_project_spec.rb | 4 ++-- spec/models/ci/job_token/allowlist_spec.rb | 4 ++-- .../models/ci/job_token/group_scope_link_spec.rb | 12 ++++++------ .../ci/job_token/project_scope_link_spec.rb | 12 ++++++------ .../update_job_token_policies_spec.rb | 8 ++++---- .../add_group_or_project_service_spec.rb | 4 ++-- .../ci/job_token_scope/add_group_service_spec.rb | 2 +- .../job_token_scope/add_project_service_spec.rb | 2 +- .../update_policies_service_spec.rb | 16 ++++++++-------- 18 files changed, 51 insertions(+), 51 deletions(-) diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb index 13a9bbc8ee03c9..92b086f568d6f7 100644 --- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb +++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb @@ -15,7 +15,7 @@ let_it_be(:target_project) { create(:project) } let_it_be(:target_project_path) { target_project.full_path } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let_it_be(:current_user) { create(:user) } @@ -51,7 +51,7 @@ let(:expected_audit_message) do "Group #{target_group_path} was added to list of allowed groups for #{project_path}, " \ - "with job token permissions: read_project, read_package" + "with job token permissions: read_containers, read_packages" end let(:event_name) { 'secure_ci_job_token_group_added' } @@ -104,7 +104,7 @@ let(:expected_audit_message) do "Project #{target_project_path} was added to inbound list of allowed projects for #{project_path}, " \ - "with job token permissions: read_project, read_package" + "with job token permissions: read_containers, read_packages" end let(:event_name) { 'secure_ci_job_token_project_added' } diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_project_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_project_spec.rb index fef9eaa927fada..7f7286d9857d29 100644 --- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_project_spec.rb +++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_project_spec.rb @@ -16,7 +16,7 @@ let_it_be(:target_project) { create(:project) } let_it_be(:target_project_path) { target_project.full_path } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let_it_be(:current_user) { create(:user, maintainer_of: project, guest_of: target_project) } diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb index 90bfa41476c378..57ecd73105c225 100644 --- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb +++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb @@ -16,7 +16,7 @@ create(:ci_job_token_group_scope_link, source_project: project, target_group: target_group, - job_token_policies: %w[read_group read_project] + job_token_policies: %w[read_containers read_packages] ) end @@ -51,7 +51,7 @@ context 'when user removes target group to the job token scope' do let(:expected_audit_message) do "Group #{target_group_path} was removed from list of allowed groups for #{project_path}, " \ - "with job token permissions: read_group, read_project" + "with job token permissions: read_containers, read_packages" end let(:event_name) { 'secure_ci_job_token_group_removed' } diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb index c1ba6da18bbfac..20db1a312ed9a2 100644 --- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb +++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb @@ -17,7 +17,7 @@ direction: :inbound, source_project: project, target_project: target_project, - job_token_policies: %w[read_project read_package] + job_token_policies: %w[read_containers read_packages] ) end @@ -59,7 +59,7 @@ let(:expected_audit_message) do "Project #{target_project_path} was removed from inbound list of allowed projects for #{project_path}, " \ - "with job token permissions: read_project, read_package" + "with job token permissions: read_containers, read_packages" end let(:event_name) { 'secure_ci_job_token_project_removed' } diff --git a/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb index 337c6bc0e2e337..be3884a5a6fe31 100644 --- a/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb +++ b/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb @@ -8,14 +8,14 @@ let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_group) } - let_it_be(:policies) { %w[read_group read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } subject(:service_result) { described_class.new(project, current_user).execute(target_group, policies: policies) } describe '#execute' do let(:expected_audit_message) do "Group #{target_group.full_path} was added to list of allowed groups for #{project.full_path}, " \ - "with job token permissions: read_group, read_package" + "with job token permissions: read_containers, read_packages" end let(:audit_event) do diff --git a/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb index de65f035a1b857..ce33ee00f39f70 100644 --- a/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb +++ b/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb @@ -8,7 +8,7 @@ let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_project) } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let_it_be(:direction) { :inbound } @@ -20,7 +20,7 @@ context 'when the direction is inbound' do let(:expected_audit_message) do "Project #{target_project.full_path} was added to inbound list of allowed projects for #{project.full_path}, " \ - "with job token permissions: read_project, read_package" + "with job token permissions: read_containers, read_packages" end let(:audit_event) do diff --git a/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb index 33a17cb77810ed..dbe43c999f5f0e 100644 --- a/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb +++ b/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb @@ -8,7 +8,7 @@ let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_group) } - let_it_be(:policies) { %w[read_group read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let_it_be(:group_link) do create(:ci_job_token_group_scope_link, @@ -23,7 +23,7 @@ describe '#execute' do let(:expected_audit_message) do "Group #{target_group.full_path} was removed from list of allowed groups for #{project.full_path}, " \ - "with job token permissions: read_group, read_package" + "with job token permissions: read_containers, read_packages" end let(:audit_event) do diff --git a/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb index 6328aee54c0e73..5cd8f249d62d06 100644 --- a/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb +++ b/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb @@ -8,7 +8,7 @@ let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_project) } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let_it_be(:direction) { :inbound } @@ -29,7 +29,7 @@ let(:expected_audit_message) do "Project #{target_project.full_path} was removed from inbound list of allowed projects " \ - "for #{project.full_path}, with job token permissions: read_project, read_package" + "for #{project.full_path}, with job token permissions: read_containers, read_packages" end let(:audit_event) do diff --git a/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb index 9319968e10b317..ba07f2b18c85e7 100644 --- a/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb +++ b/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb @@ -8,7 +8,7 @@ let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_project) } - let(:policies) { %w[read_project read_container_image] } + let(:policies) { %w[read_containers read_packages] } subject(:service_result) do described_class.new(project, current_user).execute(target_project, policies) @@ -20,7 +20,7 @@ create(:ci_job_token_project_scope_link, source_project: project, target_project: target_project, - job_token_policies: %w[read_project read_package], + job_token_policies: %w[read_containers read_packages], direction: :inbound ) end @@ -31,7 +31,7 @@ author: current_user, scope: project, target: target_project, - message: 'CI job token policies updated to: read_project, read_container_image' + message: 'CI job token policies updated to: read_containers, read_packages' } end diff --git a/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb b/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb index fa2a14f300871f..86385bfcd0c0be 100644 --- a/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb +++ b/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb @@ -36,7 +36,7 @@ let_it_be(:target_project) { create(:project) } let_it_be(:target_project_path) { target_project.full_path } - let(:policies) { %w[read_project read_package] } + let(:policies) { %w[read_containers read_packages] } let(:mutation_args) do { project_path: project.full_path, target_path: target_project_path, job_token_policies: policies } @@ -96,7 +96,7 @@ let_it_be(:target_group) { create(:group, :private) } let_it_be(:target_group_path) { target_group.full_path } - let(:policies) { %w[read_project read_package] } + let(:policies) { %w[read_containers read_packages] } let(:mutation_args) do { project_path: project.full_path, target_path: target_group_path, job_token_policies: policies } diff --git a/spec/models/ci/job_token/allowlist_spec.rb b/spec/models/ci/job_token/allowlist_spec.rb index babefc7c96eea1..dfab57ff80620c 100644 --- a/spec/models/ci/job_token/allowlist_spec.rb +++ b/spec/models/ci/job_token/allowlist_spec.rb @@ -67,7 +67,7 @@ describe 'add!' do let_it_be(:added_project) { create(:project) } let_it_be(:user) { create(:user) } - let_it_be(:policies) { %w[read_package read_project] } + let_it_be(:policies) { %w[read_containers read_packages] } subject(:add_project) { allowlist.add!(added_project, policies: policies, user: user) } @@ -107,7 +107,7 @@ describe 'add_group!' do let_it_be(:added_group) { create(:group) } let_it_be(:user) { create(:user) } - let_it_be(:policies) { %w[read_package read_project] } + let_it_be(:policies) { %w[read_containers read_packages] } subject(:add_group) { allowlist.add_group!(added_group, policies: policies, user: user) } diff --git a/spec/models/ci/job_token/group_scope_link_spec.rb b/spec/models/ci/job_token/group_scope_link_spec.rb index c087e636921764..1e5770fb9c56f7 100644 --- a/spec/models/ci/job_token/group_scope_link_spec.rb +++ b/spec/models/ci/job_token/group_scope_link_spec.rb @@ -74,12 +74,12 @@ using RSpec::Parameterized::TableSyntax where(:value, :valid) do - nil | true - [] | true - %w[read_build] | true - %w[read_build read_project] | true - %w[read_issue] | false - { project: %w[read_build] } | false + nil | true + [] | true + %w[read_containers] | true + %w[read_containers read_packages] | true + %w[read_issue] | false + { project: %w[read_build] } | false end with_them do diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb index 87b77761ef2d2f..155da77a32c9e7 100644 --- a/spec/models/ci/job_token/project_scope_link_spec.rb +++ b/spec/models/ci/job_token/project_scope_link_spec.rb @@ -78,12 +78,12 @@ using RSpec::Parameterized::TableSyntax where(:value, :valid) do - nil | true - [] | true - %w[read_build] | true - %w[read_build read_project] | true - %w[read_issue] | false - { project: %w[read_build] } | false + nil | true + [] | true + %w[read_containers] | true + %w[read_containers read_packages] | true + %w[read_issue] | false + { project: %w[read_build] } | false end with_them do diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb index 10ef438148b07f..acecd77b2443db 100644 --- a/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb +++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb @@ -45,7 +45,7 @@ let_it_be(:target_project) { create(:project, :private) } let_it_be(:target_path) { target_project.full_path } - let(:policies) { %w[READ_PROJECT READ_PACKAGE] } + let(:policies) { %w[READ_CONTAINERS READ_PACKAGES] } context 'when user does not have permissions to admin project' do let_it_be(:current_user) { create(:user, guest_of: target_project) } @@ -74,7 +74,7 @@ :ci_job_token_project_scope_link, source_project: project, target_project: target_project, - job_token_policies: %w[read_project], + job_token_policies: %w[read_containers], direction: :inbound ) end @@ -123,7 +123,7 @@ let_it_be(:target_group) { create(:group, :private) } let_it_be(:target_path) { target_group.full_path } - let(:policies) { %w[READ_GROUP READ_PACKAGE] } + let(:policies) { %w[READ_CONTAINERS READ_PACKAGES] } context 'when user does not have permissions to admin project' do let_it_be(:current_user) { create(:user, guest_of: target_group) } @@ -152,7 +152,7 @@ :ci_job_token_group_scope_link, source_project: project, target_group: target_group, - job_token_policies: %w[read_group] + job_token_policies: %w[read_containers] ) end diff --git a/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb b/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb index 3d8d7f68e6221c..8fbc181dfee692 100644 --- a/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb +++ b/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb @@ -7,7 +7,7 @@ let_it_be(:target_project) { create(:project) } let_it_be(:target_group) { create(:group) } let_it_be(:current_user) { create(:user) } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let(:response_success) { ServiceResponse.success } @@ -36,7 +36,7 @@ context 'when project is a target to add' do let(:target) { target_project } let(:add_project_service_double) { instance_double(::Ci::JobTokenScope::AddProjectService) } - let(:policies) { %w[read_project] } + let(:policies) { %w[read_containers] } before do allow(::Ci::JobTokenScope::AddProjectService).to receive(:new) diff --git a/spec/services/ci/job_token_scope/add_group_service_spec.rb b/spec/services/ci/job_token_scope/add_group_service_spec.rb index 8556dbc2d94d0b..b6e087a25d23c4 100644 --- a/spec/services/ci/job_token_scope/add_group_service_spec.rb +++ b/spec/services/ci/job_token_scope/add_group_service_spec.rb @@ -6,7 +6,7 @@ let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) } let_it_be(:target_group) { create(:group, :private) } let_it_be(:current_user) { create(:user) } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } let(:service) { described_class.new(project, current_user) } diff --git a/spec/services/ci/job_token_scope/add_project_service_spec.rb b/spec/services/ci/job_token_scope/add_project_service_spec.rb index d61518d91c6551..55815e2852a829 100644 --- a/spec/services/ci/job_token_scope/add_project_service_spec.rb +++ b/spec/services/ci/job_token_scope/add_project_service_spec.rb @@ -7,7 +7,7 @@ let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) } let_it_be(:target_project) { create(:project) } let_it_be(:current_user) { create(:user) } - let_it_be(:policies) { %w[read_project read_package] } + let_it_be(:policies) { %w[read_containers read_packages] } shared_examples 'adds project' do |context| it 'adds the project to the scope', :aggregate_failures do diff --git a/spec/services/ci/job_token_scope/update_policies_service_spec.rb b/spec/services/ci/job_token_scope/update_policies_service_spec.rb index fed5d5e4c79b37..ada3a038a6379d 100644 --- a/spec/services/ci/job_token_scope/update_policies_service_spec.rb +++ b/spec/services/ci/job_token_scope/update_policies_service_spec.rb @@ -78,12 +78,12 @@ :ci_job_token_project_scope_link, source_project: project, target_project: target_project, - job_token_policies: %w[read_project], + job_token_policies: [], direction: :inbound ) end - let(:policies) { %w[read_project read_package] } + let(:policies) { %w[read_containers read_packages] } it_behaves_like 'when user is not logged in' @@ -106,7 +106,7 @@ expect(project_link.source_project).to eq(project) expect(project_link.target_project).to eq(target_project) - expect(project_link.job_token_policies).to eq(%w[read_project read_package]) + expect(project_link.job_token_policies).to eq(%w[read_containers read_packages]) end context 'when feature-flag `add_policies_to_ci_job_token` is disabled' do @@ -117,7 +117,7 @@ it 'does not update the policies' do project_link = Ci::JobToken::ProjectScopeLink.last - expect(project_link.job_token_policies).to eq(%w[read_project]) + expect(project_link.job_token_policies).to eq([]) end end end @@ -132,11 +132,11 @@ :ci_job_token_group_scope_link, source_project: project, target_group: target_group, - job_token_policies: %w[read_group] + job_token_policies: [] ) end - let(:policies) { %w[read_group read_package] } + let(:policies) { %w[read_containers read_packages] } it_behaves_like 'when user is not logged in' @@ -159,7 +159,7 @@ expect(group_link.source_project).to eq(project) expect(group_link.target_group).to eq(target_group) - expect(group_link.job_token_policies).to eq(%w[read_group read_package]) + expect(group_link.job_token_policies).to eq(%w[read_containers read_packages]) end context 'when feature-flag `add_policies_to_ci_job_token` is disabled' do @@ -170,7 +170,7 @@ it 'does not update the policies' do group_link = Ci::JobToken::GroupScopeLink.last - expect(group_link.job_token_policies).to eq(%w[read_group]) + expect(group_link.job_token_policies).to eq([]) end end end -- GitLab From e6c49e1a5ddff77d098ce3bd0cdcf0ca25fdec5f Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Fri, 15 Nov 2024 23:19:14 -1000 Subject: [PATCH 06/14] Fix failing query_type_spec.rb --- ee/spec/graphql/types/query_type_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ee/spec/graphql/types/query_type_spec.rb b/ee/spec/graphql/types/query_type_spec.rb index ffb1bc1f3099a6..7496dd31db0009 100644 --- a/ee/spec/graphql/types/query_type_spec.rb +++ b/ee/spec/graphql/types/query_type_spec.rb @@ -51,7 +51,8 @@ :project_secrets_manager, :ai_feature_settings, :ai_slash_commands, - :compliance_requirement_controls + :compliance_requirement_controls, + :job_token_policies ] all_expected_fields = expected_foss_fields + expected_ee_fields -- GitLab From ca38bc8012cdd656d0a9966b3ec3fe09199862c8 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 01:05:39 -1000 Subject: [PATCH 07/14] Fix add_group_or_project_spec.rb and update_policies_service_spec.rb --- app/graphql/types/ci/job_token_scope/policy_types_enum.rb | 2 +- app/graphql/types/query_type.rb | 2 +- doc/api/graphql/reference/index.md | 6 +++--- lib/ci/job_token/policies.rb | 2 +- .../ci/job_token_scope/add_group_or_project_spec.rb | 2 +- .../ci/job_token_scope/update_policies_service_spec.rb | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb index b6a241e0c74e82..545f97a904a8b9 100644 --- a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb @@ -7,7 +7,7 @@ class PolicyTypesEnum < BaseEnum graphql_name 'CiJobTokenScopePolicyTypes' description 'CI_JOB_TOKEN policy type' - value 'READ', value: :read, description: 'Read only access to resource.' + value 'READ', value: :read, description: 'Read-only access to resource.' value 'ADMIN', value: :admin, description: 'Admin access to resource.' end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index ed58a104d3e4a9..914fd05396c26c 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -247,7 +247,7 @@ class QueryType < ::Types::BaseObject field :job_token_policies, [::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType], description: 'List of job token policies for use with fine-grained permissions on CI/CD job allowlist.', - experiment: { milestone: '17.6' } + experiment: { milestone: '17.7' } def design_management DesignManagementObject.new(nil) diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 9a93370a5165ce..622bdc037f9990 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -730,7 +730,7 @@ Returns [`Iteration`](#iteration). List of job token policies for use with fine-grained permissions on CI/CD job allowlist. DETAILS: -**Introduced** in GitLab 17.6. +**Introduced** in GitLab 17.7. **Status**: Experiment. Returns [`[JobTokenPolicyCategory!]`](#jobtokenpolicycategory). @@ -37927,7 +37927,7 @@ CI_JOB_TOKEN policy. | `READ_DEPLOYMENTS` | Read deployments in a project. | | `READ_ENVIRONMENTS` | Read environments in a project. | | `READ_JOBS` | Read job metadata and artifacts. | -| `READ_PACKAGES` | Read, create and delete packages. | +| `READ_PACKAGES` | Read packages. | | `READ_RELEASES` | Read releases in a project. | | `READ_SECURE_FILES` | Read secure files in a project. | | `READ_TERRAFORM_STATE` | Read terraform state files/version. | @@ -37954,7 +37954,7 @@ CI_JOB_TOKEN policy type. | Value | Description | | ----- | ----------- | | `ADMIN` | Admin access to resource. | -| `READ` | Read only access to resource. | +| `READ` | Read-only access to resource. | ### `CiRunnerAccessLevel` diff --git a/lib/ci/job_token/policies.rb b/lib/ci/job_token/policies.rb index 97fb61df2c1f0f..31eb33c75e9691 100644 --- a/lib/ci/job_token/policies.rb +++ b/lib/ci/job_token/policies.rb @@ -70,7 +70,7 @@ module Policies text: 'Packages', description: 'Packages category', policies: [ - { value: :read_packages, type: :read, text: 'Read', description: 'Read, create and delete packages' }, + { value: :read_packages, type: :read, text: 'Read', description: 'Read packages' }, { value: :admin_packages, type: :admin, text: 'Read and write', description: 'Admin packages' } ] }, diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb index 0a10852c9fc90b..cbf9f4a1883528 100644 --- a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb +++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb @@ -7,7 +7,7 @@ let_it_be(:project) { create(:project, ci_inbound_job_token_scope_enabled: true) } - let(:policies) { %w[READ_PROJECT] } + let(:policies) { %w[READ_CONTAINERS] } let(:mutation_response) { graphql_mutation_response(:ci_job_token_scope_add_group_or_project) } diff --git a/spec/services/ci/job_token_scope/update_policies_service_spec.rb b/spec/services/ci/job_token_scope/update_policies_service_spec.rb index ada3a038a6379d..7fea51eeb3256a 100644 --- a/spec/services/ci/job_token_scope/update_policies_service_spec.rb +++ b/spec/services/ci/job_token_scope/update_policies_service_spec.rb @@ -78,7 +78,7 @@ :ci_job_token_project_scope_link, source_project: project, target_project: target_project, - job_token_policies: [], + job_token_policies: %w[read_containers], direction: :inbound ) end @@ -117,7 +117,7 @@ it 'does not update the policies' do project_link = Ci::JobToken::ProjectScopeLink.last - expect(project_link.job_token_policies).to eq([]) + expect(project_link.job_token_policies).to eq(%w[read_containers]) end end end -- GitLab From beb6f008bb3a0a3b2f2bf469e880e5d643000788 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 02:12:56 -1000 Subject: [PATCH 08/14] Convert job token policies to symbols in allowlist_entry_type.rb --- app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb index 77e795f5c7435a..335767d3d5d5e8 100644 --- a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb +++ b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb @@ -66,7 +66,7 @@ def direction def job_token_policies return unless Feature.enabled?(:add_policies_to_ci_job_token, object.source_project) - object.job_token_policies + object.job_token_policies.map(&:to_sym) end end # rubocop: enable Graphql/AuthorizeTypes -- GitLab From 38f494cb38a21344e96af62cbf19497c29f1c6b8 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 11:33:43 -1000 Subject: [PATCH 09/14] Fix policy_types_enum_spec.rb --- spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb index c9646f0796bf2c..95ef5c8d13d3d5 100644 --- a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb @@ -5,7 +5,7 @@ RSpec.describe ::Types::Ci::JobTokenScope::PolicyTypesEnum, feature_category: :secrets_management do it 'the correct enum members' do expect(described_class.values).to match( - 'READ' => have_attributes(value: :read, description: 'Read only access to resource.'), + 'READ' => have_attributes(value: :read, description: 'Read-only access to resource.'), 'ADMIN' => have_attributes(value: :admin, description: 'Admin access to resource.') ) end -- GitLab From 7de3a5889282e47411a9da2c3d1cd0e85d4ede2d Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 13:36:19 -1000 Subject: [PATCH 10/14] Add test that calls jobTokenPolicies to fix undercoverage failing job --- spec/graphql/types/query_type_spec.rb | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index bab3c4c8132cca..d99b21779efeab 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -183,6 +183,42 @@ it 'returns job token policies', :aggregate_failures do is_expected.to have_graphql_type(::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType) + + query = <<~GRAPHQL + query { + jobTokenPolicies { + text + value + description + policies { + text + value + description + type + } + } + } + GRAPHQL + + expected_result = ::Ci::JobToken::Policies::POLICIES.map do |category| + { + 'text' => category[:text], + 'value' => category[:value].upcase, + 'description' => category[:description], + 'policies' => category[:policies].map do |policy| + { + 'text' => policy[:text], + 'value' => policy[:value].upcase, + 'description' => policy[:description], + 'type' => policy[:type].upcase + } + end + } + end + + result = GitlabSchema.execute(query).as_json.dig('data', 'jobTokenPolicies') + + expect(result).to eq(expected_result.as_json) end end end -- GitLab From 181026d7420a82f92a5177d95e5c356f968b80f7 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 14:54:10 -1000 Subject: [PATCH 11/14] Use safe navigation for job_token_policies --- app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb index 335767d3d5d5e8..3e976ef6919351 100644 --- a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb +++ b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb @@ -66,7 +66,7 @@ def direction def job_token_policies return unless Feature.enabled?(:add_policies_to_ci_job_token, object.source_project) - object.job_token_policies.map(&:to_sym) + object.job_token_policies&.map(&:to_sym) end end # rubocop: enable Graphql/AuthorizeTypes -- GitLab From 2662bace5045e242fe4c5aceddb28fdd4dd9e4d0 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Tue, 19 Nov 2024 23:21:18 -1000 Subject: [PATCH 12/14] Fix allowlist_query_spec.rb --- .../ci/job_token_scope/allowlist_query_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb b/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb index d4c314d85594fb..3778d47c06ac2f 100644 --- a/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb +++ b/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb @@ -70,7 +70,7 @@ { 'addedBy' => { 'username' => current_user.username }, 'direction' => 'inbound', - 'jobTokenPolicies' => ['READ_GROUP'], + 'jobTokenPolicies' => ['READ_CONTAINERS'], 'sourceProject' => { 'fullPath' => project.full_path }, 'target' => { 'fullPath' => target_group_1.full_path } } @@ -85,14 +85,14 @@ { 'addedBy' => { 'username' => current_user.username }, 'direction' => 'outbound', - 'jobTokenPolicies' => ['READ_PROJECT'], + 'jobTokenPolicies' => ['READ_CONTAINERS'], 'sourceProject' => { 'fullPath' => project.full_path }, 'target' => { 'fullPath' => target_project_2.full_path } }, { 'addedBy' => { 'username' => current_user.username }, 'direction' => 'inbound', - 'jobTokenPolicies' => ['READ_PROJECT'], + 'jobTokenPolicies' => ['READ_CONTAINERS'], 'sourceProject' => { 'fullPath' => project.full_path }, 'target' => { 'fullPath' => target_project_1.full_path } } @@ -138,7 +138,7 @@ :ci_job_token_project_scope_link, source_project: project, target_project: target_project_1, - job_token_policies: %w[read_project], + job_token_policies: %w[read_containers], added_by: current_user, direction: :inbound ) @@ -147,7 +147,7 @@ :ci_job_token_project_scope_link, source_project: project, target_project: target_project_2, - job_token_policies: %w[read_project], + job_token_policies: %w[read_containers], added_by: current_user, direction: :outbound ) @@ -157,7 +157,7 @@ source_project: project, target_group: target_group_1, added_by: current_user, - job_token_policies: %w[read_group] + job_token_policies: %w[read_containers] ) end -- GitLab From 7c3d284ab5f17178e2736d62c0010120bd2f5643 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Wed, 20 Nov 2024 14:16:16 -1000 Subject: [PATCH 13/14] Rename jobTokenPolicies query to jobTokenPoliciesByCategory --- .../types/ci/job_token_scope/policy_categories_enum.rb | 2 +- app/graphql/types/ci/job_token_scope/policy_types_enum.rb | 4 ++-- app/graphql/types/query_type.rb | 6 +++--- doc/api/graphql/reference/index.md | 6 +++--- lib/ci/job_token/policies.rb | 4 ++-- .../types/ci/job_token_scope/policy_types_enum_spec.rb | 4 ++-- spec/graphql/types/query_type_spec.rb | 8 ++++---- .../ci/job_token_scope/update_policies_service_spec.rb | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb index 967eeb4b373f4a..39683b3d6ca0ce 100644 --- a/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policy_categories_enum.rb @@ -7,7 +7,7 @@ class PolicyCategoriesEnum < BaseEnum graphql_name 'CiJobTokenScopePolicyCategoriesTypes' description 'CI_JOB_TOKEN policy category type' - ::Ci::JobToken::Policies::POLICIES.each do |category| + ::Ci::JobToken::Policies::POLICIES_BY_CATEGORY.each do |category| value category[:value].to_s.upcase, value: category[:value], description: category[:description] end end diff --git a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb index 545f97a904a8b9..420dfb46d71bc1 100644 --- a/app/graphql/types/ci/job_token_scope/policy_types_enum.rb +++ b/app/graphql/types/ci/job_token_scope/policy_types_enum.rb @@ -7,8 +7,8 @@ class PolicyTypesEnum < BaseEnum graphql_name 'CiJobTokenScopePolicyTypes' description 'CI_JOB_TOKEN policy type' - value 'READ', value: :read, description: 'Read-only access to resource.' - value 'ADMIN', value: :admin, description: 'Admin access to resource.' + value 'READ', value: :read, description: 'Read-only access to the resource.' + value 'ADMIN', value: :admin, description: 'Admin access to the resource.' end end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 914fd05396c26c..e7637e2c7e8ab3 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -245,7 +245,7 @@ class QueryType < ::Types::BaseObject description: 'Check if a feature flag is enabled', resolver: Resolvers::FeatureFlagResolver - field :job_token_policies, [::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType], + field :job_token_policies_by_category, [::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType], description: 'List of job token policies for use with fine-grained permissions on CI/CD job allowlist.', experiment: { milestone: '17.7' } @@ -303,8 +303,8 @@ def ci_pipeline_stage(id:) stage end - def job_token_policies - ::Ci::JobToken::Policies::POLICIES + def job_token_policies_by_category + ::Ci::JobToken::Policies::POLICIES_BY_CATEGORY end end end diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 622bdc037f9990..d39c335c698481 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -725,7 +725,7 @@ Returns [`Iteration`](#iteration). | ---- | ---- | ----------- | | `id` | [`IterationID!`](#iterationid) | Find an iteration by its ID. | -### `Query.jobTokenPolicies` +### `Query.jobTokenPoliciesByCategory` List of job token policies for use with fine-grained permissions on CI/CD job allowlist. @@ -37953,8 +37953,8 @@ CI_JOB_TOKEN policy type. | Value | Description | | ----- | ----------- | -| `ADMIN` | Admin access to resource. | -| `READ` | Read-only access to resource. | +| `ADMIN` | Admin access to the resource. | +| `READ` | Read-only access to the resource. | ### `CiRunnerAccessLevel` diff --git a/lib/ci/job_token/policies.rb b/lib/ci/job_token/policies.rb index 31eb33c75e9691..c746e20fdd304c 100644 --- a/lib/ci/job_token/policies.rb +++ b/lib/ci/job_token/policies.rb @@ -3,7 +3,7 @@ module Ci module JobToken module Policies - POLICIES = [ + POLICIES_BY_CATEGORY = [ { value: :containers, text: 'Containers', @@ -120,7 +120,7 @@ module Policies class << self def all_policies - POLICIES.flat_map { |category| category[:policies] } + POLICIES_BY_CATEGORY.flat_map { |category| category[:policies] } end end end diff --git a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb index 95ef5c8d13d3d5..171d7ddac6efb1 100644 --- a/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb +++ b/spec/graphql/types/ci/job_token_scope/policy_types_enum_spec.rb @@ -5,8 +5,8 @@ RSpec.describe ::Types::Ci::JobTokenScope::PolicyTypesEnum, feature_category: :secrets_management do it 'the correct enum members' do expect(described_class.values).to match( - 'READ' => have_attributes(value: :read, description: 'Read-only access to resource.'), - 'ADMIN' => have_attributes(value: :admin, description: 'Admin access to resource.') + 'READ' => have_attributes(value: :read, description: 'Read-only access to the resource.'), + 'ADMIN' => have_attributes(value: :admin, description: 'Admin access to the resource.') ) end end diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index d99b21779efeab..46c5b93d6a39eb 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -179,14 +179,14 @@ end describe 'jobTokenPolicyCategories field' do - subject { described_class.fields['jobTokenPolicies'] } + subject { described_class.fields['jobTokenPoliciesByCategory'] } it 'returns job token policies', :aggregate_failures do is_expected.to have_graphql_type(::Types::Ci::JobTokenScope::JobTokenPolicyCategoryType) query = <<~GRAPHQL query { - jobTokenPolicies { + jobTokenPoliciesByCategory { text value description @@ -200,7 +200,7 @@ } GRAPHQL - expected_result = ::Ci::JobToken::Policies::POLICIES.map do |category| + expected_result = ::Ci::JobToken::Policies::POLICIES_BY_CATEGORY.map do |category| { 'text' => category[:text], 'value' => category[:value].upcase, @@ -216,7 +216,7 @@ } end - result = GitlabSchema.execute(query).as_json.dig('data', 'jobTokenPolicies') + result = GitlabSchema.execute(query).as_json.dig('data', 'jobTokenPoliciesByCategory') expect(result).to eq(expected_result.as_json) end diff --git a/spec/services/ci/job_token_scope/update_policies_service_spec.rb b/spec/services/ci/job_token_scope/update_policies_service_spec.rb index 7fea51eeb3256a..cbcbba5f1e004f 100644 --- a/spec/services/ci/job_token_scope/update_policies_service_spec.rb +++ b/spec/services/ci/job_token_scope/update_policies_service_spec.rb @@ -132,7 +132,7 @@ :ci_job_token_group_scope_link, source_project: project, target_group: target_group, - job_token_policies: [] + job_token_policies: %w[read_containers] ) end @@ -170,7 +170,7 @@ it 'does not update the policies' do group_link = Ci::JobToken::GroupScopeLink.last - expect(group_link.job_token_policies).to eq([]) + expect(group_link.job_token_policies).to eq(%w[read_containers]) end end end -- GitLab From 185e261ae197953a2d9762cd02ab37a99f6e5981 Mon Sep 17 00:00:00 2001 From: Daniel Tian Date: Wed, 20 Nov 2024 16:07:59 -1000 Subject: [PATCH 14/14] Fix query_type_spec.rb --- ee/spec/graphql/types/query_type_spec.rb | 3 +-- spec/graphql/types/query_type_spec.rb | 2 +- .../shared_contexts/graphql/types/query_type_shared_context.rb | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ee/spec/graphql/types/query_type_spec.rb b/ee/spec/graphql/types/query_type_spec.rb index 7496dd31db0009..ffb1bc1f3099a6 100644 --- a/ee/spec/graphql/types/query_type_spec.rb +++ b/ee/spec/graphql/types/query_type_spec.rb @@ -51,8 +51,7 @@ :project_secrets_manager, :ai_feature_settings, :ai_slash_commands, - :compliance_requirement_controls, - :job_token_policies + :compliance_requirement_controls ] all_expected_fields = expected_foss_fields + expected_ee_fields diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index 46c5b93d6a39eb..3d4ea44fa3d039 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -178,7 +178,7 @@ end end - describe 'jobTokenPolicyCategories field' do + describe 'jobTokenPoliciesByCategory field' do subject { described_class.fields['jobTokenPoliciesByCategory'] } it 'returns job token policies', :aggregate_failures do diff --git a/spec/support/shared_contexts/graphql/types/query_type_shared_context.rb b/spec/support/shared_contexts/graphql/types/query_type_shared_context.rb index 8585ddd7f8cd13..997988e3636dee 100644 --- a/spec/support/shared_contexts/graphql/types/query_type_shared_context.rb +++ b/spec/support/shared_contexts/graphql/types/query_type_shared_context.rb @@ -51,7 +51,8 @@ :audit_event_definitions, :abuse_report, :abuse_report_labels, - :feature_flag_enabled + :feature_flag_enabled, + :job_token_policies_by_category ] end end -- GitLab