diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index b646b5b826f64fa514e4debf12e0000208208d84..5f096fa2254ae3128dd9a2fe35c4b4a1ec0ca250 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3502,6 +3502,30 @@ Input type: `CreateComplianceFrameworkInput`
| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| `framework` | [`ComplianceFramework`](#complianceframework) | Created compliance framework. |
+### `Mutation.createComplianceRequirement`
+
+DETAILS:
+**Introduced** in GitLab 17.6.
+**Status**: Experiment.
+
+Input type: `CreateComplianceRequirementInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| `complianceFrameworkId` | [`ComplianceManagementFrameworkID!`](#compliancemanagementframeworkid) | Global ID of the compliance framework of the new requirement. |
+| `params` | [`ComplianceRequirementInput!`](#compliancerequirementinput) | Parameters to update the compliance requirement with. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| `requirement` | [`ComplianceRequirement`](#compliancerequirement) | Created compliance requirement. |
+
### `Mutation.createContainerRegistryProtectionRule`
Creates a protection rule to restrict access to a project's container registry. Available only when feature flag `container_registry_protected_containers` is enabled.
@@ -20509,6 +20533,18 @@ Represents a ComplianceFramework associated with a Project.
| `scanExecutionPolicies` | [`ScanExecutionPolicyConnection`](#scanexecutionpolicyconnection) | Scan Execution Policies of the compliance framework. (see [Connections](#connections)) |
| `scanResultPolicies` | [`ScanResultPolicyConnection`](#scanresultpolicyconnection) | Scan Result Policies of the compliance framework. (see [Connections](#connections)) |
+### `ComplianceRequirement`
+
+Represents a ComplianceRequirement associated with a ComplianceFramework.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `description` | [`String!`](#string) | Description of the compliance requirement. |
+| `id` | [`ID!`](#id) | Compliance requirement ID. |
+| `name` | [`String!`](#string) | Name of the compliance requirement. |
+
### `ComplianceStandardsAdherence`
Compliance standards adherence for a project.
@@ -42598,6 +42634,15 @@ Attributes for defining a CI/CD variable.
| `name` | [`String`](#string) | New name for the compliance framework. |
| `pipelineConfigurationFullPath` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use pipeline execution policies instead. Deprecated in GitLab 17.4. |
+### `ComplianceRequirementInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `description` | [`String`](#string) | New description for the compliance requirement. |
+| `name` | [`String`](#string) | New name for the compliance requirement. |
+
### `ComplianceStandardsAdherenceInput`
#### Arguments
diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md
index 6cf7a4df30b15eaec8c1bde6948b5ddc2a5bf989..1183e368cb3fc24a8a9ae6a02a372f69773c2e8a 100644
--- a/doc/user/compliance/audit_event_types.md
+++ b/doc/user/compliance/audit_event_types.md
@@ -140,6 +140,7 @@ Audit event types belong to the following product categories.
| [`compliance_framework_removed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157893) | Triggered when a compliance framework is removed from a project | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/464160) | Project |
| [`create_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | Triggered on when a compliance framework is successfully created | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | Group |
| [`create_status_check`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | Triggered when an external status check is created | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/355805) | Project |
+| [`created_compliance_requirement`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169485) | Triggered when a requirement is added to a compliance framework | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.6](https://gitlab.com/gitlab-org/gitlab/-/issues/470695) | Group |
| [`delete_status_check`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | Triggered when an external status check is deleted | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/355805) | Project |
| [`destroy_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | Triggered when a compliance framework is successfully deleted | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | Group |
| [`email_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | Triggered when an email is created | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User |
diff --git a/ee/app/graphql/ee/types/mutation_type.rb b/ee/app/graphql/ee/types/mutation_type.rb
index 08d70e3ad2b449002a70be0630ac9396bd96e177..6fb7d5a6130cb9c2718cbd4a451ed30d593b3303 100644
--- a/ee/app/graphql/ee/types/mutation_type.rb
+++ b/ee/app/graphql/ee/types/mutation_type.rb
@@ -248,6 +248,8 @@ def self.authorization_scopes
mount_mutation ::Mutations::Ai::FeatureSettings::Update, alpha: { milestone: '17.4' }
mount_mutation ::Mutations::Projects::TargetBranchRules::Create
mount_mutation ::Mutations::Projects::TargetBranchRules::Destroy
+ mount_mutation ::Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirements::Create,
+ alpha: { milestone: '17.6' }
prepend(Types::DeprecatedMutations)
end
diff --git a/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create.rb b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create.rb
new file mode 100644
index 0000000000000000000000000000000000000000..82ba11d81fe80788e60e7650be4d4c908159f97b
--- /dev/null
+++ b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Mutations
+ module ComplianceManagement
+ module ComplianceFramework
+ module ComplianceRequirements
+ class Create < BaseMutation
+ graphql_name 'CreateComplianceRequirement'
+
+ authorize :admin_compliance_framework
+
+ field :requirement,
+ Types::ComplianceManagement::ComplianceRequirementType,
+ null: true,
+ description: 'Created compliance requirement.'
+
+ argument :compliance_framework_id, ::Types::GlobalIDType[::ComplianceManagement::Framework],
+ required: true,
+ description: 'Global ID of the compliance framework of the new requirement.'
+
+ argument :params, Types::ComplianceManagement::ComplianceRequirementInputType,
+ required: true,
+ description: 'Parameters to update the compliance requirement with.'
+
+ def resolve(args)
+ framework = authorized_find!(id: args[:compliance_framework_id])
+
+ service = ::ComplianceManagement::ComplianceFramework::ComplianceRequirements::CreateService.new(
+ framework: framework,
+ params: args[:params].to_h,
+ current_user: current_user
+ ).execute
+
+ service.success? ? success(service) : error(service)
+ end
+
+ private
+
+ def success(service)
+ { requirement: service.payload[:requirement], errors: [] }
+ end
+
+ def error(service)
+ errors = [service.message]
+ model_errors = service.payload.try(:full_messages).to_a
+
+ { errors: (errors + model_errors).flatten }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/ee/app/graphql/types/compliance_management/compliance_requirement_input_type.rb b/ee/app/graphql/types/compliance_management/compliance_requirement_input_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cbbd6903ae85af32a78d7ba66ba0479da2df4cca
--- /dev/null
+++ b/ee/app/graphql/types/compliance_management/compliance_requirement_input_type.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Types
+ module ComplianceManagement
+ class ComplianceRequirementInputType < BaseInputObject
+ graphql_name 'ComplianceRequirementInput'
+
+ argument :name,
+ GraphQL::Types::String,
+ required: false,
+ description: 'New name for the compliance requirement.'
+
+ argument :description,
+ GraphQL::Types::String,
+ required: false,
+ description: 'New description for the compliance requirement.'
+ end
+ end
+end
diff --git a/ee/app/graphql/types/compliance_management/compliance_requirement_type.rb b/ee/app/graphql/types/compliance_management/compliance_requirement_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..459d54a80bb0ab1bf902862b9d4e89c5a6d8a608
--- /dev/null
+++ b/ee/app/graphql/types/compliance_management/compliance_requirement_type.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# rubocop: disable Graphql/AuthorizeTypes -- because ComplianceRequirementType is, and should only be, accessible via ComplianceFrameworkType
+
+module Types
+ module ComplianceManagement
+ class ComplianceRequirementType < Types::BaseObject
+ graphql_name 'ComplianceRequirement'
+ description 'Represents a ComplianceRequirement associated with a ComplianceFramework'
+
+ field :id, GraphQL::Types::ID,
+ null: false,
+ description: 'Compliance requirement ID.'
+
+ field :name, GraphQL::Types::String,
+ null: false,
+ description: 'Name of the compliance requirement.'
+
+ field :description, GraphQL::Types::String,
+ null: false,
+ description: 'Description of the compliance requirement.'
+ end
+ end
+end
+
+# rubocop: enable Graphql/AuthorizeTypes
diff --git a/ee/app/services/compliance_management/compliance_framework/compliance_requirements/create_service.rb b/ee/app/services/compliance_management/compliance_framework/compliance_requirements/create_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..11c7c17de89761656e8a0c24d2aecec0b792f1f0
--- /dev/null
+++ b/ee/app/services/compliance_management/compliance_framework/compliance_requirements/create_service.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module ComplianceManagement
+ module ComplianceFramework
+ module ComplianceRequirements
+ class CreateService < BaseService
+ attr_reader :params, :current_user, :framework, :requirement
+
+ def initialize(framework:, params:, current_user:)
+ @framework = framework
+ @params = params
+ @current_user = current_user
+ @requirement = ComplianceManagement::ComplianceFramework::ComplianceRequirement.new
+ end
+
+ def execute
+ requirement.assign_attributes(
+ framework: framework,
+ namespace_id: framework.namespace.id,
+ name: params[:name],
+ description: params[:description]
+ )
+
+ return ServiceResponse.error(message: 'Not permitted to create requirement') unless permitted?
+
+ return error unless requirement.save
+
+ audit_create
+ success
+ end
+
+ private
+
+ def permitted?
+ can? current_user, :admin_compliance_framework, framework
+ end
+
+ def success
+ ServiceResponse.success(payload: { requirement: requirement })
+ end
+
+ def audit_create
+ audit_context = {
+ name: 'created_compliance_requirement',
+ author: current_user,
+ scope: framework.namespace,
+ target: requirement,
+ message: "Created compliance requirement #{requirement.name} for framework #{framework.name}"
+ }
+
+ ::Gitlab::Audit::Auditor.audit(audit_context)
+ end
+
+ def error
+ ServiceResponse.error(message: _('Failed to create compliance requirement'), payload: requirement.errors)
+ end
+ end
+ end
+ end
+end
diff --git a/ee/config/audit_events/types/created_compliance_requirement.yml b/ee/config/audit_events/types/created_compliance_requirement.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bc50c2d86d6ee0c1c946a8fa0e34256562fd4e3a
--- /dev/null
+++ b/ee/config/audit_events/types/created_compliance_requirement.yml
@@ -0,0 +1,10 @@
+---
+name: created_compliance_requirement
+description: Triggered when a requirement is added to a compliance framework
+introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/470695
+introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169485
+milestone: '17.6'
+feature_category: compliance_management
+saved_to_database: true
+streamed: true
+scope: [Group]
diff --git a/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_input_type_spec.rb b/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_input_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ba7d784275b791e73c5a0da2a6e6d0346d72f3fa
--- /dev/null
+++ b/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_input_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Types::ComplianceManagement::ComplianceRequirementInputType, feature_category: :compliance_management do
+ it { expect(described_class.graphql_name).to eq('ComplianceRequirementInput') }
+
+ it { expect(described_class.arguments.keys).to match_array(%w[name description]) }
+end
diff --git a/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_type_spec.rb b/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6db3f4436a392f8f47f0fd32c7d147e36d09c8c7
--- /dev/null
+++ b/ee/spec/graphql/ee/types/compliance_management/compliance_requirement_type_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ComplianceRequirement'], feature_category: :compliance_management do
+ subject { described_class }
+
+ fields = %w[
+ id
+ name
+ description
+ ]
+
+ it 'has the correct fields' do
+ is_expected.to have_graphql_fields(fields)
+ end
+end
diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8f67d223b834cf5a03ad08b5bad1c0ac60b1207d
--- /dev/null
+++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirements::Create,
+ feature_category: :compliance_management do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:namespace) { create(:group) }
+ let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
+
+ let(:params) { valid_params }
+ let(:mutation) { described_class.new(object: nil, context: query_context, field: nil) }
+
+ subject(:mutate) { mutation.resolve(**params) }
+
+ describe '#resolve' do
+ shared_examples 'resource not available' do
+ it 'raises error' do
+ expect { mutate }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ before do
+ stub_licensed_features(custom_compliance_frameworks: true)
+ end
+
+ context 'when current_user is not group namespace owner' do
+ it_behaves_like 'resource not available'
+ end
+
+ context 'when current_user is group owner' do
+ before_all do
+ namespace.add_owner(current_user)
+ end
+
+ context 'when all arguments are valid' do
+ it 'creates a new compliance requirement' do
+ expect { mutate }.to change { framework.compliance_requirements.count }.by 1
+ end
+ end
+
+ context 'when requirement parameters are invalid' do
+ subject(:mutate) { mutation.resolve(**invalid_name_params) }
+
+ it 'does not create a new compliance framework' do
+ expect { mutate }.not_to change { framework.compliance_requirements.count }
+ end
+
+ it 'returns error for name' do
+ expect(mutate[:errors]).to include "Name can't be blank"
+ end
+ end
+ end
+
+ context 'when current_user is personal namespace owner' do
+ let_it_be(:namespace) { create(:user_namespace) }
+
+ let(:current_user) { namespace.owner }
+
+ context 'when framework parameters are valid' do
+ it_behaves_like 'resource not available'
+ end
+ end
+ end
+
+ private
+
+ def valid_params
+ {
+ compliance_framework_id: framework.to_gid,
+ params: {
+ name: 'Custom framework requirement',
+ description: 'Example Description'
+ }
+ }
+ end
+
+ def invalid_name_params
+ {
+ compliance_framework_id: framework.to_gid,
+ params: {
+ name: '',
+ description: 'Example Description'
+ }
+ }
+ end
+end
diff --git a/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4784f7b5b46be638ae727d4ed6be967a198bb1b5
--- /dev/null
+++ b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements/create_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Create a Compliance Requirement', feature_category: :compliance_management do
+ include GraphqlHelpers
+
+ let_it_be(:namespace) { create(:group) }
+ let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
+ let_it_be(:current_user) { create(:user) }
+
+ let(:mutation) do
+ graphql_mutation(
+ :create_compliance_requirement,
+ compliance_framework_id: framework.to_gid,
+ params: {
+ name: 'Custom framework requirement',
+ description: 'Example Description'
+ }
+ )
+ end
+
+ subject(:mutate) { post_graphql_mutation(mutation, current_user: current_user) }
+
+ def mutation_response
+ graphql_mutation_response(:create_compliance_requirement)
+ end
+
+ shared_examples 'a mutation that creates a compliance requirement' do
+ it 'creates a new compliance requirement' do
+ expect { mutate }.to change { framework.compliance_requirements.count }.by 1
+ end
+
+ it 'returns the newly created requirement', :aggregate_failures do
+ mutate
+
+ expect(mutation_response['requirement']['name']).to eq 'Custom framework requirement'
+ expect(mutation_response['requirement']['description']).to eq 'Example Description'
+ end
+ end
+
+ context 'when framework feature is unlicensed' do
+ before do
+ stub_licensed_features(custom_compliance_frameworks: false)
+ post_graphql_mutation(mutation, current_user: current_user)
+ end
+
+ it_behaves_like 'a mutation that returns a top-level access error'
+ end
+
+ context 'when feature is licensed' do
+ before do
+ stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
+ end
+
+ context 'when current_user is group owner' do
+ before_all do
+ namespace.add_owner(current_user)
+ end
+
+ it_behaves_like 'a mutation that creates a compliance requirement'
+ end
+
+ context 'when current_user is not a group owner' do
+ context 'when current_user is group owner' do
+ before_all do
+ namespace.add_maintainer(current_user)
+ end
+
+ it 'does not create a new compliance requirement' do
+ expect { mutate }.not_to change { framework.compliance_requirements.count }
+ end
+
+ it_behaves_like 'a mutation that returns a top-level access error'
+ end
+ end
+ end
+end
diff --git a/ee/spec/services/compliance_management/compliance_framework/compliance_requirements/create_service_spec.rb b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements/create_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dfefe20a98fab6f0d717d00a60b2e37564c7e8b0
--- /dev/null
+++ b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements/create_service_spec.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ComplianceManagement::ComplianceFramework::ComplianceRequirements::CreateService,
+ feature_category: :compliance_management do
+ let_it_be_with_refind(:namespace) { create(:group) }
+ let_it_be(:current_user) { create(:user, owner_of: namespace) }
+ let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
+
+ let(:params) do
+ {
+ name: 'Custom framework requirement',
+ description: 'Description about the requirement'
+ }
+ end
+
+ context 'when custom_compliance_frameworks is disabled' do
+ before do
+ stub_licensed_features(custom_compliance_frameworks: false)
+ end
+
+ subject(:requirement_creator) do
+ described_class.new(framework: framework, params: params, current_user: current_user)
+ end
+
+ it 'does not create a new compliance requirement' do
+ expect { requirement_creator.execute }.not_to change { framework.compliance_requirements.count }
+ end
+
+ it 'responds with an error message' do
+ expect(requirement_creator.execute.message).to eq('Not permitted to create requirement')
+ end
+ end
+
+ context 'when custom_compliance_frameworks is enabled' do
+ before do
+ stub_licensed_features(custom_compliance_frameworks: true)
+ end
+
+ context 'when using invalid parameters' do
+ subject(:requirement_creator) do
+ described_class.new(framework: framework, params: params.except(:name), current_user: current_user)
+ end
+
+ let(:response) { requirement_creator.execute }
+
+ it 'responds with an error service response' do
+ expect(response.success?).to be_falsey
+ expect(response.payload.messages[:name]).to contain_exactly "can't be blank"
+ end
+ end
+
+ context 'when creating a compliance requirement for a namespace that current_user is not the owner of' do
+ subject(:requirement_creator) do
+ described_class.new(framework: framework, params: params, current_user: create(:user))
+ end
+
+ it 'responds with an error service response' do
+ expect(requirement_creator.execute.success?).to be false
+ end
+
+ it 'does not create a new compliance requirement' do
+ expect { requirement_creator.execute }.not_to change { framework.compliance_requirements.count }
+ end
+ end
+
+ context 'when using parameters for a valid compliance requirement' do
+ subject(:requirement_creator) do
+ described_class.new(framework: framework, params: params, current_user: current_user)
+ end
+
+ it 'audits the changes' do
+ expect { requirement_creator.execute }
+ .to change { AuditEvent.where("details LIKE ?", "%created_compliance_requirement%").count }.by(1)
+ end
+
+ it 'creates a new compliance requirement' do
+ expect { requirement_creator.execute }.to change { framework.compliance_requirements.count }.by(1)
+ end
+
+ it 'responds with a successful service response' do
+ expect(requirement_creator.execute.success?).to be true
+ end
+
+ it 'has the expected attributes' do
+ requirement = requirement_creator.execute.payload[:requirement]
+
+ expect(requirement.attributes).to include(
+ "name" => "Custom framework requirement",
+ "description" => "Description about the requirement",
+ "framework_id" => framework.id,
+ "namespace_id" => namespace.id
+ )
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 53b35b6d006770c7f05c68d29d9d693e5afb83ae..0821b48c1e8b2da5e19fda05d44abdeb2a4d67d5 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -22905,6 +22905,9 @@ msgstr ""
msgid "Failed to create branch target"
msgstr ""
+msgid "Failed to create compliance requirement"
+msgstr ""
+
msgid "Failed to create framework"
msgstr ""