Allow group owners to define compliance pipeline configurations at the group level
## Summary This issue serves as an outline for improvements to be made to [required pipeline configuration](https://docs.gitlab.com/ee/user/admin_area/settings/continuous_integration.html#required-pipeline-configuration-premium-only) and extending the functionality to the group-level. This feature, and features like this intended for compliance use cases, should always begin with the smallest use case and apply only to projects labeled with [compliance frameworks](https://docs.gitlab.com/ee/user/project/settings/#compliance-framework-premium). Compliance features like this should also come with an override mechanism built in to enable any user to bypass these policies in emergencies or exceptions. <!-- The first three sections: "Problem to solve", "Intended users" and "Proposal", are strongly recommended, while the rest of the sections can be filled out during the problem validation or breakdown phase. However, keep in mind that providing complete and relevant information early helps our product team validate the problem and start working on a solution. --> ### Problem to solve <!-- What problem do we solve? Try to define the who/what/why of the opportunity as a user story. For example, "As a (who), I want (what), so I can (why/value)." --> Regulated customers create organizational policies to govern how they operate. These policies exist to manage risk for an organization and maintain compliance with a legal or regulatory framework. The policies must be able to translate into an application like GitLab to satisfy an organization's security and compliance teams' requirements. Within GitLab, this manifests most often within CI/CD pipelines. Currently, regulated customers focus primarily on the concept of **separation of duties** ("SOD"). SOD exists to ensure that multiple people (eyes) are involved in sensitive processes, such as shipping a change to production. They do not have a way to define the compliance requirements for their pipelines (scans, tests, or other jobs that are required to occur) at a global level and have those requirements be consumable and enforced by individual projects. This outcome is desirable specifically to **separate** the **duties** of the compliance and/or security team(s) and the **duties** of the development team(s). ### Intended users * [Sidney (Systems Administrator)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sidney-systems-administrator) * [Cameron (Compliance Manager)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#connor-compliance-manager) ### Further details <!-- Include use cases, benefits, goals, or any other details that will help us understand the problem better. --> An additional requirement here is to allow developers to _add_ to the compliance pipeline, but not modify or remove any components of that pipeline. Speaking with a variety of customers has highlighted the multitude of nuances for this specific pain point. These are the factors we should consider for iterations on this solution, however it manifests: * Information Security or Risk teams are driving the "hard-line" on requirements and there's no negotiation * Customers have stated they are more concerned with satisfying auditors than anyone else * Customers want `Developers` to have _some_ flexibility to extend a baseline compliance pipeline template * The templates should be easily consumable by `Developers` * Customers should be able to optionally enforce failing an MR if jobs identified as "required" fail * Customers are supportive of an "override" mechanism, provided specific approvers greenlight it and it's documented for evidence ### Proposal <!-- How are we going to solve the problem? Try to include the user journey! https://about.gitlab.com/handbook/journeys/#user-journey --> This is the proposed implementation plan for this epic. | Complete? | Issue | Why | UI | | ------ | ------ | ------ | --- | | ☑️ | [Support variables in include: section of gitlab-ci.yml (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/30686) | Currently, the `include:` statement does not support variables. Adding this support allows us to create an authoritative workflow when combining the `compliance.gitlab-ci.yml` and a project's local `.gitlab-ci.yml` | | ☑️ | [Add `$CI_PROJECT_CONFIG_PATH` as a predefined environment variable (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/246802) | Once the above is completed, we will need a new predefined variable, `$CI_PROJECT_CONFIG_PATH`, which tells the `compliance.gitlab-ci.yml` to include the `.gitlab-ci.yml` of a project it is being combined with. | | ☑️ | ~backend<br/><br/>[Add ability to create/read/update/delete compliance frameworks](https://gitlab.com/gitlab-org/gitlab/-/issues/255340) | We've [refactored](https://gitlab.com/gitlab-org/gitlab/-/issues/251113) [compliance project labels](https://docs.gitlab.com/ee/user/project/settings/#compliance-framework) to be customizable at the **group level**. This prevents `project maintainers` from modifying these labels, contributing to a better separation of duties posture for this setting. | ![Settings___General__New_label_](/uploads/b2ed1e04e11098ef9f9acccb1d9f2673/Settings___General__New_label_.png) | | ☑️ | ~frontend<br/><br/><ul><li>[Create shared color picker component (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287826)</li><li>[Create a shared compliance frameworks form app (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287827)</li><li>[Show available compliance frameworks (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287828)</li><li>[Create add compliance framework page (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287845)</li><li>[Create edit framework page (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287846)</li><li>[Add delete framework process (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/287847)</li><li>**Optional:** [Add pagination and proper badge counts to list view](https://gitlab.com/gitlab-org/gitlab/-/issues/292446)</li></ul> | We've [refactored](https://gitlab.com/gitlab-org/gitlab/-/issues/251113) [compliance project labels](https://docs.gitlab.com/ee/user/project/settings/#compliance-framework) to be customizable at the **group level**. This prevents `project maintainers` from modifying these labels, contributing to a better separation of duties posture for this setting. | ![Settings___General__New_label_](/uploads/b2ed1e04e11098ef9f9acccb1d9f2673/Settings___General__New_label_.png) | | ☑️ | ~backend<br/><br/>[Add 'compliance pipeline configuration location' value to custom compliance frameworks GraphQL endpoint (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/254389) | This field, part of custom compliance labels, allows a `group owner` to specify the specific location of a `compliance.gitlab-ci.yml@group/compliance-project` stored and managed in a dedicated project away from a developer's project. This field will be inherited by any `project` where the label is applied, forcing the project to use `compliance.gitlab-ci.yml` from `group/compliance-project` | ![Text](/uploads/3c524abdf310020739c94eb411e843cb/Text.png) | | ☑️ | ~frontend<br/><br/>[Add 'compliance pipeline configuration location' value to custom compliance frameworks form (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/292696) | This field, part of custom compliance labels, allows a `group owner` to specify the specific location of a `compliance.gitlab-ci.yml@group/compliance-project` stored and managed in a dedicated project away from a developer's project. This field will be inherited by any `project` where the label is applied, forcing the project to use `compliance.gitlab-ci.yml` from `group/compliance-project` | ![Text](/uploads/3c524abdf310020739c94eb411e843cb/Text.png) | | ☑️ | [Assign custom Compliance Framework Labels to projects (closed)](https://gitlab.com/gitlab-org/gitlab/-/issues/276221) | This gives `group owners` the ability to modify a project's `compliance label`, maintaining separation of duties between them and `project maintainers` to ensure the `compliance.gitlab-ci.yml` is always inherited and run in the project. | #### Walking through this proposal ```mermaid graph LR A(Namespace) --> B(Group A) subgraph Required Compliance Pipeline B --> B2[Compliance Project] --> B3[compliance.gitlab-ci.yml] B --> B4[Developer Project with *SOX* label] --> B5[.gitlab-ci.yml] B3 & B5 --> B6[combined .gitlab-ci.yml<br>during runtime] end A --> C(Group B) --> C2[Developer Project] --> C3[.gitlab-ci.yml] --> C4[.gitlab-ci.yml<br>during runtime] ``` * [Cameron (Compliance Manager)](https://about.gitlab.com/handbook/marketing/strategic-marketing/roles-personas/#cameron-compliance-manager) defines a central `compliance.gitlab-ci.yml` in `Group-A/Compliance-Project` * [Sasha (Developer)](https://about.gitlab.com/handbook/marketing/strategic-marketing/roles-personas/#sasha-software-developer) creates their local `.gitlab-ci.yml` in `Group-A/Developer-Project` * `Cameron`, in `Group-A` creates a [custom compliance framework](https://gitlab.com/gitlab-org/gitlab/-/issues/255340) - `SOX` - that defines a `Compliance pipeline configuration location` value: `compliance.gitlab-ci.yml@Group-A/Compliance-Project` * `Cameron` applies `SOX` to `Group-A/Developer-Project`, which inherits the value of `Compliance pipeline configuration location` * Members of `Group-A/Developer-Project` would see this new field in `Project` > `Settings` > `CI/CD` > `General pipelines` * `Group-A/Developer-Project` will now evaluate `compliance.gitlab-ci.yml` **first** * `compliance.gitlab-ci.yml` would use a configuration like this: ```yaml include: # include the - file: '$CI_PROJECT_CONFIG_PATH' # .gitlab-ci.yml of project: '$CI_PROJECT_PATH' # the project currently creating the pipeline ``` * `$CI_PROJECT_PATH` exists today, but would only work in the `include:` statement by implementing https://gitlab.com/gitlab-org/gitlab/-/issues/30686 * `$CI_PROJECT_CONFIG_PATH` does **not** exist today and would need to be added as a predefined environment variable for use in `include:` * When the local project executes a pipeline, it begins by evaluating `compliance.gitlab-ci.yml`, which will `include:` `Group-A/Developer-Project`s local `.gitlab-ci.yml` **Future Iterations/Considerations** 1. Currently, a developer's `.gitlab-ci.yml` could override attributes of a `compliance.gitlab-ci.yml` configuration if they aren't defined locally to the job. This would create a gap in this implementation 1. A future state would likely leverage Parent/Child pipelines #### Example yml files <details> **Example `compliance.gitlab-ci.yml`** *Managed by the compliance team in `Compliance Project A`* ``` include: - local: .gitlab-ci.yml stages: # Allows compliance team to control the ordering and interweaving of stages/jobs - pre-compliance - build - test - pre-deploy-compliance - deploy - post-compliance variables: # can be overriden by a developer's local .gitlab-ci.yml BLAH: sast sast: # none of these attributes can be overriden by a developer's local .gitlab-ci.yml variables: BLAH: sast stage: pre-compliance script: - echo "running $BLAH" sanity check: stage: pre-deploy-compliance script: - echo "running $BLAH" audit trail: stage: post-compliance script: - echo "running $BLAH" ``` **Example `.gitlab-ci.yml`** *Managed by the developers in `Developer Project B`* ``` build: stage: build script: - echo "building" test: stage: test script: - echo "testing" ``` </details> **Issues that compliment (non-blocking) this proposal** 1. Leverage [two-person approval](https://gitlab.com/gitlab-org/gitlab/-/issues/219386) precedent to provide an override mechanism 1. [Add a Reporter (Deployer) role](https://gitlab.com/gitlab-org/gitlab/-/issues/225482) 1. Alert the designated individuals (approval group(s) or specific role like admin, group owner, or [Reporter (Deployer)](https://gitlab.com/gitlab-org/gitlab/-/issues/201898)) about Parent pipeline failures 1. [Improve the navigation between parent-child pipelines ](https://gitlab.com/gitlab-org/gitlab/-/issues/229503) 1. [Parent-child pipelines relations UI](https://gitlab.com/gitlab-org/gitlab/-/issues/212421) 1. [Add a `compliance` tab](https://gitlab.com/gitlab-org/gitlab/-/issues/241992) (or similar) to pipeline view to provide insight and data about the upstream or holistic pipeline This proposal inherently reduces the scope of compliance pipeline configurations since the `include.gitlab-ci.yml` is created for each project. An additional aspect to this solution, which may be a separate issue/proposal, would be to improve [compliance framework project labels](https://docs.gitlab.com/ee/user/project/settings/#compliance-framework-premium) to work more directly with these compliance pipeline configurations. For example: * Create a new project (potentially using [project templates](https://gitlab.com/gitlab-org/gitlab/-/issues/202078)) * Configure the project to use the `HIPAA` compliance framework label * Optionally (in that same settings area) configure the project to use `hipaa-required.gitlab-ci.yml` (stored in external `Compliance Project A` * Make these settings editable only by `owners` and/or `admins` <details> <summary>Original Proposal</summary> * Consider an instance or group-level yaml template, similar to the proposal in https://gitlab.com/gitlab-org/gitlab/-/issues/32755, that can serve as a reference point for validating a pipeline configuration * Surface signals within the [Compliance Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/2537) about projects that run non-compliant pipelines * Leverage https://gitlab.com/gitlab-org/gitlab/issues/196115, combined with https://gitlab.com/gitlab-org/gitlab/-/issues/32755 and/or external services, to empower customers to decide if the MR meets their criteria and perform a check against the pipeline that ran, then provide GitLab a response that surfaces on the MR as an approval criterion. * e.g. Pipeline A should run without failures. If that's `true`, notify `Compliance Group` approvers. If that's `false`, the MR cannot be approved. We agreed that the solution proposed here could not be sufficiently relied upon since "a pipeline cannot check itself". In leveraging the compliance dashboard (and potentially @jmeshell's CI/CD dashboard), we can generate alerts (both in-app and via email or other mechanisms) and draw attention to non-compliant pipelines and MRs. Coupled with the flexibility of an API-enabled MR that polls external (compliance) systems, we can also block a merge that doesn't meet a company's policy. *This is a broad proposal intended to be broken up into multiple, smaller issues and stored in this to-be-promoted epic* Provide a group-level pipeline template repository to store compliance pipeline templates that can be consumed by `Developers` when creating new projects. The group-level template should be included in each project created but should allow the developer to extend its functionality (potentially using [custom ci config path](https://docs.gitlab.com/ee/ci/pipelines/settings.html#custom-ci-configuration-path)). The MR should surface a specific signal about the `compliance pipeline template` to enable approvers at the MR to provide a final :white_check_mark:. There should be an override mechanism built-in for scenarios where the change cannot afford to spend the time waiting on compliance checks that are baked into the compliance pipeline template. </details> ### Feature flag ~~Name: `group_level_compliance_pipeline`~~ Name: `ff_custom_compliance_frameworks` Disabled by default ### Permissions and Security <!-- What permissions are required to perform the described actions? Are they consistent with the existing permissions as documented for users, groups, and projects as appropriate? Is the proposed behavior consistent between the UI, API, and other access methods (e.g. email replies)?--> * `Group Owners` should be able to create this template repository. * Only members of the repository group should be able to modify the templates. ### Documentation <!-- See the Feature Change Documentation Workflow https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html * Add all known Documentation Requirements in this section. See https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html#documentation-requirements * If this feature requires changing permissions, update the permissions document. See https://docs.gitlab.com/ee/user/permissions.html --> ### Availability & Testing <!-- This section needs to be retained and filled in during the workflow planning breakdown phase of this feature proposal, if not earlier. What risks does this change pose to our availability? How might it affect the quality of the product? What additional test coverage or changes to tests will be needed? Will it require cross-browser testing? Please list the test areas (unit, integration and end-to-end) that needs to be added or updated to ensure that this feature will work as intended. Please use the list below as guidance. * Unit test changes * Integration test changes * End-to-end test change See the test engineering planning process and reach out to your counterpart Software Engineer in Test for assistance: https://about.gitlab.com/handbook/engineering/quality/test-engineering/#test-planning --> ### What does success look like, and how can we measure that? <!-- Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this. --> ### What is the type of buyer? <!-- What is the buyer persona for this feature? See https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/buyer-persona/ In which enterprise tier should this feature go? See https://about.gitlab.com/handbook/product/pricing/#four-tiers --> This epic was broken into two parts and has two bundles of capabilities: ~"GitLab Premium" - Custom compliance frameworks can be created ~"GitLab Ultimate" - Compliance pipelines can be created and used. ### Is this a cross-stage feature? <!-- Communicate if this change will affect multiple Stage Groups or product areas. We recommend always start with the assumption that a feature request will have an impact into another Group. Loop in the most relevant PM and Product Designer from that Group to provide strategic support to help align the Group's broader plan and vision, as well as to avoid UX and technical debt. https://about.gitlab.com/handbook/product/#cross-stage-features --> Yes. This will require effort from gitlab~4116705 gitlab~3103453 gitlab~3103455 ### Links / references
epic