From aa8552f625d08ebdb889ce5d97046dc8029232b5 Mon Sep 17 00:00:00 2001
From: Rahul Chanila <rchanila@gitlab.com>
Date: Wed, 4 Dec 2024 01:01:24 +0000
Subject: [PATCH] Change feature name to Container repository protection rules

This used to be called Container protection rules
https://gitlab.com/gitlab-org/gitlab/-/issues/480385#note_2228248943

Updated docs & UI

Changed docs URL, added redirect
---
 .../components/container_protection_rules.vue |   8 +-
 .../container_repository_type.rb              |   2 +-
 .../protection/rule_type.rb                   |  16 +-
 .../container_repository_protection_rules.md  | 194 +++++++++++++++++
 doc/api/graphql/reference/index.md            |  16 +-
 ...ect_container_registry_protection_rules.md | 197 +-----------------
 .../container_protection_rules.md             |  89 +-------
 .../container_repository_protection_rules.md  |  86 ++++++++
 locale/gitlab.pot                             |   8 +-
 .../container_protection_rules_spec.js        |   4 +-
 10 files changed, 323 insertions(+), 297 deletions(-)
 create mode 100644 doc/api/container_repository_protection_rules.md
 create mode 100644 doc/user/packages/container_registry/container_repository_protection_rules.md

diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/container_protection_rules.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/container_protection_rules.vue
index 628f32a5ae67..92cc1d776db4 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/container_protection_rules.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/container_protection_rules.vue
@@ -43,14 +43,14 @@ export default {
   },
   inject: ['projectPath'],
   i18n: {
-    settingBlockTitle: s__('ContainerRegistry|Protected containers'),
+    settingBlockTitle: s__('ContainerRegistry|Protected container repositories'),
     settingBlockDescription: s__(
-      'ContainerRegistry|When a container is protected, only certain user roles can push the protected container image, which helps to avoid tampering with the container image.',
+      'ContainerRegistry|When a container repository is protected, only certain user roles can push the protected container image, which helps to avoid tampering with the container image.',
     ),
     protectionRuleDeletionConfirmModal: {
-      title: s__('ContainerRegistry|Delete container protection rule?'),
+      title: s__('ContainerRegistry|Delete container repository protection rule?'),
       descriptionWarning: s__(
-        'ContainerRegistry|You are about to delete the container protection rule for %{repositoryPathPattern}.',
+        'ContainerRegistry|You are about to delete the container repository protection rule for %{repositoryPathPattern}.',
       ),
       descriptionConsequence: s__(
         'ContainerRegistry|Users with at least the Developer role for this project will be able to push and delete container images to this repository path.',
diff --git a/app/graphql/types/container_registry/container_repository_type.rb b/app/graphql/types/container_registry/container_repository_type.rb
index ec1cfe110126..242e27ec6d2b 100644
--- a/app/graphql/types/container_registry/container_repository_type.rb
+++ b/app/graphql/types/container_registry/container_repository_type.rb
@@ -40,7 +40,7 @@ class ContainerRepositoryType < BaseObject
         null: false,
         experiment: { milestone: '17.2' },
         description:
-          'Whether any matching container protection rule exists for the container. ' \
+          'Whether any matching container protection rule exists for the container repository. ' \
           'Available only when feature flag `container_registry_protected_containers` is enabled.'
       field :status, Types::ContainerRegistry::ContainerRepositoryStatusEnum, null: true,
         description: 'Status of the container repository.'
diff --git a/app/graphql/types/container_registry/protection/rule_type.rb b/app/graphql/types/container_registry/protection/rule_type.rb
index 65eda788a86d..27e1df9f4b15 100644
--- a/app/graphql/types/container_registry/protection/rule_type.rb
+++ b/app/graphql/types/container_registry/protection/rule_type.rb
@@ -5,7 +5,7 @@ module ContainerRegistry
     module Protection
       class RuleType < ::Types::BaseObject
         graphql_name 'ContainerRegistryProtectionRule'
-        description 'A container registry protection rule designed to prevent users with a certain ' \
+        description 'A container repository protection rule designed to prevent users with a certain ' \
           'access level or lower from altering the container registry.'
 
         authorize :admin_container_image
@@ -14,7 +14,7 @@ class RuleType < ::Types::BaseObject
           ::Types::GlobalIDType[::ContainerRegistry::Protection::Rule],
           null: false,
           experiment: { milestone: '16.6' },
-          description: 'ID of the container registry protection rule.'
+          description: 'ID of the container repository protection rule.'
 
         field :repository_path_pattern,
           GraphQL::Types::String,
@@ -29,20 +29,20 @@ class RuleType < ::Types::BaseObject
           null: true,
           experiment: { milestone: '16.6' },
           description:
-            'Minimum GitLab access level to allow to delete container images from the container registry. ' \
+            'Minimum GitLab access level required to delete container images from the container repository. ' \
             'For example, `MAINTAINER`, `OWNER`, or `ADMIN`. ' \
-            'If the value is `nil`, the minimum access level for delete is ignored. ' \
-            'Users with at least the Developer role are allowed to delete container images.'
+            'If the value is `nil`, the minimum access level is ignored. ' \
+            'Users with at least the Developer role can delete container images.'
 
         field :minimum_access_level_for_push,
           Types::ContainerRegistry::Protection::RuleAccessLevelEnum,
           null: true,
           experiment: { milestone: '16.6' },
           description:
-            'Minimum GitLab access level to allow to push container images to the container registry. ' \
+            'Minimum GitLab access level required to push container images to the container repository. ' \
             'For example, `MAINTAINER`, `OWNER`, or `ADMIN`. ' \
-            'If the value is `nil`, the minimum access level for push is ignored. ' \
-            'Users with at least the Developer role are allowed to push container images.'
+            'If the value is `nil`, the minimum access level is ignored. ' \
+            'Users with at least the Developer role can push container images.'
       end
     end
   end
diff --git a/doc/api/container_repository_protection_rules.md b/doc/api/container_repository_protection_rules.md
new file mode 100644
index 000000000000..9c66b8d21394
--- /dev/null
+++ b/doc/api/container_repository_protection_rules.md
@@ -0,0 +1,194 @@
+---
+stage: Package
+group: Container Registry
+info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments"
+description: "Documentation for the REST API for container repository protection rules in GitLab."
+---
+
+# Container repository protection rules API
+
+DETAILS:
+**Tier:** Free, Premium, Ultimate
+**Offering:** Self-managed
+**Status:** Experiment
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155798) in GitLab 17.2 [with a flag](../administration/feature_flags.md) named `container_registry_protected_containers`. Disabled by default.
+
+FLAG:
+The availability of this feature is controlled by a feature flag.
+For more information, see the history.
+This feature is available for testing, but not ready for production use.
+
+This API endpoint manages protection rules for container repositories in a project's container registry. This feature is an experiment.
+
+## List container repository protection rules
+
+Gets a list of container repository protection rules from a project's container registry.
+
+```plaintext
+GET /api/v4/projects/:id/registry/protection/rules
+```
+
+Supported attributes:
+
+| Attribute                     | Type            | Required | Description                    |
+|-------------------------------|-----------------|----------|--------------------------------|
+| `id`                          | integer/string  | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
+
+If successful, returns [`200`](rest/troubleshooting.md#status-codes) and a list of container repository protection rules.
+
+Can return the following status codes:
+
+- `200 OK`: A list of protection rules.
+- `401 Unauthorized`: The access token is invalid.
+- `403 Forbidden`: The user does not have permission to list protection rules for this project.
+- `404 Not Found`: The project was not found.
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" \
+  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules"
+```
+
+Example response:
+
+```json
+[
+  {
+    "id": 1,
+    "project_id": 7,
+    "repository_path_pattern": "flightjs/flight0",
+    "minimum_access_level_for_push": "maintainer",
+    "minimum_access_level_for_delete": "maintainer"
+  },
+  {
+    "id": 2,
+    "project_id": 7,
+    "repository_path_pattern": "flightjs/flight1",
+    "minimum_access_level_for_push": "maintainer",
+    "minimum_access_level_for_delete": "maintainer"
+  },
+]
+```
+
+## Create a container repository protection rule
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.2.
+
+Create a container repository protection rule for a project's container registry.
+
+```plaintext
+POST /api/v4/projects/:id/registry/protection/rules
+```
+
+Supported attributes:
+
+| Attribute                         | Type           | Required | Description |
+|-----------------------------------|----------------|----------|-------------|
+| `id`                              | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
+| `repository_path_pattern`         | string         | Yes      | Container repository path pattern protected by the protection rule. For example `flight/flight-*`. Wildcard character `*` allowed. |
+| `minimum_access_level_for_push`   | string         | No       | Minimum GitLab access level required to push container images to the container registry. For example `maintainer`, `owner` or `admin`. Must be provided when `minimum_access_level_for_delete` is not set. |
+| `minimum_access_level_for_delete` | string         | No       | Minimum GitLab access level required to delete container images in the container registry. For example `maintainer`, `owner`, `admin`. Must be provided when `minimum_access_level_for_push` is not set. |
+
+If successful, returns [`201`](rest/troubleshooting.md#status-codes) and the created container repository protection rule.
+
+Can return the following status codes:
+
+- `201 Created`: The protection rule was created successfully.
+- `400 Bad Request`: The protection rule is invalid.
+- `401 Unauthorized`: The access token is invalid.
+- `403 Forbidden`: The user does not have permission to create a protection rule.
+- `404 Not Found`: The project was not found.
+- `422 Unprocessable Entity`: The protection rule could not be created. For example, because the `repository_path_pattern` is already taken.
+
+Example request:
+
+```shell
+curl --request POST \
+  --header "PRIVATE-TOKEN: <your_access_token>" \
+  --header "Content-Type: application/json" \
+  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules" \
+  --data '{
+        "repository_path_pattern": "flightjs/flight-needs-to-be-a-unique-path",
+        "minimum_access_level_for_push": "maintainer",
+        "minimum_access_level_for_delete": "maintainer"
+    }'
+```
+
+## Update a container repository protection rule
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.2.
+
+Update a container repository protection rule for a project's container registry.
+
+```plaintext
+PATCH /api/v4/projects/:id/registry/protection/rules/:protection_rule_id
+```
+
+Supported attributes:
+
+| Attribute                         | Type           | Required | Description |
+|-----------------------------------|----------------|----------|-------------|
+| `id`                              | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
+| `protection_rule_id`              | integer        | Yes      | ID of the protection rule to be updated. |
+| `repository_path_pattern`         | string         | No       | Container repository path pattern protected by the protection rule. For example `flight/flight-*`. Wildcard character `*` allowed. |
+| `minimum_access_level_for_push`   | string         | No       | Minimum GitLab access level required to push container images to the container registry. For example `maintainer`, `owner` or `admin`. Must be provided when `minimum_access_level_for_delete` is not set. To unset the value, use an empty string `""`. |
+| `minimum_access_level_for_delete` | string         | No       | Minimum GitLab access level required to delete container images in the container registry. For example `maintainer`, `owner`, `admin`. Must be provided when `minimum_access_level_for_push` is not set. To unset the value, use an empty string `""`. |
+
+If successful, returns [`200`](rest/troubleshooting.md#status-codes) and the updated protection rule.
+
+Can return the following status codes:
+
+- `200 OK`: The protection rule was updated successfully.
+- `400 Bad Request`: The protection rule is invalid.
+- `401 Unauthorized`: The access token is invalid.
+- `403 Forbidden`: The user does not have permission to update the protection rule.
+- `404 Not Found`: The project was not found.
+- `422 Unprocessable Entity`: The protection rule could not be updated. For example, because the `repository_path_pattern` is already taken.
+
+Example request:
+
+```shell
+curl --request PATCH \
+  --header "PRIVATE-TOKEN: <your_access_token>" \
+  --header "Content-Type: application/json" \
+  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules/32" \
+  --data '{
+       "repository_path_pattern": "flight/flight-*"
+    }'
+```
+
+## Delete a container repository protection rule
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.4.
+
+Deletes a container repository protection rule from a project's container registry.
+
+```plaintext
+DELETE /api/v4/projects/:id/registry/protection/rules/:protection_rule_id
+```
+
+Supported attributes:
+
+| Attribute            | Type           | Required | Description |
+|----------------------|----------------|----------|-------------|
+| `id`                 | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
+| `protection_rule_id` | integer        | Yes      | ID of the container repository protection rule to be deleted. |
+
+If successful, returns [`204 No Content`](rest/troubleshooting.md#status-codes).
+
+Can return the following status codes:
+
+- `204 No Content`: The protection rule was deleted successfully.
+- `400 Bad Request`: The `id` or the `protection_rule_id` are missing or are invalid.
+- `401 Unauthorized`: The access token is invalid.
+- `403 Forbidden`: The user does not have permission to delete the protection rule.
+- `404 Not Found`: The project or the protection rule was not found.
+
+Example request:
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
+  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules/1"
+```
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index b056b50d16d9..315a70626944 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3654,8 +3654,8 @@ Input type: `CreateContainerRegistryProtectionRuleInput`
 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | <a id="mutationcreatecontainerregistryprotectionruleclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationcreatecontainerregistryprotectionruleminimumaccesslevelfordelete"></a>`minimumAccessLevelForDelete` | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | Minimum GitLab access level to allow to delete container images from the container registry. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level for delete is ignored. Users with at least the Developer role are allowed to delete container images. Introduced in GitLab 16.6: **Status**: Experiment. |
-| <a id="mutationcreatecontainerregistryprotectionruleminimumaccesslevelforpush"></a>`minimumAccessLevelForPush` | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | Minimum GitLab access level to allow to push container images to the container registry. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level for push is ignored. Users with at least the Developer role are allowed to push container images. Introduced in GitLab 16.6: **Status**: Experiment. |
+| <a id="mutationcreatecontainerregistryprotectionruleminimumaccesslevelfordelete"></a>`minimumAccessLevelForDelete` | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | Minimum GitLab access level required to delete container images from the container repository. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level is ignored. Users with at least the Developer role can delete container images. Introduced in GitLab 16.6: **Status**: Experiment. |
+| <a id="mutationcreatecontainerregistryprotectionruleminimumaccesslevelforpush"></a>`minimumAccessLevelForPush` | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | Minimum GitLab access level required to push container images to the container repository. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level is ignored. Users with at least the Developer role can push container images. Introduced in GitLab 16.6: **Status**: Experiment. |
 | <a id="mutationcreatecontainerregistryprotectionruleprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project where a protection rule is located. |
 | <a id="mutationcreatecontainerregistryprotectionrulerepositorypathpattern"></a>`repositoryPathPattern` | [`String!`](#string) | Container repository path pattern protected by the protection rule. For example, `my-project/my-container-*`. Wildcard character `*` allowed. Introduced in GitLab 16.6: **Status**: Experiment. |
 
@@ -21212,15 +21212,15 @@ A tag expiration policy designed to keep only the images that matter most.
 
 ### `ContainerRegistryProtectionRule`
 
-A container registry protection rule designed to prevent users with a certain access level or lower from altering the container registry.
+A container repository protection rule designed to prevent users with a certain access level or lower from altering the container registry.
 
 #### Fields
 
 | Name | Type | Description |
 | ---- | ---- | ----------- |
-| <a id="containerregistryprotectionruleid"></a>`id` **{warning-solid}** | [`ContainerRegistryProtectionRuleID!`](#containerregistryprotectionruleid) | **Introduced** in GitLab 16.6. **Status**: Experiment. ID of the container registry protection rule. |
-| <a id="containerregistryprotectionruleminimumaccesslevelfordelete"></a>`minimumAccessLevelForDelete` **{warning-solid}** | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | **Introduced** in GitLab 16.6. **Status**: Experiment. Minimum GitLab access level to allow to delete container images from the container registry. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level for delete is ignored. Users with at least the Developer role are allowed to delete container images. |
-| <a id="containerregistryprotectionruleminimumaccesslevelforpush"></a>`minimumAccessLevelForPush` **{warning-solid}** | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | **Introduced** in GitLab 16.6. **Status**: Experiment. Minimum GitLab access level to allow to push container images to the container registry. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level for push is ignored. Users with at least the Developer role are allowed to push container images. |
+| <a id="containerregistryprotectionruleid"></a>`id` **{warning-solid}** | [`ContainerRegistryProtectionRuleID!`](#containerregistryprotectionruleid) | **Introduced** in GitLab 16.6. **Status**: Experiment. ID of the container repository protection rule. |
+| <a id="containerregistryprotectionruleminimumaccesslevelfordelete"></a>`minimumAccessLevelForDelete` **{warning-solid}** | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | **Introduced** in GitLab 16.6. **Status**: Experiment. Minimum GitLab access level required to delete container images from the container repository. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level is ignored. Users with at least the Developer role can delete container images. |
+| <a id="containerregistryprotectionruleminimumaccesslevelforpush"></a>`minimumAccessLevelForPush` **{warning-solid}** | [`ContainerRegistryProtectionRuleAccessLevel`](#containerregistryprotectionruleaccesslevel) | **Introduced** in GitLab 16.6. **Status**: Experiment. Minimum GitLab access level required to push container images to the container repository. For example, `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, the minimum access level is ignored. Users with at least the Developer role can push container images. |
 | <a id="containerregistryprotectionrulerepositorypathpattern"></a>`repositoryPathPattern` **{warning-solid}** | [`String!`](#string) | **Introduced** in GitLab 16.6. **Status**: Experiment. Container repository path pattern protected by the protection rule. For example, `my-project/my-container-*`. Wildcard character `*` allowed. |
 
 ### `ContainerRepository`
@@ -21241,7 +21241,7 @@ A container repository.
 | <a id="containerrepositoryname"></a>`name` | [`String!`](#string) | Name of the container repository. |
 | <a id="containerrepositorypath"></a>`path` | [`String!`](#string) | Path of the container repository. |
 | <a id="containerrepositoryproject"></a>`project` | [`Project!`](#project) | Project of the container registry. |
-| <a id="containerrepositoryprotectionruleexists"></a>`protectionRuleExists` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.2. **Status**: Experiment. Whether any matching container protection rule exists for the container. Available only when feature flag `container_registry_protected_containers` is enabled. |
+| <a id="containerrepositoryprotectionruleexists"></a>`protectionRuleExists` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.2. **Status**: Experiment. Whether any matching container protection rule exists for the container repository. Available only when feature flag `container_registry_protected_containers` is enabled. |
 | <a id="containerrepositorystatus"></a>`status` | [`ContainerRepositoryStatus`](#containerrepositorystatus) | Status of the container repository. |
 | <a id="containerrepositorytagscount"></a>`tagsCount` | [`Int!`](#int) | Number of tags associated with the image. |
 | <a id="containerrepositoryupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp when the container repository was updated. |
@@ -21266,7 +21266,7 @@ Details of a container repository.
 | <a id="containerrepositorydetailsname"></a>`name` | [`String!`](#string) | Name of the container repository. |
 | <a id="containerrepositorydetailspath"></a>`path` | [`String!`](#string) | Path of the container repository. |
 | <a id="containerrepositorydetailsproject"></a>`project` | [`Project!`](#project) | Project of the container registry. |
-| <a id="containerrepositorydetailsprotectionruleexists"></a>`protectionRuleExists` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.2. **Status**: Experiment. Whether any matching container protection rule exists for the container. Available only when feature flag `container_registry_protected_containers` is enabled. |
+| <a id="containerrepositorydetailsprotectionruleexists"></a>`protectionRuleExists` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.2. **Status**: Experiment. Whether any matching container protection rule exists for the container repository. Available only when feature flag `container_registry_protected_containers` is enabled. |
 | <a id="containerrepositorydetailssize"></a>`size` | [`Float`](#float) | Deduplicated size of the image repository in bytes. This is only available on GitLab.com for repositories created after `2021-11-04`. |
 | <a id="containerrepositorydetailsstatus"></a>`status` | [`ContainerRepositoryStatus`](#containerrepositorystatus) | Status of the container repository. |
 | <a id="containerrepositorydetailstagscount"></a>`tagsCount` | [`Int!`](#int) | Number of tags associated with the image. |
diff --git a/doc/api/project_container_registry_protection_rules.md b/doc/api/project_container_registry_protection_rules.md
index 98242134564e..7f4f71162935 100644
--- a/doc/api/project_container_registry_protection_rules.md
+++ b/doc/api/project_container_registry_protection_rules.md
@@ -1,194 +1,13 @@
 ---
-stage: Package
-group: Container Registry
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments"
-description: "Documentation for the REST API for container registry protection rules in GitLab."
+redirect_to: 'container_repository_protection_rules.md'
+remove_date: '2025-03-02'
 ---
 
-# Container registry protection rules API
+<!-- markdownlint-disable -->
 
-DETAILS:
-**Tier:** Free, Premium, Ultimate
-**Offering:** Self-managed
-**Status:** Experiment
+This document was moved to [another location](container_repository_protection_rules.md).
 
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155798) in GitLab 17.2 [with a flag](../administration/feature_flags.md) named `container_registry_protected_containers`. Disabled by default.
-
-FLAG:
-The availability of this feature is controlled by a feature flag.
-For more information, see the history.
-This feature is available for testing, but not ready for production use.
-
-This API endpoint manages the protection rules for container registries in a project. This feature is an experiment.
-
-## List container registry protection rules
-
-Gets a list of container registry protection rules from a project.
-
-```plaintext
-GET /api/v4/projects/:id/registry/protection/rules
-```
-
-Supported attributes:
-
-| Attribute                     | Type            | Required | Description                    |
-|-------------------------------|-----------------|----------|--------------------------------|
-| `id`                          | integer/string  | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
-
-If successful, returns [`200`](rest/troubleshooting.md#status-codes) and a list of container registry protection rules.
-
-Can return the following status codes:
-
-- `200 OK`: A list of container registry protection rules.
-- `401 Unauthorized`: The access token is invalid.
-- `403 Forbidden`: The user does not have permission to list container registry protection rules for this project.
-- `404 Not Found`: The project was not found.
-
-Example request:
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" \
-  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules"
-```
-
-Example response:
-
-```json
-[
-  {
-    "id": 1,
-    "project_id": 7,
-    "repository_path_pattern": "flightjs/flight0",
-    "minimum_access_level_for_push": "maintainer",
-    "minimum_access_level_for_delete": "maintainer"
-  },
-  {
-    "id": 2,
-    "project_id": 7,
-    "repository_path_pattern": "flightjs/flight1",
-    "minimum_access_level_for_push": "maintainer",
-    "minimum_access_level_for_delete": "maintainer"
-  },
-]
-```
-
-## Create a container registry protection rule
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.2.
-
-Create a container registry protection rule for a project.
-
-```plaintext
-POST /api/v4/projects/:id/registry/protection/rules
-```
-
-Supported attributes:
-
-| Attribute                         | Type           | Required | Description |
-|-----------------------------------|----------------|----------|-------------|
-| `id`                              | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
-| `repository_path_pattern`         | string         | Yes      | Container repository path pattern protected by the protection rule. For example `flight/flight-*`. Wildcard character `*` allowed. |
-| `minimum_access_level_for_push`   | string         | No       | Minimum GitLab access level to allow to push container images to the container registry. For example `maintainer`, `owner` or `admin`. Must be provided when `minimum_access_level_for_delete` is not set. |
-| `minimum_access_level_for_delete` | string         | No       | Minimum GitLab access level to allow to delete container images in the container registry. For example `maintainer`, `owner`, `admin`. Must be provided when `minimum_access_level_for_push` is not set. |
-
-If successful, returns [`201`](rest/troubleshooting.md#status-codes) and the created container registry protection rule.
-
-Can return the following status codes:
-
-- `201 Created`: The container registry protection rule was created successfully.
-- `400 Bad Request`: The container registry protection rule is invalid.
-- `401 Unauthorized`: The access token is invalid.
-- `403 Forbidden`: The user does not have permission to create a container registry protection rule.
-- `404 Not Found`: The project was not found.
-- `422 Unprocessable Entity`: The container registry protection rule could not be created, for example, because the `repository_path_pattern` is already taken.
-
-Example request:
-
-```shell
-curl --request POST \
-  --header "PRIVATE-TOKEN: <your_access_token>" \
-  --header "Content-Type: application/json" \
-  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules" \
-  --data '{
-        "repository_path_pattern": "flightjs/flight-needs-to-be-a-unique-path",
-        "minimum_access_level_for_push": "maintainer",
-        "minimum_access_level_for_delete": "maintainer"
-    }'
-```
-
-## Update a container registry protection rule
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.2.
-
-Update a container registry protection rule for a project.
-
-```plaintext
-PATCH /api/v4/projects/:id/registry/protection/rules/:protection_rule_id
-```
-
-Supported attributes:
-
-| Attribute                         | Type           | Required | Description |
-|-----------------------------------|----------------|----------|-------------|
-| `id`                              | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
-| `protection_rule_id`              | integer        | Yes      | ID of the protection rule to be updated. |
-| `repository_path_pattern`         | string         | No       | Container repository path pattern protected by the protection rule. For example `flight/flight-*`. Wildcard character `*` allowed. |
-| `minimum_access_level_for_push`   | string         | No       | Minimum GitLab access level to allow to push container images to the container registry. For example `maintainer`, `owner` or `admin`. Must be provided when `minimum_access_level_for_delete` is not set. To unset the value, use an empty string `""`. |
-| `minimum_access_level_for_delete` | string         | No       | Minimum GitLab access level to allow to delete container images in the container registry. For example `maintainer`, `owner`, `admin`. Must be provided when `minimum_access_level_for_push` is not set. To unset the value, use an empty string `""`. |
-
-If successful, returns [`200`](rest/troubleshooting.md#status-codes) and the updated protection rule.
-
-Can return the following status codes:
-
-- `200 OK`: The protection rule was patched successfully.
-- `400 Bad Request`: The patch is invalid.
-- `401 Unauthorized`: The access token is invalid.
-- `403 Forbidden`: The user does not have permission to patch the protection rule.
-- `404 Not Found`: The project was not found.
-- `422 Unprocessable Entity`: The protection rule could not be patched, for example, because the `repository_path_pattern` is already taken.
-
-Example request:
-
-```shell
-curl --request PATCH \
-  --header "PRIVATE-TOKEN: <your_access_token>" \
-  --header "Content-Type: application/json" \
-  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules/32" \
-  --data '{
-       "repository_path_pattern": "flight/flight-*"
-    }'
-```
-
-## Delete a container registry protection rule
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/457518) in GitLab 17.4.
-
-Deletes a container registry protection rule from a project.
-
-```plaintext
-DELETE /api/v4/projects/:id/registry/protection/rules/:protection_rule_id
-```
-
-Supported attributes:
-
-| Attribute            | Type           | Required | Description |
-|----------------------|----------------|----------|-------------|
-| `id`                 | integer/string | Yes      | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
-| `protection_rule_id` | integer        | Yes      | ID of the container registry protection rule to be deleted. |
-
-If successful, returns [`204 No Content`](rest/troubleshooting.md#status-codes).
-
-Can return the following status codes:
-
-- `204 No Content`: The protection rule was deleted successfully.
-- `400 Bad Request`: The `id` or the `protection_rule_id` are missing or are invalid.
-- `401 Unauthorized`: The access token is invalid.
-- `403 Forbidden`: The user does not have permission to delete the protection rule.
-- `404 Not Found`: The project or the protection rule was not found.
-
-Example request:
-
-```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
-  --url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules/1"
-```
+<!-- This redirect file can be deleted after <2025-03-02>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/packages/container_registry/container_protection_rules.md b/doc/user/packages/container_registry/container_protection_rules.md
index 8963c61863f9..5a23a4b16488 100644
--- a/doc/user/packages/container_registry/container_protection_rules.md
+++ b/doc/user/packages/container_registry/container_protection_rules.md
@@ -1,86 +1,13 @@
 ---
-stage: Container
-group: Container Registry
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
+redirect_to: 'container_repository_protection_rules.md'
+remove_date: '2025-02-28'
 ---
 
-# Protected container repositories
+<!-- markdownlint-disable -->
 
-DETAILS:
-**Tier:** Free, Premium, Ultimate
-**Offering:** GitLab.com, Self-managed
-**Status:** Experiment
+This document was moved to [another location](container_repository_protection_rules.md).
 
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/463669) in GitLab 16.7 [with a flag](../../../administration/feature_flags.md) named `containers_protected_containers`. Disabled by default. This feature is an [experiment](../../../policy/development_stages_support.md).
-
-FLAG:
-The availability of this feature is controlled by a feature flag.
-To selectively enable this feature for certain projects or groups, you need to use the root namespace of the project or group.
-It is not possible to enable this feature for projects individually.
-For more information, see the history.
-This feature is available for testing, but not ready for production use.
-
-By default, any user with at least the Developer role can push and delete
-container images to or from container repositories. Protect a container repository to restrict
-which users can make changes to container images in your container repository.
-
-When a container repository is protected, the default behavior enforces these restrictions on the container repository and its images:
-
-| Action                                                     | Minimum role         |
-|------------------------------------------------------------|----------------------|
-| Protect a container repository and its container images    | The Maintainer role. |
-| Push or create a new image in a container repository       | The role set in the [**Minimum access level for push**](#protect-a-container-repository-and-create-a-protection-rule) setting.   |
-| Push or update an existing image in a container repository | The role set in the [**Minimum access level for push**](#protect-a-container-repository-and-create-a-protection-rule) setting    |
-
-You can use a wildcard (`*`) to protect multiple container repositories with the same container protection rule.
-For example, you can protect different container repositories containing temporary container images built during a CI/CD pipeline.
-
-The following table contains examples of container protection rules that match multiple container repositories:
-
-| Path pattern with wildcard | Example matching container repositories |
-|----------------------------|-----------------------------------------|
-| `group/container-*`        | `group/container-prod`, `group/container-prod-sha123456789` |
-| `group/*container`         | `group/container`, `group/prod-container`, `group/prod-sha123456789-container` |
-| `group/*container*`        | `group/container`, `group/prod-sha123456789-container-v1` |
-
-You can apply several protection rules to the same container repository.
-A container repository is protected if at least one protection rule matches.
-
-## Protect a container repository and create a protection rule
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146523) in GitLab 16.10.
-
-Prerequisites:
-
-- You must have at least the Maintainer role.
-
-To protect a container repository:
-
-1. On the left sidebar, select **Search or go to** and find your project.
-1. Select **Settings > Packages and registries**.
-1. Under **Protected containers**, select **Add protection rule**.
-1. Complete the fields:
-   - **Repository path pattern** is a container repository path you want to protect.
-     The pattern can include a wildcard (`*`).
-   - **Minimum access level for push** describes the minimum access level required
-     to push (create or update) to the protected container repository path.
-1. Select **Protect**.
-
-The container protection rule is created, and appears in the settings.
-
-## Delete a container protection rule and unprotect a container repository
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146622) in GitLab 17.0.
-
-Prerequisites:
-
-- You must have at least the Maintainer role.
-
-To unprotect a container repository:
-
-1. On the left sidebar, select **Search or go to** and find your project.
-1. Select **Settings > Packages and registries**.
-1. Under **Protected containers**, next to the protection rule you want to delete, select **Delete** (**{remove}**).
-1. On the confirmation dialog, select **Delete**.
-
-The container protection rule is deleted, and does not appear in the settings.
+<!-- This redirect file can be deleted after <2025-02-28>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/packages/container_registry/container_repository_protection_rules.md b/doc/user/packages/container_registry/container_repository_protection_rules.md
new file mode 100644
index 000000000000..c99ca38b3dfc
--- /dev/null
+++ b/doc/user/packages/container_registry/container_repository_protection_rules.md
@@ -0,0 +1,86 @@
+---
+stage: Container
+group: Container Registry
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Protected container repositories
+
+DETAILS:
+**Tier:** Free, Premium, Ultimate
+**Offering:** GitLab.com, Self-managed
+**Status:** Experiment
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/463669) in GitLab 16.7 [with a flag](../../../administration/feature_flags.md) named `containers_protected_containers`. Disabled by default. This feature is an [experiment](../../../policy/development_stages_support.md).
+
+FLAG:
+The availability of this feature is controlled by a feature flag.
+To selectively enable this feature for certain projects or groups, you need to use the root namespace of the project or group.
+It is not possible to enable this feature for projects individually.
+For more information, see the history.
+This feature is available for testing, but not ready for production use.
+
+By default, any user with at least the Developer role can push and delete
+container images to or from container repositories. Protect a container repository to restrict
+which users can make changes to container images in your container repository.
+
+When a container repository is protected, the default behavior enforces these restrictions on the container repository and its images:
+
+| Action                                                     | Minimum role         |
+|------------------------------------------------------------|----------------------|
+| Protect a container repository and its container images.    | The Maintainer role. |
+| Push or create a new image in a container repository.       | The role set in the [**Minimum access level for push**](#create-a-container-repository-protection-rule) setting.   |
+| Push or update an existing image in a container repository. | The role set in the [**Minimum access level for push**](#create-a-container-repository-protection-rule) setting.    |
+
+You can use a wildcard (`*`) to protect multiple container repositories with the same container protection rule.
+For example, you can protect different container repositories containing temporary container images built during a CI/CD pipeline.
+
+The following table contains examples of container protection rules that match multiple container repositories:
+
+| Path pattern with wildcard | Example matching container repositories |
+|----------------------------|-----------------------------------------|
+| `group/container-*`        | `group/container-prod`, `group/container-prod-sha123456789` |
+| `group/*container`         | `group/container`, `group/prod-container`, `group/prod-sha123456789-container` |
+| `group/*container*`        | `group/container`, `group/prod-sha123456789-container-v1` |
+
+You can apply several protection rules to the same container repository.
+A container repository is protected if at least one protection rule matches.
+
+## Create a container repository protection rule
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146523) in GitLab 16.10.
+
+Prerequisites:
+
+- You must have at least the Maintainer role.
+
+To create a protection rule:
+
+1. On the left sidebar, select **Search or go to** and find your project.
+1. Select **Settings > Packages and registries**.
+1. Under **Protected container repositories**, select **Add protection rule**.
+1. Complete the fields:
+   - **Repository path pattern** is a container repository path you want to protect.
+     The pattern can include a wildcard (`*`).
+   - **Minimum access level for push** describes the minimum access level required
+     to push (create or update) to the protected container repository path.
+1. Select **Protect**.
+
+The protection rule is created and the container repository is now protected.
+
+## Delete a container repository protection rule
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146622) in GitLab 17.0.
+
+Prerequisites:
+
+- You must have at least the Maintainer role.
+
+To delete a protection rule:
+
+1. On the left sidebar, select **Search or go to** and find your project.
+1. Select **Settings > Packages and registries**.
+1. Under **Protected container repositories**, next to the protection rule you want to delete, select **Delete** (**{remove}**).
+1. On the confirmation dialog, select **Delete**.
+
+The protection rule is deleted and the container repository is no longer protected.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d82a4b51c76c..0a2ecfa1c6a3 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -14976,7 +14976,7 @@ msgstr ""
 msgid "ContainerRegistry|Delete container protection rule"
 msgstr ""
 
-msgid "ContainerRegistry|Delete container protection rule?"
+msgid "ContainerRegistry|Delete container repository protection rule?"
 msgstr ""
 
 msgid "ContainerRegistry|Delete image repository"
@@ -15087,7 +15087,7 @@ msgstr ""
 msgid "ContainerRegistry|Please try different search criteria"
 msgstr ""
 
-msgid "ContainerRegistry|Protected containers"
+msgid "ContainerRegistry|Protected container repositories"
 msgstr ""
 
 msgid "ContainerRegistry|Published %{timeInfo}"
@@ -15257,7 +15257,7 @@ msgstr ""
 msgid "ContainerRegistry|We are having trouble connecting to the Container Registry. Please try refreshing the page. If this error persists, please review  %{docLinkStart}the troubleshooting documentation%{docLinkEnd}."
 msgstr ""
 
-msgid "ContainerRegistry|When a container is protected, only certain user roles can push the protected container image, which helps to avoid tampering with the container image."
+msgid "ContainerRegistry|When a container repository is protected, only certain user roles can push the protected container image, which helps to avoid tampering with the container image."
 msgstr ""
 
 msgid "ContainerRegistry|While the rename is in progress, new uploads to the container registry are blocked. Ongoing uploads may fail and need to be retried."
@@ -15269,7 +15269,7 @@ msgstr ""
 msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. Push at least one Docker image in one of this group's projects in order to show up here. %{docLinkStart}More Information%{docLinkEnd}"
 msgstr ""
 
-msgid "ContainerRegistry|You are about to delete the container protection rule for %{repositoryPathPattern}."
+msgid "ContainerRegistry|You are about to delete the container repository protection rule for %{repositoryPathPattern}."
 msgstr ""
 
 msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/container_protection_rules_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/container_protection_rules_spec.js
index a041e8fb4044..67559677faec 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/container_protection_rules_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/container_protection_rules_spec.js
@@ -33,7 +33,7 @@ describe('Container protection rules project settings', () => {
 
   const findSettingsBlock = () => wrapper.findComponent(SettingsSection);
   const findTable = () =>
-    extendedWrapper(wrapper.findByRole('table', { name: /protected containers/i }));
+    extendedWrapper(wrapper.findByRole('table', { name: /protected container repositories/i }));
   const findTableBody = () => extendedWrapper(findTable().findAllByRole('rowgroup').at(1));
   const findTableLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
   const findTableRow = (i) => extendedWrapper(findTableBody().findAllByRole('row').at(i));
@@ -445,7 +445,7 @@ describe('Container protection rules project settings', () => {
             const modalId = getBinding(findTableRowButtonDelete(0).element, 'gl-modal');
 
             expect(findModal().props('modal-id')).toBe(modalId);
-            expect(findModal().props('title')).toBe('Delete container protection rule?');
+            expect(findModal().props('title')).toBe('Delete container repository protection rule?');
             expect(findModal().text()).toContain(
               'Users with at least the Developer role for this project will be able to push and delete container images to this repository path.',
             );
-- 
GitLab