Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-02-25 06:11:21 +00:00
parent a1e4372fbf
commit 223ffc2e59
85 changed files with 1036 additions and 760 deletions

View File

@ -1 +1 @@
e0204f0c2b736bb4b72f622c64bbf8220ede14bc
3bec5af36c5d3304174566c706807806eee8996d

View File

@ -303,7 +303,7 @@ gem 'gitlab-sidekiq-fetcher',
gem 'fugit', '~> 1.11.1', feature_category: :continuous_integration
# HTTP requests
gem 'httparty', '~> 0.21.0', feature_category: :shared
gem 'httparty', '~> 0.22.0', feature_category: :shared
# Colored output to console
gem 'rainbow', '~> 3.0', feature_category: :shared

View File

@ -330,7 +330,7 @@
{"name":"http-accept","version":"1.7.0","platform":"ruby","checksum":"c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126"},
{"name":"http-cookie","version":"1.0.5","platform":"ruby","checksum":"73756d46c7dbdc7023deecdb8a171348ea95a1b99810b31cfe8b4fb4e9a6318f"},
{"name":"http-form_data","version":"2.3.0","platform":"ruby","checksum":"cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3"},
{"name":"httparty","version":"0.21.0","platform":"ruby","checksum":"00ef7bf9a71f30a3bff88edeb5b16a34bea883ab67c246b3f0db2d6794fe1214"},
{"name":"httparty","version":"0.22.0","platform":"ruby","checksum":"78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c"},
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
{"name":"i18n","version":"1.14.4","platform":"ruby","checksum":"c7deedead0866ea9102975a4eab7968f53de50793a0c211a37808f75dd187551"},
{"name":"i18n_data","version":"0.13.1","platform":"ruby","checksum":"e5aa99b09a69b463bb0443fc1f9540351a49f3d1541c5e91316bafa035c63f66"},

View File

@ -74,7 +74,7 @@ PATH
gitlab-http (0.1.0)
activesupport (~> 7)
concurrent-ruby (~> 1.2)
httparty (~> 0.21.0)
httparty (~> 0.21)
ipaddress (~> 0.8.3)
net-http (= 0.6.0)
railties (~> 7)
@ -1015,7 +1015,8 @@ GEM
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
httparty (0.21.0)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
@ -2161,7 +2162,7 @@ DEPENDENCIES
health_check (~> 3.0)
html-pipeline (~> 2.14.3)
html2text
httparty (~> 0.21.0)
httparty (~> 0.22.0)
i18n_data (~> 0.13.1)
icalendar (~> 2.10.1)
influxdb-client (~> 3.1)
@ -2363,4 +2364,4 @@ DEPENDENCIES
yajl-ruby (~> 1.4.3)
BUNDLED WITH
2.5.11
2.6.5

View File

@ -330,7 +330,7 @@
{"name":"http-accept","version":"1.7.0","platform":"ruby","checksum":"c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126"},
{"name":"http-cookie","version":"1.0.5","platform":"ruby","checksum":"73756d46c7dbdc7023deecdb8a171348ea95a1b99810b31cfe8b4fb4e9a6318f"},
{"name":"http-form_data","version":"2.3.0","platform":"ruby","checksum":"cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3"},
{"name":"httparty","version":"0.21.0","platform":"ruby","checksum":"00ef7bf9a71f30a3bff88edeb5b16a34bea883ab67c246b3f0db2d6794fe1214"},
{"name":"httparty","version":"0.22.0","platform":"ruby","checksum":"78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c"},
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
{"name":"i18n","version":"1.14.4","platform":"ruby","checksum":"c7deedead0866ea9102975a4eab7968f53de50793a0c211a37808f75dd187551"},
{"name":"i18n_data","version":"0.13.1","platform":"ruby","checksum":"e5aa99b09a69b463bb0443fc1f9540351a49f3d1541c5e91316bafa035c63f66"},
@ -802,8 +802,8 @@
{"name":"webmock","version":"3.25.0","platform":"ruby","checksum":"573c23fc4887008c830f22da588db339ca38b6d59856fd57f5a068959474198e"},
{"name":"webrick","version":"1.8.2","platform":"ruby","checksum":"431746a349199546ff9dd272cae10849c865f938216e41c402a6489248f12f21"},
{"name":"websocket","version":"1.2.10","platform":"ruby","checksum":"2cc1a4a79b6e63637b326b4273e46adcddf7871caa5dc5711f2ca4061a629fa8"},
{"name":"websocket-driver","version":"0.7.7","platform":"java","checksum":"e2520a6049feb88691e042d631063fa96d50620fb7f53b30180ae6fb2cf75eb1"},
{"name":"websocket-driver","version":"0.7.7","platform":"ruby","checksum":"056d99f2cd545712cfb1291650fde7478e4f2661dc1db6a0fa3b966231a146b4"},
{"name":"websocket-driver","version":"0.7.6","platform":"java","checksum":"bc894b9e9d5aee55ac04b61003e1957c4ef411a5a048199587d0499785b505c3"},
{"name":"websocket-driver","version":"0.7.6","platform":"ruby","checksum":"f69400be7bc197879726ad8e6f5869a61823147372fd8928836a53c2c741d0db"},
{"name":"websocket-extensions","version":"0.1.5","platform":"ruby","checksum":"1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241"},
{"name":"wikicloth","version":"0.8.1","platform":"ruby","checksum":"7ac8a9ca0a948cf472851e521afc6c2a6b04a8f91ef1d824ba6a61ffbd60e6ca"},
{"name":"wisper","version":"2.0.1","platform":"ruby","checksum":"ce17bc5c3a166f241a2e6613848b025c8146fce2defba505920c1d1f3f88fae6"},

View File

@ -74,7 +74,7 @@ PATH
gitlab-http (0.1.0)
activesupport (~> 7)
concurrent-ruby (~> 1.2)
httparty (~> 0.21.0)
httparty (~> 0.21)
ipaddress (~> 0.8.3)
net-http (= 0.6.0)
railties (~> 7)
@ -1027,7 +1027,8 @@ GEM
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
httparty (0.21.0)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
@ -2007,8 +2008,7 @@ GEM
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.2)
websocket (1.2.10)
websocket-driver (0.7.7)
base64
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
wikicloth (0.8.1)
@ -2196,7 +2196,7 @@ DEPENDENCIES
health_check (~> 3.0)
html-pipeline (~> 2.14.3)
html2text
httparty (~> 0.21.0)
httparty (~> 0.22.0)
i18n_data (~> 0.13.1)
icalendar (~> 2.10.1)
influxdb-client (~> 3.1)
@ -2398,4 +2398,4 @@ DEPENDENCIES
yajl-ruby (~> 1.4.3)
BUNDLED WITH
2.5.11
2.6.5

View File

@ -51,6 +51,11 @@ export default {
type: String,
required: true,
},
disabled: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
@ -89,6 +94,7 @@ export default {
:data-track-action-for-errors="trackActionForErrors"
:title="title"
:type="type"
:disabled="disabled"
/>
<gl-button
v-gl-tooltip="toggleVisibilityLabel"
@ -96,6 +102,7 @@ export default {
category="tertiary"
:aria-label="toggleVisibilityLabel"
:icon="toggleVisibilityIcon"
:disabled="disabled"
@click="handleToggleVisibilityButtonClick"
/>
</div>

View File

@ -20,9 +20,11 @@ export const initPasswordInput = () => {
required,
autocomplete,
name,
disabled,
} = el.dataset;
const requiredAttr = required ? parseBoolean(required) : true;
const disabledAttr = disabled ? parseBoolean(disabled) : false;
// eslint-disable-next-line no-new
new Vue({
@ -39,6 +41,7 @@ export const initPasswordInput = () => {
autocomplete,
name,
required: requiredAttr,
disabled: disabledAttr,
},
});
},

View File

@ -5,9 +5,11 @@ import {
initDeleteUserModals,
} from '~/admin/users';
import initConfirmModal from '~/confirm_modal';
import { initPasswordInput } from '~/authentication/password';
initAdminUsersFilterApp();
initAdminUserActions();
initAdminUsersApp();
initDeleteUserModals();
initConfirmModal();
initPasswordInput();

View File

@ -788,14 +788,9 @@ module Ci
return unless project
return if user&.blocked?
if Feature.enabled?(:ci_async_build_hooks_execution, project)
return unless project.has_active_hooks?(:job_hooks) || project.has_active_integrations?(:job_hooks)
return unless project.has_active_hooks?(:job_hooks) || project.has_active_integrations?(:job_hooks)
Ci::ExecuteBuildHooksWorker.perform_async(project.id, build_data)
else
project.execute_hooks(build_data.dup, :job_hooks) if project.has_active_hooks?(:job_hooks)
project.execute_integrations(build_data.dup, :job_hooks) if project.has_active_integrations?(:job_hooks)
end
Ci::ExecuteBuildHooksWorker.perform_async(project.id, build_data)
end
def browsable_artifacts?

View File

@ -24,7 +24,7 @@ module Integrations
build_help_page_url(
'user/project/integrations/discord_notifications.md',
s_("DiscordService|Send notifications about project events to a Discord channel."),
_('How do I set up this integration?')
link_text: _('How do I set up this integration?')
)
end

View File

@ -29,7 +29,7 @@ module Integrations
'user/project/integrations/hangouts_chat.md',
'Before enabling this integration, create a webhook for the space in Google Chat where you want to ' \
'receive notifications from this project.',
_('How do I set up a Google Chat webhook?')
link_text: _('How do I set up a Google Chat webhook?')
)
end

View File

@ -424,7 +424,7 @@ module Integrations
@field_storage || :properties
end
def build_help_page_url(url_path, help_text, link_text = _("Learn More"), options = {})
def build_help_page_url(url_path, help_text, options = {}, link_text: _("Learn More"))
docs_link = ActionController::Base.helpers.link_to(
'',
Rails.application.routes.url_helpers.help_page_url(url_path, **options), # rubocop:disable Gitlab/DocumentationLinks/Link: -- existing code moved as is

View File

@ -196,7 +196,7 @@ module Integrations
build_help_page_url(
'integration/datadog.md',
s_('DatadogIntegration|Connect your GitLab projects to your Datadog account to synchronize repository metadata and enrich telemetry on your Datadog account.'),
_('How do I set up this integration?')
link_text: _('How do I set up this integration?')
)
end

View File

@ -31,13 +31,13 @@
- c.with_body do
= s_('AdminUsers|Reset link will be generated and sent to the user. User will be forced to set the password on first sign in.')
- else
.form-group.gl-form-group{ role: 'group' }
.form-group.gl-form-group.gl-form-input-lg{ role: 'group' }
= f.label :password, _('Password'), class: 'gl-block col-form-label'
= f.password_field :password, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-form-input-lg'
= f.password_field :password, class: 'form-control gl-form-input js-password-complexity-validation js-password', data: { autocomplete: 'new-password', disabled: f.object.force_random_password, required: false, id: 'user_password', name: 'user[password]' }
= render_if_exists 'shared/password_requirements_list'
.form-group.gl-form-group{ role: 'group' }
.form-group.gl-form-group.gl-form-input-lg{ role: 'group' }
= f.label :password_confirmation, _('Password confirmation'), class: 'gl-block col-form-label'
= f.password_field :password_confirmation, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input gl-form-input-lg'
= f.password_field :password_confirmation, class: 'form-control gl-form-input js-password', data: { autocomplete: 'new-password', disabled: f.object.force_random_password, required: false, id: 'user_password_confirmation', name: 'user[password_confirmation]' }
= render partial: 'access', locals: { f: f }

View File

@ -15,6 +15,8 @@ module Ci
project = Project.find_by_id(project_id)
return unless project
build_data = build_data.with_indifferent_access
project.execute_hooks(build_data, :job_hooks) if project.has_active_hooks?(:job_hooks)
project.execute_integrations(build_data, :job_hooks) if project.has_active_integrations?(:job_hooks)
end

View File

@ -1,9 +0,0 @@
---
name: ci_async_build_hooks_execution
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/499290
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177706
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/512832
milestone: '17.9'
group: group::pipeline authoring
type: gitlab_com_derisk
default_enabled: false

View File

@ -47,7 +47,7 @@ Other examples of internal users:
[GitLab Admin Bot](https://gitlab.com/gitlab-org/gitlab/-/blob/1d38cfdbed081f8b3fa14b69dd743440fe85081b/lib/users/internal.rb#L104)
is an internal user that cannot be accessed or modified by regular users and is responsible for many tasks including:
- Applying [default compliance frameworks](../user/group/compliance_frameworks.md#default-compliance-frameworks) to
- Applying [default compliance frameworks](../user/compliance/compliance_frameworks.md#default-compliance-frameworks) to
projects.
- [Automatically deactivating dormant users](moderate_users.md#automatically-deactivate-dormant-users).
- [Automatically deleting unconfirmed users](moderate_users.md#automatically-delete-unconfirmed-users).

View File

@ -43,16 +43,16 @@ If you don't have access to the `gitaly` command, alternatives to server hooks i
## Set server hooks for a repository
{{< tabs >}}
{{< tab title="GitLab 15.11 and later" >}}
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access. Existing Git hooks don't need migrating for the `hooks set` command.
{{< /history >}}
{{< tabs >}}
{{< tab title="GitLab 15.11 and later" >}}
Prerequisites:
- The [storage name](gitaly/configure_gitaly.md#gitlab-requires-a-default-repository-storage), path to the Gitaly configuration file
@ -181,16 +181,16 @@ subdirectories.
## Remove server hooks for a repository
{{< tabs >}}
{{< tab title="GitLab 15.11 and later" >}}
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access.
{{< /history >}}
{{< tabs >}}
{{< tab title="GitLab 15.11 and later" >}}
Prerequisites:
- The [storage name and relative path](repository_storage_paths.md#from-project-name-to-hashed-path) for the repository.

View File

@ -521,7 +521,7 @@ To set the maximum file size:
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/389467) in GitLab 15.9
and was removed in 17.0. From 17.4, it is available only behind the feature flag `required_pipelines`, disabled by default.
Use [compliance pipelines](../../user/group/compliance_pipelines.md) instead. This change is a breaking change.
Use [compliance pipelines](../../user/compliance/compliance_pipelines.md) instead. This change is a breaking change.
{{< /alert >}}

View File

@ -141,9 +141,9 @@ In this example:
{{< alert type="note" >}}
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857), projects that use [compliance pipelines](../../user/group/compliance_pipelines.md) can have prefilled variables not appear
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857), projects that use [compliance pipelines](../../user/compliance/compliance_pipelines.md) can have prefilled variables not appear
when running a pipeline manually. To workaround this issue,
[change the compliance pipeline configuration](../../user/group/compliance_pipelines.md#prefilled-variables-are-not-shown).
[change the compliance pipeline configuration](../../user/compliance/compliance_pipelines.md#prefilled-variables-are-not-shown).
{{< /alert >}}

View File

@ -554,7 +554,7 @@ start. Jobs in the current stage are not stopped and continue to run.
- If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage.
- If a stage is defined but no jobs use it, the stage is not visible in the pipeline,
which can help [compliance pipeline configurations](../../user/group/compliance_pipelines.md):
which can help [compliance pipeline configurations](../../user/compliance/compliance_pipelines.md):
- Stages can be defined in the compliance configuration but remain hidden if not used.
- The defined stages become visible when developers use them in job definitions.
@ -4651,7 +4651,7 @@ In this example:
section. The project containing the `include` section can be different than the project
running the pipeline when using:
- [Nested includes](includes.md#use-nested-includes).
- [Compliance pipelines](../../user/group/compliance_pipelines.md).
- [Compliance pipelines](../../user/compliance/compliance_pipelines.md).
- `rules:exists` cannot search for the presence of [artifacts](../jobs/job_artifacts.md),
because `rules` evaluation happens before jobs run and artifacts are fetched.

View File

@ -106,6 +106,12 @@ you must enable and configure product analytics.
### Product analytics provider
{{< history >}}
- Self-managed provider [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117804) in GitLab 16.0.
{{< /history >}}
Your GitLab instance connects to a product analytics provider.
A product analytics provider is the collection of services required to receive,
process, store and query your analytics data.
@ -114,12 +120,6 @@ process, store and query your analytics data.
{{< tab title="GitLab-managed provider" >}}
{{< details >}}
- Offering: GitLab.com
{{< /details >}}
On GitLab.com you can use a GitLab-managed provider offered only in the Google Cloud Platform zone `us-central-1`.
If GitLab manages your product analytics provider, then your analytics data is retained for one year.
@ -129,8 +129,6 @@ You can request to delete your data at any time by [contacting support](https://
{{< tab title="Self-managed provider" >}}
>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117804) in GitLab 16.0.
A self-managed product analytics provider is a deployed instance of the
[product analytics Helm charts](https://gitlab.com/gitlab-org/analytics-section/product-analytics/helm-charts).

View File

@ -18,13 +18,13 @@ title: 'Tutorial: Create a compliance pipeline (deprecated)'
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
and is planned for removal in 18.0. Use [pipeline execution policy type](../../user/application_security/policies/pipeline_execution_policies.md) instead.
This change is a breaking change. For more information, see the [migration guide](../../user/group/compliance_pipelines.md#pipeline-execution-policies-migration).
This change is a breaking change. For more information, see the [migration guide](../../user/compliance/compliance_pipelines.md#pipeline-execution-policies-migration).
{{< /alert >}}
You can use [compliance pipelines](../../user/group/compliance_pipelines.md) to ensure specific
You can use [compliance pipelines](../../user/compliance/compliance_pipelines.md) to ensure specific
compliance-related jobs are run on pipelines for all projects in a group. Compliance pipelines are applied
to projects through [compliance frameworks](../../user/group/compliance_frameworks.md).
to projects through [compliance frameworks](../../user/compliance/compliance_frameworks.md).
In this tutorial, you:
@ -57,7 +57,7 @@ To create the new group:
## Create a new compliance pipeline project
Now you're ready to create a compliance pipeline project. This project contains the
[compliance pipeline configuration](../../user/group/compliance_pipelines.md#example-configuration) to apply to all
[compliance pipeline configuration](../../user/compliance/compliance_pipelines.md#example-configuration) to apply to all
projects with the compliance framework applied.
To create the compliance pipeline project:
@ -191,6 +191,6 @@ Notice the pipeline runs two jobs in a **test** stage:
Congratulations, you've created and configured a compliance pipeline!
See more [example compliance pipeline configurations](../../user/group/compliance_pipelines.md#example-configuration).
See more [example compliance pipeline configurations](../../user/compliance/compliance_pipelines.md#example-configuration).
<!--- end_remove -->

View File

@ -193,7 +193,7 @@ Security and compliance teams must ensure that security scans:
GitLab provides two methods of accomplishing this, each with advantages and disadvantages.
- [Compliance framework pipelines](../group/compliance_pipelines.md)
- [Compliance framework pipelines](../compliance/compliance_pipelines.md)
are recommended when:
- Scan execution enforcement is required for any scanner that uses a GitLab template, such as SAST IaC, DAST, Dependency Scanning,

View File

@ -32,8 +32,8 @@ compliance:
| Feature | Instances | Groups | Projects | Description |
|:-----------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------|:-------------------------------------|:-------------------------------------|:------------|
| [Compliance frameworks](../group/compliance_frameworks.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Describe the type of compliance requirements projects must follow. |
| [Compliance pipelines](../group/compliance_pipelines.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Define a pipeline configuration to run for any projects with a given compliance framework. |
| [Compliance frameworks](../compliance/compliance_frameworks.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Describe the type of compliance requirements projects must follow. |
| [Compliance pipelines](../compliance/compliance_pipelines.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Define a pipeline configuration to run for any projects with a given compliance framework. |
| [Merge request approval policy approval settings](../application_security/policies/merge_request_approval_policies.md#approval_settings) | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Enforce a merge request approval policy enforcing multiple approvers and override various project settings in all enforced groups or projects across your GitLab instance or group. |
## Audit management

View File

@ -78,6 +78,34 @@ To delete a compliance framework from the compliance frameworks report:
1. Hover over framework and select **Edit the framework**.
1. Select the **Delete framework** to delete compliance framework.
## Set and remove a compliance framework as default
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181500) in GitLab 17.10.
{{< /history >}}
Prerequisites:
- You must be an administrator or have the Owner role for the group.
To set a compliance framework as [default](../compliance_frameworks.md#default-compliance-frameworks)] from the compliance frameworks report:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Frameworks** tab.
1. Next to the compliance framework you want to set as default, select {{< icon name="pencil" >}} action.
1. Select the **Set as default** to set as default.
To remove a compliance framework as default from the compliance frameworks report:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Frameworks** tab.
1. Next to the compliance framework that is default, select {{< icon name="pencil" >}} action.
1. Select the **Remove as default** to remove as default.
## Export a report of compliance frameworks in a group
{{< history >}}

View File

@ -0,0 +1,112 @@
---
stage: Software Supply Chain Security
group: Compliance
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
title: Compliance frameworks
---
{{< details >}}
- Tier: Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
{{< /details >}}
You can create a compliance framework that is a label to identify that your project has certain compliance
requirements or needs additional oversight.
In the Ultimate tier, the compliance framework can optionally enforce
[compliance pipeline configuration](compliance_pipelines.md) and
[security policies](../application_security/policies/_index.md#scope) to the projects on which it is applied.
Compliance frameworks are created on top-level groups. If a project is moved outside of its existing top-level group,
its frameworks are removed.
You can apply up to 20 compliance frameworks to each project.
For a click-through demo, see [Compliance frameworks](https://gitlab.navattic.com/compliance).
<!-- Demo published on 2025-01-27 -->
## Prerequisites
- To create, edit, and delete compliance frameworks, users must have either:
- The Owner role for the top-level group.
- Be assigned a [custom role](../custom_roles.md) with the `admin_compliance_framework`
[custom permission](../custom_roles/abilities.md#compliance-management).
- To add or remove a compliance framework to or from a project, the group to which the project belongs must have a
compliance framework.
## Create, edit, or delete a compliance framework
You can create, edit, or delete a compliance framework from a compliance framework report. For more information, see:
- [Create a new compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#create-a-new-compliance-framework).
- [Edit a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#edit-a-compliance-framework).
- [Delete a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#delete-a-compliance-framework).
You can create, edit, or delete a compliance framework from a compliance projects report. For more information, see:
- [Create a new compliance framework](../compliance/compliance_center/compliance_projects_report.md#create-a-new-compliance-framework).
- [Edit a compliance framework](../compliance/compliance_center/compliance_projects_report.md#edit-a-compliance-framework).
- [Delete a compliance framework](../compliance/compliance_center/compliance_projects_report.md#delete-a-compliance-framework).
Subgroups and projects have access to all compliance frameworks created on their top-level group. However, compliance frameworks cannot be created, edited,
or deleted at the subgroup or project level. Project owners can choose a framework to apply to their projects.
## Apply a compliance framework to a project
{{< history >}}
- Assigning multiple compliance frameworks [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13294) in GitLab 17.3.
{{< /history >}}
You can apply multiple compliance frameworks to a project but cannot apply compliance frameworks to projects in personal namespaces.
To apply a compliance framework to a project, apply the compliance framework through the
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#apply-a-compliance-framework-to-projects-in-a-group).
You can use the [GraphQL API](../../api/graphql/reference/_index.md#mutationprojectupdatecomplianceframeworks) to apply one or many
compliance frameworks to a project.
If you create compliance frameworks on subgroups with GraphQL, the framework is created on the root ancestor if the user
has the correct permissions. The GitLab UI presents a read-only view to discourage this behavior.
## Default compliance frameworks
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375036) in GitLab 15.6.
{{< /history >}}
Group owners can set a default compliance framework. The default framework is applied to all the new and imported
projects that are created in that group. It does not affect the framework applied to the existing projects. The
default framework cannot be deleted.
A compliance framework that is set to default has a **default** label.
### Set and remove a default by using the compliance center
To set as default (or remove the default) from [compliance projects report](../compliance/compliance_center/compliance_projects_report.md):
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Projects** tab.
1. Hover over a compliance framework, select the **Edit Framework** tab.
1. Select **Set as default**.
1. Select **Save changes**.
To set as default (or remove the default) from [compliance framework report](../compliance/compliance_center/compliance_frameworks_report.md):
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Frameworks** tab.
1. Hover over a compliance framework, select the **Edit Framework** tab.
1. Select **Set as default**.
1. Select **Save changes**.
## Remove a compliance framework from a project
To remove a compliance framework from one or multiple project in a group, remove the compliance framework through the
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#remove-a-compliance-framework-from-projects-in-a-group).

View File

@ -0,0 +1,416 @@
---
stage: Software Supply Chain Security
group: Compliance
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
title: Compliance pipelines (deprecated)
---
<!--- start_remove The following content will be removed on remove_date: '2025-08-15' -->
{{< details >}}
- Tier: Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
{{< /details >}}
{{< alert type="warning" >}}
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
and is planned for removal in 19.0. Use [pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) instead.
This change is a breaking change. For more information, see the [migration guide](#pipeline-execution-policies-migration).
{{< /alert >}}
Group owners can configure a compliance pipeline in a project separate to other projects. By default, the compliance
pipeline configuration (for example, `.compliance-gitlab-ci.yml`) is run instead of the pipeline configuration (for example, `.gitlab-ci.yml`) of labeled
projects.
However, the compliance pipeline configuration can reference the `.gitlab-ci.yml` file of the labeled projects so that:
- The compliance pipeline can also run jobs of labeled project pipelines. This allows for centralized control of
pipeline configuration.
- Jobs and variables defined in the compliance pipeline can't be changed by variables in the labeled project's
`.gitlab-ci.yml` file.
{{< alert type="note" >}}
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/414004), project pipelines must be included first at the top of compliance pipeline configuration
to prevent projects overriding settings downstream.
{{< /alert >}}
For more information, see:
- [Example configuration](#example-configuration) for help configuring a compliance pipeline that runs jobs from
labeled project pipeline configuration.
- The [Create a compliance pipeline](../../tutorials/compliance_pipeline/_index.md) tutorial.
## Pipeline execution policies migration
To consolidate and simplify scan and pipeline enforcement, we have introduced pipeline execution policies. We deprecated
compliance pipelines in GitLab 17.3 and will remove compliance pipelines in GitLab 19.0.
Pipeline execution policies extend a project's `.gitlab-ci.yml` file with the configuration provided in separate YAML file
(for example, `pipeline-execution.yml`) linked in the pipeline execution policy.
By default, when creating a new compliance framework, you are directed to use the pipeline execution policy type instead
of compliance pipelines.
Existing compliance pipelines must be migrated. Customers should migrate from compliance pipelines to the new
[pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) as soon as possible.
### Migrate an existing compliance framework
To migrate an existing compliance framework to use the pipeline execution policy type:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. [Edit](compliance_frameworks.md#create-edit-or-delete-a-compliance-framework) the existing compliance framework.
1. In the banner than appears, select **Migrate pipeline to a policy** to create a new policy in the security policies.
1. Edit the compliance framework again to remove the compliance pipeline.
For more information, see [Security policy project](../application_security/policies/_index.md#security-policy-project).
If you receive a `Pipeline execution policy error: Job names must be unique` error during the migration, see the
[relevant troubleshooting information](#error-job-names-must-be-unique).
## Effect on labeled projects
Users have no way of knowing that a compliance pipeline has been configured and might be confused why their own
pipelines are not running at all, or include jobs that they did not define themselves.
When authoring pipelines on a labeled project, there is no indication that a compliance pipeline has been configured.
The only marker at the project level is the compliance framework label itself, but the label does not say whether the
framework has a compliance pipeline configured or not.
Therefore, communicate with project users about compliance pipeline configuration to reduce uncertainty and confusion.
### Multiple compliance frameworks
You can [apply to a single project](compliance_frameworks.md#apply-a-compliance-framework-to-a-project) multiple compliance frameworks with compliance pipelines configured.
In this case, only the first compliance framework applied to a project has its compliance pipeline included in the project pipeline.
To ensure that the correct compliance pipeline is included in a project:
1. Remove all compliance frameworks from the project.
1. Apply the compliance framework with the correct compliance pipeline to the project.
1. Apply additional compliance frameworks to the project.
## Configure a compliance pipeline
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383209) in GitLab 15.11, compliance frameworks moved to compliance center.
{{< /history >}}
To configure a compliance pipeline:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure** > **Compliance Center**.
1. Select **Frameworks** section.
1. Select **New framework** section, add information of compliance framework including path to the compliance framework configuration. Use the
`path/file.y[a]ml@group-name/project-name` format. For example:
- `.compliance-ci.yml@gitlab-org/gitlab`.
- `.compliance-ci.yaml@gitlab-org/gitlab`.
This configuration is inherited by projects where the compliance framework label is
[applied](../project/working_with_projects.md#add-a-compliance-framework-to-a-project). In projects with the applied compliance
framework label, the compliance pipeline configuration is run instead of the labeled project's own pipeline configuration.
The user running the pipeline in the labeled project must at least have the Reporter role on the compliance project.
When used to enforce scan execution, this feature has some overlap with
[scan execution policies](../application_security/policies/scan_execution_policies.md). We have not
[unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312). For details on
the similarities and differences between these features, see [Enforce scan execution](../application_security/_index.md#enforce-scan-execution).
### Example configuration
The following example `.compliance-gitlab-ci.yml` includes the `include` keyword to ensure labeled project pipeline
configuration is also executed.
```yaml
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA' # Must be defined or MR pipelines always use the use default branch
rules:
- if: $CI_PROJECT_PATH != "my-group/project-1" # Must run on projects other than the one hosting this configuration.
# Allows compliance team to control the ordering and interweaving of stages/jobs.
# Stages without jobs defined will remain hidden.
stages:
- pre-compliance
- build
- test
- pre-deploy-compliance
- deploy
- post-compliance
variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
FOO: sast
sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml
variables:
FOO: sast
image: ruby:2.6
stage: pre-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
sanity check:
image: ruby:2.6
stage: pre-deploy-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
audit trail:
image: ruby:2.7
stage: post-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
```
The `rules` configuration in the `include` definition avoids circular inclusion in case the compliance pipeline must be able to run in the host project itself.
You can leave it out if your compliance pipeline only ever runs in labeled projects.
#### Compliance pipelines and custom pipeline configuration hosted externally
The example above assumes that all projects host their pipeline configuration in the same project.
If any projects use [configuration hosted externally](../../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file),
the example configuration does not work. See [issue 393960](https://gitlab.com/gitlab-org/gitlab/-/issues/393960)
for more details.
With projects that use externally hosted configuration, you can try the this workaround:
- The `include` section in the example compliance pipeline configuration must be adjusted.
For example, using [`include:rules`](../../ci/yaml/includes.md#use-rules-with-include):
```yaml
include:
# If the custom path variables are defined, include the project's external config file.
- project: '$PROTECTED_PIPELINE_CI_PROJECT_PATH'
file: '$PROTECTED_PIPELINE_CI_CONFIG_PATH'
ref: '$PROTECTED_PIPELINE_CI_REF'
rules:
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH && $PROTECTED_PIPELINE_CI_CONFIG_PATH && $PROTECTED_PIPELINE_CI_REF
# If any custom path variable is not defined, include the project's internal config file as normal.
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
rules:
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH == null || $PROTECTED_PIPELINE_CI_CONFIG_PATH == null || $PROTECTED_PIPELINE_CI_REF == null
```
- [CI/CD variables](../../ci/variables/_index.md) must be added to projects with external
pipeline configuration. In this example:
- `PROTECTED_PIPELINE_CI_PROJECT_PATH`: The path to the project hosting the configuration file, for example `group/subgroup/project`.
- `PROTECTED_PIPELINE_CI_CONFIG_PATH`: The path to the configuration file in the project, for example `path/to/.gitlab-ci.yml`.
- `PROTECTED_PIPELINE_CI_REF`: The ref to use when retrieving the configuration file, for example `main`.
#### Compliance pipelines in merge requests originating in project forks
When a merge request originates in a fork, the branch to be merged usually only exists in the fork.
When creating such a merge request against a project with compliance pipelines, the above snippet fails with a
`Project <project-name> reference <branch-name> does not exist!` error message.
This error occurs because in the context of the target project, `$CI_COMMIT_REF_NAME` evaluates to a non-existing
branch name.
To get the correct context, use `$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` instead of `$CI_PROJECT_PATH`.
This variable is only available in
[merge request pipelines](../../ci/pipelines/merge_request_pipelines.md).
For example, for a configuration that supports both merge request pipelines originating in project forks and branch pipelines,
you need to [combine both `include` directives with `rules:if`](../../ci/yaml/includes.md#use-rules-with-include):
```yaml
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
- project: '$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME'
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME'
rules:
- if: $CI_PIPELINE_SOURCE != 'merge_request_event'
```
#### Compliance pipelines in projects with no configuration file
The [example configuration](#example-configuration) above assumes that all projects contain
a pipeline configuration file (`.gitlab-ci.yml` by default). However, in projects
with no configuration file (and therefore no pipelines by default), the compliance pipeline
fails because the file specified in `include:project` is required.
To only include a configuration file if it exists in a target project, use
[`rules:exists:project`](../../ci/yaml/_index.md#rulesexistsproject):
```yaml
include: # Execute individual project's configuration
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
rules:
- exists:
paths:
- '$CI_CONFIG_PATH'
project: '$CI_PROJECT_PATH'
ref: '$CI_COMMIT_SHA'
```
In this example, a configuration file is only included if it exists for the given `ref`
in the project in `exists:project: $CI_PROJECT_PATH'`.
If `exists:project` is not specified in the compliance pipeline configuration, it searches for files in the project
in which the `include` is defined. In compliance pipelines, the `include` from the example above
is defined in the project hosting the compliance pipeline configuration file, not the project
running the pipeline.
## Ensure compliance jobs are always run
Compliance pipelines [use GitLab CI/CD](../../ci/_index.md) to give you an incredible amount of flexibility
for defining any sort of compliance jobs you like. Depending on your goals, these jobs
can be configured to be:
- Modified by users.
- Non-modifiable.
Generally, if a value in a compliance job:
- Is set, it cannot be changed or overridden by project-level configurations.
- Is not set, a project-level configuration may be set.
Either might be wanted or not depending on your use case.
The following are a few best practices for ensuring that these jobs are always run exactly
as you define them and that downstream, project-level pipeline configurations
cannot change them:
- Add [a `rules:when:always` block](../../ci/yaml/_index.md#when) to each of your compliance jobs. This ensures they are
non-modifiable and are always run.
- Explicitly set any [variables](../../ci/yaml/_index.md#variables) the job references. This:
- Ensures that project-level pipeline configurations do not set them and alter their
behavior. For example, see `before_script` and `after_script` configuration in the [example configuration](#example-configuration).
- Includes any jobs that drive the logic of your job.
- Explicitly set the [container image](../../ci/yaml/_index.md#image) to run the job in. This ensures that your script
steps execute in the correct environment.
- Explicitly set any relevant GitLab pre-defined [job keywords](../../ci/yaml/_index.md#job-keywords).
This ensures that your job uses the settings you intend and that they are not overridden by
project-level pipelines.
## Troubleshooting
### Compliance jobs are overwritten by target repository
If you use the `extends` statement in a compliance pipeline configuration, compliance jobs are overwritten by the target repository job. For example,
you could have the following `.compliance-gitlab-ci.yml` configuration:
```yaml
"compliance job":
extends:
- .compliance_template
stage: build
.compliance_template:
script:
- echo "take compliance action"
```
You could also have the following `.gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: test
script:
- echo "overwriting compliance action"
```
This configuration results in the target repository pipeline overwriting the compliance pipeline, and you get the following message:
`overwriting compliance action`.
To avoid overwriting a compliance job, don't use the `extends` keyword in compliance pipeline configuration. For example,
you could have the following `.compliance-gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: build
script:
- echo "take compliance action"
```
You could also have the following `.gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: test
script:
- echo "overwriting compliance action"
```
This configuration doesn't overwrite the compliance pipeline and you get the following message:
`take compliance action`.
### Prefilled variables are not shown
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857),
compliance pipelines in GitLab 15.3 and later can prevent
[prefilled variables](../../ci/pipelines/_index.md#prefill-variables-in-manual-pipelines)
from appearing when manually starting a pipeline.
To workaround this issue, use `ref: '$CI_COMMIT_SHA'` instead of `ref: '$CI_COMMIT_REF_NAME'`
in the `include:` statement that executes the individual project's configuration.
The [example configuration](#example-configuration) has been updated with this change:
```yaml
include:
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
```
### Error: `Job names must be unique`
To configure a compliance pipeline, the [example configuration](#example-configuration) recommends including the
individual project configuration with `include.project`.
The configuration can lead to an error when running the projects pipeline: `Pipeline execution policy error: Job names must be unique`.
This error occurs because the pipeline execution policy includes the project's `.gitlab-ci.yml` and tries to insert the
jobs when the jobs have already been declared in the pipeline.
To resolve this error, remove `include.project` from the separate YAML file linked in the pipeline execution policy.
<!--- end_remove -->

View File

@ -43,7 +43,7 @@ License approval policies rely on the output of a dependency scanning job to ver
To ensure enforcement of your policies, you should enable dependency scanning on your target development projects. You can achieve this a few different ways:
- Create a global [scan execution policy](../application_security/policies/scan_execution_policies.md) that enforces Dependency Scanning to run in all target development projects.
- Use a [Compliance Pipeline](../group/compliance_frameworks.md) to define a Dependency Scanning job that is enforced on projects enforced by a given Compliance Framework.
- Use a [Compliance Pipeline](../compliance/compliance_frameworks.md) to define a Dependency Scanning job that is enforced on projects enforced by a given Compliance Framework.
- Work with development teams to configure [Dependency Scanning](../application_security/dependency_scanning/_index.md) in each of their project's `.gitlab-ci.yml` files or enable by using the [Security Configuration panel](../application_security/configuration/_index.md).
License approval policies require license information from [GitLab-supported packages](license_scanning_of_cyclonedx_files/_index.md#supported-languages-and-package-managers).

View File

@ -1,112 +1,13 @@
---
stage: Software Supply Chain Security
group: Compliance
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
title: Compliance frameworks
redirect_to: '../compliance/compliance_frameworks.md'
remove_date: '2025-05-25'
---
{{< details >}}
<!-- markdownlint-disable -->
- Tier: Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
This document was moved to [another location](../compliance/compliance_frameworks.md).
{{< /details >}}
You can create a compliance framework that is a label to identify that your project has certain compliance
requirements or needs additional oversight.
In the Ultimate tier, the compliance framework can optionally enforce
[compliance pipeline configuration](compliance_pipelines.md) and
[security policies](../application_security/policies/_index.md#scope) to the projects on which it is applied.
Compliance frameworks are created on top-level groups. If a project is moved outside of its existing top-level group,
its frameworks are removed.
You can apply up to 20 compliance frameworks to each project.
For a click-through demo, see [Compliance frameworks](https://gitlab.navattic.com/compliance).
<!-- Demo published on 2025-01-27 -->
## Prerequisites
- To create, edit, and delete compliance frameworks, users must have either:
- The Owner role for the top-level group.
- Be assigned a [custom role](../custom_roles.md) with the `admin_compliance_framework`
[custom permission](../custom_roles/abilities.md#compliance-management).
- To add or remove a compliance framework to or from a project, the group to which the project belongs must have a
compliance framework.
## Create, edit, or delete a compliance framework
You can create, edit, or delete a compliance framework from a compliance framework report. For more information, see:
- [Create a new compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#create-a-new-compliance-framework).
- [Edit a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#edit-a-compliance-framework).
- [Delete a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#delete-a-compliance-framework).
You can create, edit, or delete a compliance framework from a compliance projects report. For more information, see:
- [Create a new compliance framework](../compliance/compliance_center/compliance_projects_report.md#create-a-new-compliance-framework).
- [Edit a compliance framework](../compliance/compliance_center/compliance_projects_report.md#edit-a-compliance-framework).
- [Delete a compliance framework](../compliance/compliance_center/compliance_projects_report.md#delete-a-compliance-framework).
Subgroups and projects have access to all compliance frameworks created on their top-level group. However, compliance frameworks cannot be created, edited,
or deleted at the subgroup or project level. Project owners can choose a framework to apply to their projects.
## Apply a compliance framework to a project
{{< history >}}
- Assigning multiple compliance frameworks [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13294) in GitLab 17.3.
{{< /history >}}
You can apply multiple compliance frameworks to a project but cannot apply compliance frameworks to projects in personal namespaces.
To apply a compliance framework to a project, apply the compliance framework through the
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#apply-a-compliance-framework-to-projects-in-a-group).
You can use the [GraphQL API](../../api/graphql/reference/_index.md#mutationprojectupdatecomplianceframeworks) to apply one or many
compliance frameworks to a project.
If you create compliance frameworks on subgroups with GraphQL, the framework is created on the root ancestor if the user
has the correct permissions. The GitLab UI presents a read-only view to discourage this behavior.
## Default compliance frameworks
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375036) in GitLab 15.6.
{{< /history >}}
Group owners can set a default compliance framework. The default framework is applied to all the new and imported
projects that are created in that group. It does not affect the framework applied to the existing projects. The
default framework cannot be deleted.
A compliance framework that is set to default has a **default** label.
### Set and remove a default by using the compliance center
To set as default (or remove the default) from [compliance projects report](../compliance/compliance_center/compliance_projects_report.md):
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Projects** tab.
1. Hover over a compliance framework, select the **Edit Framework** tab.
1. Select **Set as default**.
1. Select **Save changes**.
To set as default (or remove the default) from [compliance framework report](../compliance/compliance_center/compliance_frameworks_report.md):
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. On the page, select the **Frameworks** tab.
1. Hover over a compliance framework, select the **Edit Framework** tab.
1. Select **Set as default**.
1. Select **Save changes**.
## Remove a compliance framework from a project
To remove a compliance framework from one or multiple project in a group, remove the compliance framework through the
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#remove-a-compliance-framework-from-projects-in-a-group).
<!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
<!-- 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 (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/development/documentation/redirects -->

View File

@ -1,416 +1,13 @@
---
stage: Software Supply Chain Security
group: Compliance
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
title: Compliance pipelines (deprecated)
redirect_to: '../compliance/compliance_pipelines.md'
remove_date: '2025-05-25'
---
<!--- start_remove The following content will be removed on remove_date: '2025-08-15' -->
<!-- markdownlint-disable -->
{{< details >}}
This document was moved to [another location](../compliance/compliance_pipelines.md).
- Tier: Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
{{< /details >}}
{{< alert type="warning" >}}
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
and is planned for removal in 19.0. Use [pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) instead.
This change is a breaking change. For more information, see the [migration guide](#pipeline-execution-policies-migration).
{{< /alert >}}
Group owners can configure a compliance pipeline in a project separate to other projects. By default, the compliance
pipeline configuration (for example, `.compliance-gitlab-ci.yml`) is run instead of the pipeline configuration (for example, `.gitlab-ci.yml`) of labeled
projects.
However, the compliance pipeline configuration can reference the `.gitlab-ci.yml` file of the labeled projects so that:
- The compliance pipeline can also run jobs of labeled project pipelines. This allows for centralized control of
pipeline configuration.
- Jobs and variables defined in the compliance pipeline can't be changed by variables in the labeled project's
`.gitlab-ci.yml` file.
{{< alert type="note" >}}
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/414004), project pipelines must be included first at the top of compliance pipeline configuration
to prevent projects overriding settings downstream.
{{< /alert >}}
For more information, see:
- [Example configuration](#example-configuration) for help configuring a compliance pipeline that runs jobs from
labeled project pipeline configuration.
- The [Create a compliance pipeline](../../tutorials/compliance_pipeline/_index.md) tutorial.
## Pipeline execution policies migration
To consolidate and simplify scan and pipeline enforcement, we have introduced pipeline execution policies. We deprecated
compliance pipelines in GitLab 17.3 and will remove compliance pipelines in GitLab 19.0.
Pipeline execution policies extend a project's `.gitlab-ci.yml` file with the configuration provided in separate YAML file
(for example, `pipeline-execution.yml`) linked in the pipeline execution policy.
By default, when creating a new compliance framework, you are directed to use the pipeline execution policy type instead
of compliance pipelines.
Existing compliance pipelines must be migrated. Customers should migrate from compliance pipelines to the new
[pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) as soon as possible.
### Migrate an existing compliance framework
To migrate an existing compliance framework to use the pipeline execution policy type:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. [Edit](compliance_frameworks.md#create-edit-or-delete-a-compliance-framework) the existing compliance framework.
1. In the banner than appears, select **Migrate pipeline to a policy** to create a new policy in the security policies.
1. Edit the compliance framework again to remove the compliance pipeline.
For more information, see [Security policy project](../application_security/policies/_index.md#security-policy-project).
If you receive a `Pipeline execution policy error: Job names must be unique` error during the migration, see the
[relevant troubleshooting information](#error-job-names-must-be-unique).
## Effect on labeled projects
Users have no way of knowing that a compliance pipeline has been configured and might be confused why their own
pipelines are not running at all, or include jobs that they did not define themselves.
When authoring pipelines on a labeled project, there is no indication that a compliance pipeline has been configured.
The only marker at the project level is the compliance framework label itself, but the label does not say whether the
framework has a compliance pipeline configured or not.
Therefore, communicate with project users about compliance pipeline configuration to reduce uncertainty and confusion.
### Multiple compliance frameworks
You can [apply to a single project](compliance_frameworks.md#apply-a-compliance-framework-to-a-project) multiple compliance frameworks with compliance pipelines configured.
In this case, only the first compliance framework applied to a project has its compliance pipeline included in the project pipeline.
To ensure that the correct compliance pipeline is included in a project:
1. Remove all compliance frameworks from the project.
1. Apply the compliance framework with the correct compliance pipeline to the project.
1. Apply additional compliance frameworks to the project.
## Configure a compliance pipeline
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383209) in GitLab 15.11, compliance frameworks moved to compliance center.
{{< /history >}}
To configure a compliance pipeline:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure** > **Compliance Center**.
1. Select **Frameworks** section.
1. Select **New framework** section, add information of compliance framework including path to the compliance framework configuration. Use the
`path/file.y[a]ml@group-name/project-name` format. For example:
- `.compliance-ci.yml@gitlab-org/gitlab`.
- `.compliance-ci.yaml@gitlab-org/gitlab`.
This configuration is inherited by projects where the compliance framework label is
[applied](../project/working_with_projects.md#add-a-compliance-framework-to-a-project). In projects with the applied compliance
framework label, the compliance pipeline configuration is run instead of the labeled project's own pipeline configuration.
The user running the pipeline in the labeled project must at least have the Reporter role on the compliance project.
When used to enforce scan execution, this feature has some overlap with
[scan execution policies](../application_security/policies/scan_execution_policies.md). We have not
[unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312). For details on
the similarities and differences between these features, see [Enforce scan execution](../application_security/_index.md#enforce-scan-execution).
### Example configuration
The following example `.compliance-gitlab-ci.yml` includes the `include` keyword to ensure labeled project pipeline
configuration is also executed.
```yaml
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA' # Must be defined or MR pipelines always use the use default branch
rules:
- if: $CI_PROJECT_PATH != "my-group/project-1" # Must run on projects other than the one hosting this configuration.
# Allows compliance team to control the ordering and interweaving of stages/jobs.
# Stages without jobs defined will remain hidden.
stages:
- pre-compliance
- build
- test
- pre-deploy-compliance
- deploy
- post-compliance
variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
FOO: sast
sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml
variables:
FOO: sast
image: ruby:2.6
stage: pre-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
sanity check:
image: ruby:2.6
stage: pre-deploy-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
audit trail:
image: ruby:2.7
stage: post-compliance
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always # or when: on_success
allow_failure: false
before_script:
- "# No before scripts."
script:
- echo "running $FOO"
after_script:
- "# No after scripts."
```
The `rules` configuration in the `include` definition avoids circular inclusion in case the compliance pipeline must be able to run in the host project itself.
You can leave it out if your compliance pipeline only ever runs in labeled projects.
#### Compliance pipelines and custom pipeline configuration hosted externally
The example above assumes that all projects host their pipeline configuration in the same project.
If any projects use [configuration hosted externally](../../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file),
the example configuration does not work. See [issue 393960](https://gitlab.com/gitlab-org/gitlab/-/issues/393960)
for more details.
With projects that use externally hosted configuration, you can try the this workaround:
- The `include` section in the example compliance pipeline configuration must be adjusted.
For example, using [`include:rules`](../../ci/yaml/includes.md#use-rules-with-include):
```yaml
include:
# If the custom path variables are defined, include the project's external config file.
- project: '$PROTECTED_PIPELINE_CI_PROJECT_PATH'
file: '$PROTECTED_PIPELINE_CI_CONFIG_PATH'
ref: '$PROTECTED_PIPELINE_CI_REF'
rules:
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH && $PROTECTED_PIPELINE_CI_CONFIG_PATH && $PROTECTED_PIPELINE_CI_REF
# If any custom path variable is not defined, include the project's internal config file as normal.
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
rules:
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH == null || $PROTECTED_PIPELINE_CI_CONFIG_PATH == null || $PROTECTED_PIPELINE_CI_REF == null
```
- [CI/CD variables](../../ci/variables/_index.md) must be added to projects with external
pipeline configuration. In this example:
- `PROTECTED_PIPELINE_CI_PROJECT_PATH`: The path to the project hosting the configuration file, for example `group/subgroup/project`.
- `PROTECTED_PIPELINE_CI_CONFIG_PATH`: The path to the configuration file in the project, for example `path/to/.gitlab-ci.yml`.
- `PROTECTED_PIPELINE_CI_REF`: The ref to use when retrieving the configuration file, for example `main`.
#### Compliance pipelines in merge requests originating in project forks
When a merge request originates in a fork, the branch to be merged usually only exists in the fork.
When creating such a merge request against a project with compliance pipelines, the above snippet fails with a
`Project <project-name> reference <branch-name> does not exist!` error message.
This error occurs because in the context of the target project, `$CI_COMMIT_REF_NAME` evaluates to a non-existing
branch name.
To get the correct context, use `$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` instead of `$CI_PROJECT_PATH`.
This variable is only available in
[merge request pipelines](../../ci/pipelines/merge_request_pipelines.md).
For example, for a configuration that supports both merge request pipelines originating in project forks and branch pipelines,
you need to [combine both `include` directives with `rules:if`](../../ci/yaml/includes.md#use-rules-with-include):
```yaml
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
- project: '$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME'
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME'
rules:
- if: $CI_PIPELINE_SOURCE != 'merge_request_event'
```
#### Compliance pipelines in projects with no configuration file
The [example configuration](#example-configuration) above assumes that all projects contain
a pipeline configuration file (`.gitlab-ci.yml` by default). However, in projects
with no configuration file (and therefore no pipelines by default), the compliance pipeline
fails because the file specified in `include:project` is required.
To only include a configuration file if it exists in a target project, use
[`rules:exists:project`](../../ci/yaml/_index.md#rulesexistsproject):
```yaml
include: # Execute individual project's configuration
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
rules:
- exists:
paths:
- '$CI_CONFIG_PATH'
project: '$CI_PROJECT_PATH'
ref: '$CI_COMMIT_SHA'
```
In this example, a configuration file is only included if it exists for the given `ref`
in the project in `exists:project: $CI_PROJECT_PATH'`.
If `exists:project` is not specified in the compliance pipeline configuration, it searches for files in the project
in which the `include` is defined. In compliance pipelines, the `include` from the example above
is defined in the project hosting the compliance pipeline configuration file, not the project
running the pipeline.
## Ensure compliance jobs are always run
Compliance pipelines [use GitLab CI/CD](../../ci/_index.md) to give you an incredible amount of flexibility
for defining any sort of compliance jobs you like. Depending on your goals, these jobs
can be configured to be:
- Modified by users.
- Non-modifiable.
Generally, if a value in a compliance job:
- Is set, it cannot be changed or overridden by project-level configurations.
- Is not set, a project-level configuration may be set.
Either might be wanted or not depending on your use case.
The following are a few best practices for ensuring that these jobs are always run exactly
as you define them and that downstream, project-level pipeline configurations
cannot change them:
- Add [a `rules:when:always` block](../../ci/yaml/_index.md#when) to each of your compliance jobs. This ensures they are
non-modifiable and are always run.
- Explicitly set any [variables](../../ci/yaml/_index.md#variables) the job references. This:
- Ensures that project-level pipeline configurations do not set them and alter their
behavior. For example, see `before_script` and `after_script` configuration in the [example configuration](#example-configuration).
- Includes any jobs that drive the logic of your job.
- Explicitly set the [container image](../../ci/yaml/_index.md#image) to run the job in. This ensures that your script
steps execute in the correct environment.
- Explicitly set any relevant GitLab pre-defined [job keywords](../../ci/yaml/_index.md#job-keywords).
This ensures that your job uses the settings you intend and that they are not overridden by
project-level pipelines.
## Troubleshooting
### Compliance jobs are overwritten by target repository
If you use the `extends` statement in a compliance pipeline configuration, compliance jobs are overwritten by the target repository job. For example,
you could have the following `.compliance-gitlab-ci.yml` configuration:
```yaml
"compliance job":
extends:
- .compliance_template
stage: build
.compliance_template:
script:
- echo "take compliance action"
```
You could also have the following `.gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: test
script:
- echo "overwriting compliance action"
```
This configuration results in the target repository pipeline overwriting the compliance pipeline, and you get the following message:
`overwriting compliance action`.
To avoid overwriting a compliance job, don't use the `extends` keyword in compliance pipeline configuration. For example,
you could have the following `.compliance-gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: build
script:
- echo "take compliance action"
```
You could also have the following `.gitlab-ci.yml` configuration:
```yaml
"compliance job":
stage: test
script:
- echo "overwriting compliance action"
```
This configuration doesn't overwrite the compliance pipeline and you get the following message:
`take compliance action`.
### Prefilled variables are not shown
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857),
compliance pipelines in GitLab 15.3 and later can prevent
[prefilled variables](../../ci/pipelines/_index.md#prefill-variables-in-manual-pipelines)
from appearing when manually starting a pipeline.
To workaround this issue, use `ref: '$CI_COMMIT_SHA'` instead of `ref: '$CI_COMMIT_REF_NAME'`
in the `include:` statement that executes the individual project's configuration.
The [example configuration](#example-configuration) has been updated with this change:
```yaml
include:
- project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_SHA'
```
### Error: `Job names must be unique`
To configure a compliance pipeline, the [example configuration](#example-configuration) recommends including the
individual project configuration with `include.project`.
The configuration can lead to an error when running the projects pipeline: `Pipeline execution policy error: Job names must be unique`.
This error occurs because the pipeline execution policy includes the project's `.gitlab-ci.yml` and tries to insert the
jobs when the jobs have already been declared in the pipeline.
To resolve this error, remove `include.project` from the separate YAML file linked in the pipeline execution policy.
<!--- end_remove -->
<!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
<!-- 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 (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/development/documentation/redirects -->

View File

@ -469,8 +469,8 @@ Group permissions for [compliance](compliance/_index.md) features including comp
| View [audit events](compliance/audit_events.md) | | | | ✓ | ✓ | ✓ | Users can view only events based on their individual actions. For more details, see the [prerequisites](compliance/audit_events.md#prerequisites). |
| View licenses in the [dependency list](application_security/dependency_list/_index.md) | | | | ✓ | ✓ | ✓ | |
| View the [compliance center](compliance/compliance_center/_index.md) | | | | | | ✓ | |
| Manage [compliance frameworks](group/compliance_frameworks.md) | | | | | | ✓ | |
| Assign [compliance frameworks](group/compliance_frameworks.md) to projects | | | | | | ✓ | |
| Manage [compliance frameworks](compliance/compliance_frameworks.md) | | | | | | ✓ | |
| Assign [compliance frameworks](compliance/compliance_frameworks.md) to projects | | | | | | ✓ | |
| Manage [audit streams](compliance/audit_event_streaming.md) | | | | | | ✓ | |
### GitLab Duo group permissions

View File

@ -597,7 +597,7 @@ To leave a project:
{{< /details >}}
You can add compliance frameworks to projects in a group that has a [compliance framework](../group/compliance_frameworks.md).
You can add compliance frameworks to projects in a group that has a [compliance framework](../compliance/compliance_frameworks.md).
## Manage project access through LDAP groups

View File

@ -21,7 +21,7 @@ PATH
gitlab-http (0.1.0)
activesupport (~> 7)
concurrent-ruby (~> 1.2)
httparty (~> 0.21.0)
httparty (~> 0.21)
ipaddress (~> 0.8.3)
net-http (= 0.6.0)
railties (~> 7)
@ -62,6 +62,7 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
csv (3.3.2)
debug_inspector (1.2.0)
diff-lcs (1.5.0)
erubi (1.12.0)
@ -75,7 +76,8 @@ GEM
rubocop-rspec (~> 3.0.4)
rubocop-rspec_rails (~> 2.30.0)
hashdiff (1.0.1)
httparty (0.21.0)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.1)

View File

@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'activesupport', '~> 7'
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.2'
spec.add_runtime_dependency 'httparty', '~> 0.21.0'
spec.add_runtime_dependency 'httparty', '~> 0.21'
spec.add_runtime_dependency 'ipaddress', '~> 0.8.3'
spec.add_runtime_dependency "railties", "~> 7"
# See lib/net_http/connect_patch.rb

View File

@ -70,7 +70,8 @@ module API
'available only on Premium and Ultimate tiers.'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_jobs
route_setting :authorization, job_token_policies: :read_jobs,
allow_public_access_for_enabled_project_features: [:repository, :builds]
get ':id/jobs/artifacts/:ref_name/raw/*artifact_path',
urgency: :low,
format: false,

View File

@ -392,7 +392,8 @@ module API
optional :direct_download, default: false, type: Boolean, desc: 'Perform direct download from remote storage instead of proxying artifacts'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_jobs
route_setting :authorization, job_token_policies: :read_jobs,
allow_public_access_for_enabled_project_features: [:repository, :builds]
get '/:id/artifacts', feature_category: :job_artifacts do
authenticate_job_via_dependent_job!
authorize_job_token_policies!(current_job.project)

View File

@ -204,7 +204,8 @@ module API
requires :package_name, type: String, file_path: true, desc: 'The Composer package name', documentation: { example: 'my-composer-package' }
end
route_setting :authentication, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true, deploy_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'archives/*package_name', urgency: :default do
project = authorized_user_project(action: :read_package)
authorize_job_token_policies!(project)

View File

@ -59,7 +59,8 @@ module API
tags %w[conan_packages]
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get urgency: :low do
download_package_file(:recipe_file)
end

View File

@ -110,7 +110,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'packages/:conan_package_reference', urgency: :low do
authorize_read_package!(project)
@ -137,7 +138,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get urgency: :low do
authorize_read_package!(project)
@ -168,7 +170,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'packages/:conan_package_reference/digest', urgency: :low do
present_package_download_urls
@ -186,7 +189,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'digest', urgency: :low do
present_recipe_download_urls
@ -215,7 +219,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'packages/:conan_package_reference/download_urls', urgency: :low do
present_package_download_urls
@ -233,7 +238,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'download_urls', urgency: :low do
present_recipe_download_urls
@ -263,7 +269,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
post 'packages/:conan_package_reference/upload_urls', urgency: :low do
authorize_read_package!(project)
@ -284,7 +291,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
post 'upload_urls', urgency: :low do
authorize_read_package!(project)
@ -358,7 +366,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get urgency: :low do
download_package_file(:recipe_file)
@ -430,7 +439,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get urgency: :low do
download_package_file(:package_file)

View File

@ -79,7 +79,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
authenticate_non_public: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'dist-tags', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = params[:package_name]
@ -194,7 +195,8 @@ module API
tags %w[npm_packages]
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
post '-/npm/v1/security/advisories/bulk' do
redirect_or_present_audit_report
end
@ -214,7 +216,8 @@ module API
tags %w[npm_packages]
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
post '-/npm/v1/security/audits/quick' do
redirect_or_present_audit_report
end

View File

@ -59,7 +59,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
authenticate_non_public: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = declared_params[:package_name]
packages =

View File

@ -69,7 +69,8 @@ module API
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_deployments
route_setting :authorization, job_token_policies: :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
get ':id/deployments' do
authorize! :read_deployment, user_project
@ -95,7 +96,8 @@ module API
requires :deployment_id, type: Integer, desc: 'The ID of the deployment'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_deployments
route_setting :authorization, job_token_policies: :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
get ':id/deployments/:deployment_id' do
authorize! :read_deployment, user_project
@ -251,7 +253,8 @@ module API
use :merge_requests_base_params
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_deployments
route_setting :authorization, job_token_policies: :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
get ':id/deployments/:deployment_id/merge_requests' do
authorize! :read_deployment, user_project

View File

@ -39,7 +39,8 @@ module API
mutually_exclusive :name, :search, message: 'cannot be used together'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_environments
route_setting :authorization, job_token_policies: :read_environments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
get ':id/environments' do
authorize! :read_environment, user_project
@ -271,7 +272,8 @@ module API
requires :environment_id, type: Integer, desc: 'The ID of the environment'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_environments
route_setting :authorization, job_token_policies: :read_environments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
get ':id/environments/:environment_id' do
authorize! :read_environment, user_project

View File

@ -128,7 +128,8 @@ module API
end
route_setting :authentication, job_token_allowed: %i[request basic_auth], basic_auth_personal_access_token: true, deploy_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get do
project = authorized_user_project(action: :read_package)

View File

@ -69,7 +69,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true,
authenticate_non_public: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do
authorize_read_package!(project)

View File

@ -1038,6 +1038,7 @@ module API
return true unless current_user&.from_ci_job_token?
return true unless Feature.enabled?(:add_policies_to_ci_job_token, project)
return true if skip_job_token_policies?
return true if publicly_accessible_feature?(project)
current_user.ci_job_token_scope.policies_allowed?(project, job_token_policies)
end
@ -1069,6 +1070,19 @@ module API
route_setting(:authorization).try(:fetch, :skip_job_token_policies, false)
end
def publicly_accessible_feature?(project)
return false unless respond_to?(:route_setting)
return false unless project.public? || project.internal?
return false unless project&.project_feature
project_features = Array(route_setting(:authorization).try(:fetch, :allow_public_access_for_enabled_project_features, nil))
return false if project_features.empty?
project_features.all? do |project_feature|
project.project_feature.access_level(project_feature) >= ProjectFeature::ENABLED
end
end
end
end

View File

@ -102,7 +102,8 @@ module API
use :path_and_file_name
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
# return a similar failure to authorize_read_package!(project)
@ -158,7 +159,8 @@ module API
use :path_and_file_name
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/-/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
# return a similar failure to group = find_group(params[:id])
group = find_authorized_group!(action: :read_package_within_public_registries)
@ -200,7 +202,8 @@ module API
use :path_and_file_name
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
project = authorized_user_project(action: :read_package)

View File

@ -61,7 +61,8 @@ module API
requires :file_name, type: String, desc: 'Package file name'
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get '*package_name/-/*file_name', format: false do
authorize_read_package!(project)
@ -141,7 +142,8 @@ module API
end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
authenticate_non_public: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = declared_params[:package_name]
packages = ::Packages::Npm::PackageFinder.new(project: project_or_nil, params: { package_name: package_name }).execute

View File

@ -31,7 +31,8 @@ module API
use :pagination
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/packages/:package_id/package_files' do
package = ::Packages::PackageFinder
.new(user_project, params[:package_id]).execute

View File

@ -54,7 +54,8 @@ module API
desc: 'Return packages with specified status'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/packages' do
packages = ::Packages::PackagesFinder.new(
user_project,
@ -77,7 +78,8 @@ module API
requires :package_id, type: Integer, desc: 'The ID of a package'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/packages/:package_id' do
render_api_error!('Package not found', 404) unless package.detailed_info?
@ -104,7 +106,8 @@ module API
values: 1..20
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get ':id/packages/:package_id/pipelines' do
not_found!('Package not found') unless package.detailed_info?

View File

@ -131,7 +131,8 @@ module API
end
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'files/:sha256/*file_identifier' do
group = find_authorized_group!
authorize_read_package!(group)
@ -212,7 +213,8 @@ module API
end
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'files/:sha256/*file_identifier' do
project = project!
authorize_job_token_policies!(project)
@ -240,7 +242,8 @@ module API
# An API entry point but returns an HTML file instead of JSON.
# PyPi simple API returns a list of packages as a simple HTML file.
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'simple', format: :txt do
project = project!
authorize_job_token_policies!(project)
@ -265,7 +268,8 @@ module API
# An API entry point but returns an HTML file instead of JSON.
# PyPi simple API returns the package descriptor as a simple HTML file.
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
route_setting :authorization, job_token_policies: :read_packages
route_setting :authorization, job_token_policies: :read_packages,
allow_public_access_for_enabled_project_features: :package_registry
get 'simple/*package_name', format: :txt do
project = project!
authorize_job_token_policies!(project)

View File

@ -38,7 +38,8 @@ module API
use :pagination
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: :releases
get 'links' do
authorize! :read_release, release
@ -95,7 +96,8 @@ module API
tags release_links_tags
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: :releases
get do
authorize! :read_release, release

View File

@ -98,7 +98,8 @@ module API
optional :updated_after, type: DateTime, desc: 'Return releases updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases]
get ':id/releases' do
releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort, :updated_before, :updated_after)).execute
@ -134,7 +135,8 @@ module API
desc: 'If `true`, a response includes HTML rendered markdown of the release description'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases]
get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
authorize_read_code!
@ -162,7 +164,8 @@ module API
as: :filepath
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases]
get ':id/releases/:tag_name/downloads/*direct_asset_path', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
authorize_read_code!
@ -191,7 +194,8 @@ module API
desc: 'The path to be suffixed to the latest release'
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases]
get ':id/releases/permalink/latest(/)(*suffix_path)', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
authorize_read_code!

View File

@ -293,7 +293,8 @@ module API
desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'"
end
route_setting :authentication, job_token_allowed: true
route_setting :authorization, job_token_policies: :read_releases
route_setting :authorization, job_token_policies: :read_releases,
allow_public_access_for_enabled_project_features: :repository
get ':id/repository/changelog' do
check_rate_limit!(:project_repositories_changelog, scope: [current_user, user_project]) do
render_api_error!({ error: 'This changelog has been requested too many times. Try again later.' }, 429)

View File

@ -63,7 +63,7 @@
"@gitlab/fonts": "^1.3.0",
"@gitlab/query-language-rust": "0.4.0",
"@gitlab/svgs": "3.123.0",
"@gitlab/ui": "108.3.1",
"@gitlab/ui": "108.4.1",
"@gitlab/vue-router-vue3": "npm:vue-router@4.5.0",
"@gitlab/vuex-vue3": "npm:vuex@4.1.0",
"@gitlab/web-ide": "^0.0.1-dev-20250211142744",

View File

@ -40,6 +40,7 @@ describe('PasswordInput', () => {
expect(passwordInput.attributes('data-testid')).toBe(propsData.testid);
expect(passwordInput.attributes('title')).toBe(propsData.title);
expect(passwordInput.attributes('required')).toBe('true');
expect(passwordInput.attributes('disabled')).toBeUndefined();
});
describe('when password input is not required', () => {
@ -73,4 +74,13 @@ describe('PasswordInput', () => {
});
});
});
describe('when password input is disabled', () => {
it('disables the input field and the toggle button', () => {
wrapper = createComponent({ disabled: true });
expect(findPasswordInput().attributes('disabled')).toBeDefined();
expect(findToggleButton().attributes('disabled')).toBeDefined();
});
});
});

View File

@ -334,6 +334,16 @@ RSpec.describe API::Helpers, feature_category: :shared do
it { is_expected.to eq project }
end
context 'when the project feature is publicly accessible' do
let_it_be(:project) { create(:project, :public, :builds_enabled) }
before do
allow(helper).to receive(:route_setting).with(:authorization).and_return(allow_public_access_for_enabled_project_features: :builds)
end
it { is_expected.to eq project }
end
end
context 'when no policy is given' do

View File

@ -5112,79 +5112,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def
build.clear_memoization(:build_data)
end
context 'when ci_async_build_hooks_execution flag is disabled' do
before do
stub_feature_flags(ci_async_build_hooks_execution: false)
end
context 'with project services' do
before do
create(:integration, active: true, job_events: true, project: project)
end
it 'executes services' do
allow_next_instance_of(Integration) do |integration|
expect(integration).to receive(:async_execute)
end
build.execute_hooks
end
end
context 'without relevant project services' do
before do
create(:integration, active: true, job_events: false, project: project)
end
it 'does not execute services' do
allow_next_instance_of(Integration) do |integration|
expect(integration).not_to receive(:async_execute)
end
build.execute_hooks
end
end
context 'with project hooks' do
let(:build_data) { double(:BuildData, dup: double(:DupedData)) }
before do
create(:project_hook, project: project, job_events: true)
end
it 'executes hooks' do
expect(::Gitlab::DataBuilder::Build)
.to receive(:build).with(build).and_return(build_data)
expect(build.project)
.to receive(:execute_hooks).with(build_data.dup, :job_hooks)
build.execute_hooks
end
context 'with blocked users' do
before do
allow(build).to receive(:user) { FactoryBot.build(:user, :blocked) }
end
it 'does not execute hooks' do
expect(build.project).not_to receive(:execute_hooks)
build.execute_hooks
end
end
end
context 'without project hooks' do
it 'does not execute hooks' do
expect(build.project).not_to receive(:execute_hooks)
build.execute_hooks
end
end
end
context 'when ci_async_build_hooks_execution flag is enabled' do
context 'when project hooks exists' do
let(:build_data) { double(:BuildData) }
before do

View File

@ -35,6 +35,12 @@ RSpec.describe Integrations::Campfire, feature_category: :integrations do
end
end
describe '.help' do
it 'links to the help page correctly' do
expect(described_class.help).to include('help/api/integrations.md#campfire', 'Learn More')
end
end
describe "#execute" do
let(:user) { build_stubbed(:user) }
let(:project) { build_stubbed(:project, :repository) }

View File

@ -152,11 +152,10 @@ RSpec.describe Integrations::Datadog, feature_category: :integrations do
end
end
describe '#help' do
subject { instance.help }
it { is_expected.to be_a(String) }
it { is_expected.not_to be_empty }
describe '.help' do
it 'links to the help page correctly' do
expect(described_class.help).to include('help/integration/datadog.md', 'How do I set up this integration?')
end
end
describe 'upgrade from previous version' do

View File

@ -506,10 +506,7 @@ RSpec.describe API::Ci::JobArtifacts, feature_category: :job_artifacts do
it_behaves_like 'enforcing job token policies', :read_jobs do
before do
stub_licensed_features(cross_project_pipelines: true)
end
around do |example|
Sidekiq::Testing.inline! { example.run }
pipeline.update!(status: :success)
end
let(:request) do
@ -701,6 +698,19 @@ RSpec.describe API::Ci::JobArtifacts, feature_category: :job_artifacts do
expect(response.headers.to_h)
.not_to include('Gitlab-Workhorse-Send-Data' => /artifacts-entry/)
end
it_behaves_like 'enforcing job token policies', :read_jobs,
allow_public_access_for_enabled_project_features: [:repository, :builds] do
before do
stub_licensed_features(cross_project_pipelines: true)
pipeline.update!(status: :success)
end
let(:request) do
get api("/projects/#{source_project.id}/jobs/artifacts/#{pipeline.ref}/raw/#{artifact}"),
params: { job: job.name, job_token: target_job.token }
end
end
end
end

View File

@ -1082,7 +1082,8 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state, feature_catego
expect(response).to have_gitlab_http_status(:forbidden)
end
it_behaves_like 'enforcing job token policies', :read_jobs do
it_behaves_like 'enforcing job token policies', :read_jobs,
allow_public_access_for_enabled_project_features: [:repository, :builds] do
let(:token) { target_job.token }
let(:request) { download_artifact }
end

View File

@ -595,7 +595,8 @@ RSpec.describe API::ComposerPackages, feature_category: :package_registry do
let(:branch) { project.repository.find_branch('master') }
let(:sha) { branch.target }
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
before_all do
project.add_developer(user)
end

View File

@ -43,6 +43,11 @@ RSpec.describe API::Conan::V2::ProjectPackages, feature_category: :package_regis
it_behaves_like 'accept get request on private project with access to package registry for everyone'
it_behaves_like 'project not found by project id'
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:headers) { job_basic_auth_header(target_job) }
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(conan_package_revisions_support: false)

View File

@ -23,7 +23,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
get api("/projects/#{project.id}/deployments", user), params: params
end
it_behaves_like 'enforcing job token policies', :read_deployments do
it_behaves_like 'enforcing job token policies', :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
let(:request) do
get api("/projects/#{source_project.id}/deployments"), params: { job_token: target_job.token }
end
@ -174,7 +175,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
shared_examples "returns project deployments" do
let(:project) { deployment.environment.project }
it_behaves_like 'enforcing job token policies', :read_deployments do
it_behaves_like 'enforcing job token policies', :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
let(:request) do
get api("/projects/#{source_project.id}/deployments/#{deployment.id}"),
params: { job_token: target_job.token }
@ -670,7 +672,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
subject { get api("/projects/#{project.id}/deployments/#{deployment.id}/merge_requests", user) }
it_behaves_like 'enforcing job token policies', :read_deployments do
it_behaves_like 'enforcing job token policies', :read_deployments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
let(:request) do
get api("/projects/#{source_project.id}/deployments/#{deployment.id}/merge_requests"), params: { job_token: target_job.token }
end

View File

@ -124,7 +124,8 @@ RSpec.describe API::Environments, feature_category: :continuous_delivery do
end
end
it_behaves_like 'enforcing job token policies', :read_environments do
it_behaves_like 'enforcing job token policies', :read_environments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
let(:request) do
get api("/projects/#{source_project.id}/environments"), params: { job_token: target_job.token }
end
@ -646,7 +647,8 @@ RSpec.describe API::Environments, feature_category: :continuous_delivery do
let_it_be(:bridge_job) { create(:ci_bridge, :running, project: project, user: user) }
let_it_be(:build_job) { create(:ci_build, :running, project: project, user: user) }
it_behaves_like 'enforcing job token policies', :read_environments do
it_behaves_like 'enforcing job token policies', :read_environments,
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
let(:request) do
get api("/projects/#{source_project.id}/environments/#{environment.id}"),
params: { job_token: target_job.token }

View File

@ -691,7 +691,8 @@ RSpec.describe API::GenericPackages, feature_category: :package_registry do
let_it_be(:package) { create(:generic_package, project: project) }
let_it_be(:package_file) { create(:package_file, :generic, package: package) }
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
before do
source_project.add_developer(user)
end

View File

@ -190,7 +190,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
it_behaves_like 'a missing module version list resource'
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:module_name) { base }
let(:resource) { 'list' }
let(:request) { get_resource(job_token: target_job.token) }
@ -250,7 +251,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:module_name) { base }
let(:resource) { 'v1.0.1.info' }
let(:request) { get_resource(job_token: target_job.token) }
@ -278,7 +280,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
it_behaves_like 'a missing module file resource', 'v1.0.1', path: '/mod'
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:module_name) { base }
let(:resource) { 'v1.0.1.mod' }
let(:request) { get_resource(job_token: target_job.token) }
@ -306,7 +309,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
it_behaves_like 'a module archive resource', 'v2.0.0', ['go.mod', 'a.go', 'x.go'], path: '/v2'
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:module_name) { base }
let(:resource) { 'v1.0.1.zip' }
let(:request) { get_resource(job_token: target_job.token) }

View File

@ -475,7 +475,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
before_all do
project.add_maintainer(user)
end
@ -649,7 +650,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:request) do
download_file(file_name: package_file.file_name, params: { job_token: target_job.token })
end
@ -842,7 +844,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
subject { download_file_with_token(file_name: package_file.file_name) }
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:request) do
download_file(file_name: package_file.file_name, params: { job_token: target_job.token })
end

View File

@ -203,7 +203,8 @@ RSpec.describe API::NpmProjectPackages, feature_category: :package_registry do
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:headers) { build_token_auth_header(target_job.token) }
end

View File

@ -23,7 +23,8 @@ RSpec.describe API::PackageFiles, feature_category: :package_registry do
project.add_developer(user)
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:request) { get api(url), params: { job_token: target_job.token } }
end

View File

@ -22,7 +22,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
subject(:request) { get api(url), params: params }
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:params) { { job_token: target_job.token } }
end
@ -231,7 +232,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
subject { get api(package_url, user) }
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:request) { get api(package_url), params: { job_token: target_job.token } }
end
@ -421,7 +423,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:request) { get api(package_pipelines_url), params: { job_token: target_job.token } }
end

View File

@ -25,7 +25,8 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
end
describe 'GET /projects/:id/releases/:tag_name/assets/links' do
it_behaves_like 'enforcing job token policies', :read_releases do
it_behaves_like 'enforcing job token policies', :read_releases,
allow_public_access_for_enabled_project_features: :releases do
let_it_be(:user) { maintainer }
let(:request) do
get api("/projects/#{source_project.id}/releases/v0.1/assets/links"),
@ -114,7 +115,8 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
describe 'GET /projects/:id/releases/:tag_name/assets/links/:link_id' do
let!(:release_link) { create(:release_link, release: release) }
it_behaves_like 'enforcing job token policies', :read_releases do
it_behaves_like 'enforcing job token policies', :read_releases,
allow_public_access_for_enabled_project_features: :releases do
let_it_be(:user) { maintainer }
let(:request) do
get api("/projects/#{source_project.id}/releases/v0.1/assets/links/#{release_link.id}"),

View File

@ -19,7 +19,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
end
describe 'GET /projects/:id/releases', :use_clean_rails_redis_caching do
it_behaves_like 'enforcing job token policies', :read_releases do
it_behaves_like 'enforcing job token policies', :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases] do
let(:user) { developer }
let(:request) do
get api("/projects/#{source_project.id}/releases"), params: { job_token: target_job.token }
@ -326,7 +327,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
)
end
it_behaves_like 'enforcing job token policies', :read_releases do
it_behaves_like 'enforcing job token policies', :read_releases,
allow_public_access_for_enabled_project_features: [:repository, :releases] do
let(:user) { developer }
let(:request) do
get api("/projects/#{source_project.id}/releases/v0.1"), params: { job_token: target_job.token }
@ -595,7 +597,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
context 'with a valid release tag' do
context 'when filepath is provided' do
context 'when filepath exists' do
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect do
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect,
allow_public_access_for_enabled_project_features: [:repository, :releases] do
let(:user) { developer }
let(:request) do
get api("/projects/#{source_project.id}/releases/v0.1/downloads#{filepath}"),
@ -731,7 +734,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
)
end
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect do
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect,
allow_public_access_for_enabled_project_features: [:repository, :releases] do
let(:user) { developer }
let(:request) do
get api("/projects/#{source_project.id}/releases/permalink/latest"), params: { job_token: target_job.token }

View File

@ -855,7 +855,8 @@ RSpec.describe API::Repositories, feature_category: :source_code_management do
end
describe 'GET /projects/:id/repository/changelog' do
it_behaves_like 'enforcing job token policies', :read_releases do
it_behaves_like 'enforcing job token policies', :read_releases,
allow_public_access_for_enabled_project_features: :repository do
before do
allow(Repositories::ChangelogService).to receive(:new)
.and_return(instance_spy(Repositories::ChangelogService))

View File

@ -1,13 +1,23 @@
# frozen_string_literal: true
RSpec.shared_examples 'enforcing job token policies' do |policies, expected_success_status: :success|
RSpec.shared_examples 'enforcing job token policies' do |policies, expected_success_status: :success,
allow_public_access_for_enabled_project_features: nil|
context 'when authenticating with a CI job token from another project' do
let(:source_project) { project }
let(:target_job) { create(:ci_build, :running, user: user) }
let(:job_user) { user }
let(:target_job) { create(:ci_build, :running, user: job_user) }
let(:allowed_policies) { Array(policies) }
let(:default_permissions) { false }
let!(:features_state) do
source_project.project_feature.attributes
.slice(*::ProjectFeature::FEATURES.map { |feature| "#{feature}_access_level" })
end
before do
# Make all project features private
enable_project_features(source_project, nil)
create(:ci_job_token_project_scope_link,
source_project: source_project,
target_project: target_job.project,
@ -17,6 +27,11 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
)
end
after do
# Reinstate the initial project features
source_project.project_feature.update!(features_state)
end
subject(:do_request) do
request
response
@ -58,5 +73,59 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
it { is_expected.to have_gitlab_http_status(expected_success_status) }
end
end
context 'when the source project is public and the target job user is not a member of the source project' do
let(:visibility_level) { source_project.visibility_level }
let(:job_user) { create(:user) }
before do
if visibility_level != ::Gitlab::VisibilityLevel::PUBLIC
source_project.update!(visibility_level: ::Gitlab::VisibilityLevel::PUBLIC)
end
end
after do
if visibility_level != ::Gitlab::VisibilityLevel::PUBLIC
source_project.update!(visibility_level: visibility_level)
end
end
context 'when policies are not allowed, but the specified project features allow public access',
if: allow_public_access_for_enabled_project_features.present? do
let(:allowed_policies) { [] }
context 'when all project features are private' do
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
context 'when the specified project features are public' do
before do
enable_project_features(source_project, allow_public_access_for_enabled_project_features)
end
it { is_expected.to have_gitlab_http_status(expected_success_status) }
end
end
context 'when policies are allowed and all project features are public',
unless: allow_public_access_for_enabled_project_features.present? do
before do
enable_project_features(source_project, ::ProjectFeature::FEATURES)
end
it 'denies access' do
expect(do_request).to have_gitlab_http_status(:forbidden)
.or have_gitlab_http_status(:unauthorized)
.or have_gitlab_http_status(:bad_request)
end
end
end
end
def enable_project_features(project, project_features)
attrs = ::ProjectFeature::FEATURES.index_with(::ProjectFeature::PRIVATE)
attrs.merge!(Array(project_features).index_with(::ProjectFeature::ENABLED)) if project_features.present?
attrs.transform_keys! { |feature| "#{feature}_access_level" }
project.project_feature.update!(attrs)
end
end

View File

@ -40,6 +40,15 @@ RSpec.shared_examples Integrations::Base::Discord do
end
end
describe '.help' do
it 'links to help page correctly' do
expect(described_class.help).to include(
'user/project/integrations/discord_notifications.md',
'How do I set up this integration?'
)
end
end
describe '#execute' do
include StubRequests

View File

@ -16,6 +16,15 @@ RSpec.shared_examples Integrations::Base::HangoutsChat do
let(:webhook_url_regex) { /\A#{webhook_url}.*/ }
let(:query_params) { { messageReplyOption: Integrations::HangoutsChat::REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD } }
describe '.help' do
it 'links to help page correctly' do
expect(described_class.help).to include(
'user/project/integrations/hangouts_chat.md',
'How do I set up a Google Chat webhook?'
)
end
end
describe "#execute" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, :wiki_repo) }

View File

@ -23,6 +23,15 @@ RSpec.shared_examples Integrations::Base::Irker do
end
end
describe '.help' do
it 'links to help page correctly' do
expect(described_class.help).to include(
'help/user/project/integrations/irker.md#set-up-an-irker-daemon',
'Learn More'
)
end
end
describe 'Execute' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }

View File

@ -131,7 +131,8 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:headers) { build_token_auth_header(target_job.token) }
end
@ -346,7 +347,8 @@ RSpec.shared_examples 'handling audit request' do |path:, scope: :project|
it_behaves_like 'accept audit request', status: :ok
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: scope == :project ? :package_registry : nil do
before_all do
project.add_reporter(user)
end
@ -491,7 +493,8 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
end
end
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:headers) { build_token_auth_header(target_job.token) }
end

View File

@ -101,7 +101,8 @@ RSpec.shared_examples 'job token for package GET requests' do
end
RSpec.shared_examples 'enforcing read_packages job token policy' do
it_behaves_like 'enforcing job token policies', :read_packages do
it_behaves_like 'enforcing job token policies', :read_packages,
allow_public_access_for_enabled_project_features: :package_registry do
let(:headers) { job_basic_auth_header(target_job) }
end
end

View File

@ -24,6 +24,73 @@ RSpec.describe Ci::ExecuteBuildHooksWorker, feature_category: :pipeline_composit
describe '#perform' do
subject(:perform) { described_class.new.perform(project.id, build_data) }
context 'when build_data has string keys' do
let(:string_build_data) do
{
'object_kind' => 'build',
'ref' => 'main',
'build_id' => build.id,
'build_name' => build.name,
'build_stage' => build.stage_name,
'build_status' => build.status,
'project_id' => project.id,
'project_name' => project.full_name
}
end
it 'converts data to indifferent access' do
allow_next_instance_of(Project) do |project|
expect(project).to receive(:execute_hooks).with(
kind_of(ActiveSupport::HashWithIndifferentAccess),
:job_hooks
)
end
described_class.new.perform(project.id, string_build_data)
end
it 'allows both string and symbol access to build data' do
allow_next_instance_of(Project) do |project|
allow(project).to receive(:has_active_hooks?).and_return(true)
expect(project).to receive(:execute_hooks) do |data, _hook_type|
expect(data[:object_kind]).to eq('build')
expect(data['object_kind']).to eq('build')
expect(data[:build_name]).to eq(build.name)
expect(data['build_name']).to eq(build.name)
end
end
described_class.new.perform(project.id, string_build_data)
end
end
context 'when build_data has symbol keys' do
it 'converts data to indifferent access' do
allow_next_instance_of(Project) do |project|
expect(project).to receive(:execute_hooks).with(
kind_of(ActiveSupport::HashWithIndifferentAccess),
:job_hooks
)
end
perform
end
it 'allows both string and symbol access to build data' do
allow_next_instance_of(Project) do |project|
allow(project).to receive(:has_active_hooks?).and_return(true)
expect(project).to receive(:execute_hooks) do |data, _hook_type|
expect(data[:object_kind]).to eq('build')
expect(data['object_kind']).to eq('build')
expect(data[:build_name]).to eq(build.name)
expect(data['build_name']).to eq(build.name)
end
end
perform
end
end
context 'when project exists' do
context 'with project services' do
let!(:integration) { create(:integration, active: true, job_events: true, project: project) }

View File

@ -1436,10 +1436,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.123.0.tgz#1fa3b1a709755ff7c8ef67e18c0442101655ebf0"
integrity sha512-yjVn+utOTIKk8d9JlvGo6EgJ4TQ+CKpe3RddflAqtsQqQuL/2MlVdtaUePybxYzWIaumFuh5LouQ6BrWyw1niQ==
"@gitlab/ui@108.3.1":
version "108.3.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-108.3.1.tgz#eb1db6c1ddc0ad7a239e6bcf21624fd1bc54b27b"
integrity sha512-O4haNCEJl3nHK8DB1mi01YRJOZomNXI0sBA600BLrbptm/NAO9oVE7O/U8sFEdXM7EtFHYwRYcF/LrWwfJmE9g==
"@gitlab/ui@108.4.1":
version "108.4.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-108.4.1.tgz#d45dbcc3a9f568694f53eebb795544157ddbf44f"
integrity sha512-o3mcR/AQ5tkKd3mMClMvsJIHhLWzU6n1L0m3bp4Yr4zaNtRG3c8gEGF7MR6pMhlnyb5r/FQk2wigxHaUuOSblQ==
dependencies:
"@floating-ui/dom" "1.4.3"
echarts "^5.3.2"