InfoGrab DocsInfoGrab Docs

파이프라인 실행 정책

요약

파이프라인 실행 정책을 사용하면 하나의 구성으로 여러 프로젝트의 CI/CD job을 관리하고 강제할 수 있습니다. 같은 프로젝트에 있는 기존 컴플라이언스 파이프라인을 마이그레이션하기 전에는 파이프라인 실행 정책을 활성화하지 마십시오.

히스토리
  • GitLab 17.2에서 pipeline_execution_policy_type이라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 17.3에서 정식 출시되었습니다. 기능 플래그 pipeline_execution_policy_type이 제거되었습니다.

파이프라인 실행 정책을 사용하면 하나의 구성으로 여러 프로젝트의 CI/CD job을 관리하고 강제할 수 있습니다.

Warning

같은 프로젝트에 있는 기존 컴플라이언스 파이프라인을 마이그레이션하기 전에는 파이프라인 실행 정책을 활성화하지 마십시오. 둘 다 구성되어 있으면 컴플라이언스 파이프라인이 표준 프로젝트 파이프라인을 대체하지만, 파이프라인 실행 정책은 원래의 프로젝트 파이프라인을 기준으로 적용됩니다. 이 때문에 파이프라인 실행 정책 전략과 CI/CD 구성에 따라 동작을 예측할 수 없게 되며, job이 중복되거나 파이프라인이 실패하거나 중요한 보안 및 컴플라이언스 검사가 누락될 수 있습니다. 컴플라이언스 파이프라인은 더 이상 사용되지 않습니다. 기존 컴플라이언스 파이프라인은 가능한 한 빨리 마이그레이션하고, 모든 신규 구현에는 파이프라인 실행 정책을 사용해야 합니다.

스키마#

히스토리
  • GitLab 17.4에서 suffix 필드가 활성화되었습니다.
  • GitLab 17.7에서 이후 stage가 .pipeline-policy-pre stage의 완료를 기다리도록 파이프라인 실행 방식이 변경되었습니다.
  • GitLab 18.10에서 .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뛰도록 파이프라인 실행 방식이 변경되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 19.0에서 새 파이프라인 실행 방식이 정식 출시되었습니다. 기능 플래그 ensure_pipeline_policy_pre_succeeds가 제거되었습니다.

파이프라인 실행 정책이 담긴 YAML 파일은 pipeline_execution_policy 키 아래에 중첩된, 파이프라인 실행 정책 스키마와 일치하는 객체 배열로 구성됩니다. 보안 정책 프로젝트당 pipeline_execution_policy 키 아래에 최대 5개의 정책을 구성할 수 있습니다. 처음 5개 이후에 구성한 정책은 적용되지 않습니다.

새 정책을 저장하면 GitLab이 이 JSON 스키마에 대해 내용을 검증합니다. JSON 스키마를 읽는 방법에 익숙하지 않다면 다음 절과 표를 대신 참고할 수 있습니다.

필드 유형 필수 설명
pipeline_execution_policy array of pipeline execution policy true 파이프라인 실행 정책 목록 (최대 5개)

pipeline_execution_policy 스키마#

필드 유형 필수 설명
name string true 정책 이름. 최대 255자입니다.
description (선택 사항) string true 정책 설명.
enabled boolean true 정책을 활성화(true)하거나 비활성화(false)하는 플래그.
content object of content true 프로젝트 파이프라인에 주입할 CI/CD 구성에 대한 참조.
pipeline_config_strategy string false inject_policy, inject_ci(더 이상 사용되지 않음), override_project_ci 중 하나일 수 있습니다. 자세한 내용은 파이프라인 전략을 참고합니다.
policy_scope object of policy_scope false 지정한 프로젝트, 그룹 또는 컴플라이언스 프레임워크 레이블을 기준으로 정책의 범위를 지정합니다.
suffix string false on_conflict(기본값) 또는 never일 수 있습니다. job 이름 충돌을 처리하는 동작을 정의합니다. on_conflict는 고유성을 깨뜨리는 job의 이름에 고유한 접미사를 붙입니다. never는 프로젝트와 적용 가능한 모든 정책에 걸쳐 job 이름이 고유하지 않으면 파이프라인을 실패시킵니다.
skip_ci object of skip_ci false 사용자가 skip-ci 지시문을 적용할 수 있는지 여부를 정의합니다. 기본적으로 skip-ci 사용은 무시되며, 그 결과 파이프라인 실행 정책이 적용된 파이프라인은 건너뛸 수 없습니다.
no_pipeline object of no_pipeline false 사용자가 no_pipeline 지시문을 적용할 수 있는지 여부를 정의합니다. 기본적으로 no_pipeline 사용은 무시되며, 그 결과 파이프라인 실행 정책이 적용된 파이프라인은 생성되지 않도록 막을 수 없습니다.
variables_override object of variables_override false 사용자가 정책이 생성한 job에서 정책 변수의 동작을 재정의할 수 있는지 제어합니다. 기본적으로 정책 변수는 가장 높은 우선순위로 강제되며 사용자가 재정의할 수 없습니다.

다음 사항에 유의합니다.

  • 파이프라인을 트리거하는 사용자는 파이프라인 실행 정책에 지정된 파이프라인 실행 파일에 대해 최소한 읽기 권한이 있어야 합니다. 그렇지 않으면 파이프라인이 시작되지 않습니다.
  • 파이프라인 실행 파일이 삭제되거나 이름이 바뀌면 해당 정책이 적용된 프로젝트의 파이프라인이 동작하지 않을 수 있습니다.
  • 파이프라인 실행 정책 job은 예약된 두 stage 중 하나에 할당할 수 있습니다.
    • .pipeline-policy-pre: 파이프라인의 시작 부분에 있으며 .pre stage보다 앞에 위치합니다.
    • .pipeline-policy-post: 파이프라인의 맨 끝에 있으며 .post stage 뒤에 위치합니다.
  • 예약된 stage에 job을 주입하는 것은 항상 동작하도록 보장됩니다. 실행 정책 job은 표준 stage(build, test, deploy)나 사용자가 선언한 stage에도 할당할 수 있습니다. 다만 이 경우 프로젝트 파이프라인 구성에 따라 job이 무시될 수 있습니다.
  • 파이프라인 실행 정책 밖에서는 job을 예약된 stage에 할당할 수 없습니다.
  • 파이프라인 실행 정책에는 고유한 job 이름을 선택합니다. 일부 CI/CD 구성은 job 이름을 기준으로 동작하므로, 같은 파이프라인에 같은 이름의 job이 여러 개 있으면 원치 않는 결과가 생길 수 있습니다. 예를 들어 needs 키워드는 한 job이 다른 job에 의존하도록 만듭니다. 이름이 example인 job이 여러 개 있으면, example job 이름을 needs하는 job은 example job 인스턴스 중 하나에만 무작위로 의존합니다.
  • 프로젝트에 CI/CD 구성 파일이 없어도 파이프라인 실행 정책은 계속 유효합니다.
  • 적용되는 접미사에는 정책의 순서가 영향을 줍니다.
  • 특정 프로젝트에 적용된 정책 중 하나라도 suffix: never이면, 파이프라인에 이름이 같은 다른 job이 이미 있을 때 파이프라인이 실패합니다.
  • 파이프라인 실행 정책은 모든 브랜치와 파이프라인 소스에 강제됩니다. 다만 머지 리퀘스트 파이프라인에서는 일부 rules: 또는 workflow:rules 구성이 job 실행을 막을 수 있습니다. 파이프라인 실행 정책이 강제되는 시점을 제어하려면 workflow 규칙을 사용합니다.

보안 정책 파이프라인 검사#

히스토리

프로젝트에 파이프라인 실행 정책이나 스캔 실행 정책이 구성되어 있으면, 보안 정책 파이프라인 검사는 머지 리퀘스트를 머지하기 전에 최신 커밋의 모든 파이프라인이 성공하도록 요구합니다. 이 검사는 보안 정책이 만든 파이프라인만이 아니라 해당 커밋 때문에 실행되는 모든 파이프라인에 적용됩니다.

보안 정책 파이프라인 검사는 머지 리퀘스트 파이프라인은 통과했지만 다른 파이프라인(예: 보안 정책이 만든 브랜치 파이프라인)이 실패한 경우 머지를 막습니다. 이런 검사가 없으면 검증되지 않은 코드가 머지될 수 있습니다.

보안 정책 파이프라인 검사는 다음과 같이 동작합니다.

  • 프로젝트 설정 Pipelines must succeed가 활성화되어 있으면, 파이프라인 실패는 머지를 막는 강한 차단으로 이어집니다.
  • Pipelines must succeed가 활성화되어 있지 않으면, 파이프라인 실패는 경고로 표시됩니다. 머지 리퀘스트는 여전히 자동 머지로 설정할 수 있습니다.
  • 프로젝트 설정 Skipped pipelines are considered successful가 활성화되어 있으면, 건너뛴 파이프라인은 통과한 것으로 취급됩니다.
Warning

프로젝트를 마이그레이션하면 가져온 파이프라인이 원본의 상태를 그대로 유지하므로, 다시 실행하지 않고도 대상 인스턴스에서 보안 정책 파이프라인 검사를 충족할 수 있습니다. 가져온 머지 리퀘스트는 머지하기 전에 새 파이프라인을 실행합니다.

.pipeline-policy-pre stage#

히스토리
  • GitLab 18.10에서 .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뛰도록 파이프라인 실행 방식이 변경되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 19.0에서 새 파이프라인 실행 방식이 정식 출시되었습니다. 기능 플래그 ensure_pipeline_policy_pre_succeeds가 제거되었습니다.

.pipeline-policy-pre stage의 job은 항상 실행됩니다. 이 stage는 보안 및 컴플라이언스 사용 사례를 위해 설계되었습니다. 파이프라인의 job은 .pipeline-policy-pre stage가 완료될 때까지 시작되지 않습니다.

.pipeline-policy-pre stage가 실패하거나 이 stage의 모든 job을 건너뛰면, 다음을 포함해 이후 stage의 모든 job을 건너뜁니다.

  • needs: []가 있는 job.
  • when: always가 있는 job.

워크플로에서 이 동작이 필요하지 않다면 대신 .pre stage나 사용자 지정 stage를 사용합니다.

Note

GitLab 18.9 이전 버전에서는 needs: [] 또는 when: always가 있는 job이 실패한 .pipeline-policy-pre stage를 우회할 수 있었습니다. 이 동작은 GitLab 18.10에서 기본값이 되었고 GitLab 19.0부터 영구 적용됩니다.

Job 이름 모범 사례#

히스토리
  • GitLab 17.4에서 이름 충돌 처리가 도입되었습니다.

job이 보안 정책으로 생성되었음을 나타내는 표시는 눈에 보이지 않습니다. 정책이 만든 job을 쉽게 식별하고 job 이름 충돌을 피하려면 job 이름에 고유한 접두사나 접미사를 추가합니다.

예시:

  • 사용: policy1:deployments:sast. 이 이름은 다른 모든 정책과 프로젝트에서 고유할 가능성이 높습니다.
  • 사용하지 않음: sast. 이 이름은 다른 정책과 프로젝트에서 중복될 가능성이 높습니다.

파이프라인 실행 정책은 suffix 속성에 따라 이름 충돌을 처리합니다. 이름이 같은 job이 여러 개 있는 경우는 다음과 같습니다.

  • on_conflict(기본값)를 사용하면, job 이름이 파이프라인의 다른 job과 충돌할 때 해당 job에 접미사가 추가됩니다.
  • never를 사용하면, 충돌이 발생해도 접미사가 추가되지 않고 파이프라인이 실패합니다.

접미사는 job이 메인 파이프라인에 병합되는 순서에 따라 추가됩니다.

순서는 다음과 같습니다.

  1. 프로젝트 파이프라인 job
  2. 프로젝트 정책 job (해당하는 경우)
  3. 그룹 정책 job (해당하는 경우, 계층 구조 순으로 정렬되며 최상위 그룹이 마지막에 적용됨)

적용되는 접미사의 형식은 다음과 같습니다.

:policy-<security-policy-project-id>-<policy-index>.

결과 job의 예: sast:policy-123456-0.

하나의 보안 정책 프로젝트에서 여러 정책이 같은 job 이름을 정의하면, 숫자 접미사는 충돌하는 정책의 인덱스에 해당합니다.

결과 job의 예:

  • sast:policy-123456-0
  • sast:policy-123456-1

Job stage 모범 사례#

파이프라인 실행 정책에 정의된 job은 프로젝트의 CI/CD 구성에 정의된 모든 stage와 예약된 stage인 .pipeline-policy-pre, .pipeline-policy-post를 사용할 수 있습니다.

Note

정책에 .pre와 .post stage의 job만 있으면 정책의 파이프라인은 empty로 평가됩니다. 이 경우 프로젝트의 파이프라인에 병합되지 않습니다.

파이프라인 실행 정책에서 .pre와 .post stage를 사용하려면 다른 stage에서 실행되는 job을 하나 이상 포함해야 합니다. 예: .pipeline-policy-pre.

inject_policy 파이프라인 전략을 사용할 때 대상 프로젝트에 자체 .gitlab-ci.yml 파일이 없으면 모든 정책 stage가 파이프라인에 주입됩니다.

(더 이상 사용되지 않는) inject_ci 파이프라인 전략을 사용할 때 대상 프로젝트에 자체 .gitlab-ci.yml 파일이 없으면 사용할 수 있는 stage는 기본 파이프라인 stage와 예약된 stage뿐입니다.

수정할 권한이 없는 CI/CD 구성이 있는 프로젝트에 파이프라인 실행 정책을 강제할 때는 .pipeline-policy-pre와 .pipeline-policy-post stage에 job을 정의해야 합니다. 이 stage는 프로젝트의 CI/CD 구성과 관계없이 항상 사용할 수 있습니다.

여러 파이프라인 실행 정책과 사용자 지정 stage에 override_project_ci 파이프라인 전략을 함께 사용하면, 서로 호환되도록 stage를 같은 상대적 순서로 정의해야 합니다.

유효한 구성 예시:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [test, deploy]

유효하지 않은 구성 예시:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [deploy, test]

override_project_ci 정책 중 하나 이상의 stages 구성이 유효하지 않으면 파이프라인이 실패합니다.

content 유형#

필드 유형 필수 설명
project string true 같은 GitLab 인스턴스에 있는 프로젝트의 전체 GitLab 프로젝트 경로.
file string true 루트 디렉터리(/)를 기준으로 한 전체 파일 경로. YAML 파일의 확장자는 .yml 또는 .yaml이어야 합니다.
ref string false 파일을 가져올 ref. 지정하지 않으면 프로젝트의 HEAD가 기본값입니다.

정책에서 content 유형을 사용하면 다른 리포지터리에 저장된 CI/CD 구성을 참조할 수 있습니다. 따라서 여러 정책에서 같은 CI/CD 구성을 재사용할 수 있어 이러한 구성을 유지 관리하는 부담이 줄어듭니다. 예를 들어 정책 A와 정책 B에 강제하려는 사용자 지정 시크릿 탐지 CI/CD 구성이 있다면, YAML 구성 파일을 하나만 만들고 두 정책에서 그 구성을 참조하면 됩니다.

사전 요구 사항:

  • content 유형이 포함된 정책이 강제되는 프로젝트에서 파이프라인을 실행하는 사용자는 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다.

  • 파이프라인 실행 정책을 강제하는 프로젝트에서, 사용자가 파이프라인을 트리거하려면 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다.

    GitLab 17.4 이상에서는 content 유형을 사용해 보안 정책 프로젝트에 지정된 CI/CD 구성 파일에 필요한 읽기 전용 접근 권한을 부여할 수 있습니다. 이렇게 하려면 보안 정책 프로젝트의 일반 설정에서 Pipeline execution policies 설정을 활성화합니다. 이 설정을 활성화하면 파이프라인을 트리거한 사용자가 파이프라인 실행 정책이 강제하는 CI/CD 구성 파일을 읽을 수 있습니다. 이 설정은 구성 파일이 저장된 프로젝트의 다른 부분에는 사용자에게 접근 권한을 부여하지 않습니다. 자세한 내용은 접근 권한 자동 부여를 참고합니다.

skip_ci 유형#

히스토리
  • GitLab 17.7에서 도입되었습니다.

파이프라인 실행 정책으로 [skip ci] 지시문을 사용할 수 있는 사용자를 제어할 수 있습니다. 중요한 보안 및 컴플라이언스 검사는 계속 수행되도록 하면서, 특정 사용자나 서비스 계정에만 [skip ci] 사용을 허용할 수 있습니다.

skip_ci 키워드를 사용해 사용자가 skip_ci 지시문을 적용해 파이프라인을 건너뛸 수 있는지 지정합니다. 이 키워드를 지정하지 않으면 skip_ci 지시문은 무시되어 모든 사용자가 파이프라인 실행 정책을 우회할 수 없습니다.

필드 유형 가능한 값 설명
allowed boolean true, false 파이프라인 실행 정책이 강제되는 파이프라인에서 skip-ci 지시문 사용을 허용(true)하거나 금지(false)하는 플래그.
allowlist object users allowed 플래그와 관계없이 항상 skip-ci 지시문을 사용할 수 있는 사용자를 지정합니다. users: 다음에 사용자 ID를 나타내는 id 키를 가진 객체 배열을 사용합니다.

no_pipeline 유형#

파이프라인 실행 정책으로 [no_pipeline] 지시문을 사용할 수 있는 사용자를 제어할 수 있습니다. 중요한 보안 및 컴플라이언스 검사는 계속 수행되도록 하면서, 특정 사용자나 서비스 계정에만 [no_pipeline] 사용을 허용할 수 있습니다.

no_pipeline 키워드를 사용해 사용자가 no_pipeline 지시문을 적용해 파이프라인을 생성하지 않을 수 있는지 지정합니다. 이 키워드를 지정하지 않으면 no_pipeline 지시문은 무시되어 모든 사용자가 파이프라인 실행 정책을 우회할 수 없습니다.

필드 유형 가능한 값 설명
allowed boolean true, false 파이프라인 실행 정책이 강제되는 파이프라인에서 no_pipeline 지시문 사용을 허용(true)하거나 금지(false)하는 플래그.
allowlist object users allowed 플래그와 관계없이 항상 no_pipeline 지시문을 사용할 수 있는 사용자를 지정합니다. users: 다음에 사용자 ID를 나타내는 id 키를 가진 객체 배열을 사용합니다.

variables_override 유형#

히스토리
  • GitLab 18.1에서 도입되었습니다.
필드 유형 가능한 값 설명
allowed boolean true, false true이면 다른 구성이 정책 변수를 재정의할 수 있습니다. false이면 다른 구성이 정책 변수를 재정의할 수 없습니다.
exceptions array array of string 전역 규칙의 예외가 되는 변수. allowed: false일 때 exceptions는 허용 목록입니다. allowed: true일 때 exceptions는 거부 목록입니다.
dotenv string respect_policy, allow_override dotenv 아티팩트 변수가 variables_override 정책 규칙을 따르는지 제어합니다. 기본적으로(지정하지 않았거나 respect_policy로 설정한 경우) dotenv 변수는 다른 변수와 같은 재정의 규칙을 적용받습니다. dotenv 변수가 정책 규칙을 우회하도록 하려면 allow_override로 설정합니다. 이 옵션은 dotenv 아티팩트가 정책 변수를 재정의하는 데 의존하는 워크플로와의 하위 호환성을 위해 제공됩니다. allow_override를 사용하면 variables_override가 제공하는 보안 보장이 약해지므로 권장하지 않습니다.

이 옵션은 정책이 강제되는 파이프라인에서 사용자 정의 변수를 처리하는 방식을 제어합니다. 이 기능으로 다음을 할 수 있습니다.

  • 기본적으로 사용자 정의 변수를 거부합니다(권장). 보안이 더 강력하지만, 사용자가 변경할 수 있어야 하는 모든 변수를 exceptions 허용 목록에 추가해야 합니다.
  • 기본적으로 사용자 정의 변수를 허용합니다. 유연성은 더 높지만 보안은 낮아집니다. 정책 강제에 영향을 줄 수 있는 변수를 exceptions 거부 목록에 추가해야 하기 때문입니다.
  • allowed 전역 규칙에 대한 예외를 정의합니다.

사용자 정의 변수는 파이프라인에 있는 모든 정책 job의 동작에 영향을 줄 수 있으며 다양한 소스에서 올 수 있습니다.

variables_override 옵션을 지정하지 않으면 "가장 높은 우선순위" 동작이 유지됩니다. 이 동작에 대한 자세한 내용은 파이프라인 실행 정책의 변수 우선순위를 참고합니다.

파이프라인 실행 정책이 변수 우선순위를 제어하면 job 로그에 구성된 variables_override 옵션과 정책 이름이 포함됩니다. 이 로그를 보려면 gitlab-runner를 버전 18.1 이상으로 업데이트해야 합니다.

variables_override 구성 예시#

파이프라인 실행 정책 구성에 variables_override 옵션을 추가합니다.

pipeline_execution_policy:
  - name: Security Scans
    description: 'Enforce security scanning'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: gitlab-org/security-policies
          file: security-scans.yml
    variables_override:
      allowed: false
      exceptions:
        - CS_IMAGE
        - SAST_EXCLUDED_ANALYZERS
컨테이너 사용자 지정은 허용하면서 보안 스캔 강제 (허용 목록 방식)#

보안 스캔은 강제하되 프로젝트 팀이 자체 컨테이너 이미지를 지정하도록 허용하려면 다음과 같이 합니다.

variables_override:
  allowed: false
  exceptions:
    - CS_IMAGE

이 구성은 CS_IMAGE를 제외한 모든 사용자 정의 변수를 차단하므로, 보안 스캔을 비활성화할 수 없도록 보장하면서 팀이 컨테이너 이미지를 사용자 지정할 수 있게 합니다.

특정 보안 변수의 재정의 방지 (거부 목록 방식)#

대부분의 변수는 허용하되 보안 스캔의 비활성화를 막으려면 다음과 같이 합니다.

variables_override:
  allowed: true
  exceptions:
    - SECRET_DETECTION_DISABLED
    - SAST_DISABLED
    - DEPENDENCY_SCANNING_DISABLED
    - DAST_DISABLED
    - CONTAINER_SCANNING_DISABLED

이 구성은 보안 스캔을 비활성화할 수 있는 변수를 제외한 모든 사용자 정의 변수를 허용합니다.

Warning

이 구성은 유연성을 제공할 수 있지만 보안상의 영향 때문에 권장하지 않습니다. exceptions에 명시적으로 나열되지 않은 변수는 모두 사용자가 주입할 수 있습니다. 그 결과 정책 구성은 allowlist 방식을 사용할 때만큼 잘 보호되지 않습니다.

policy scope 스키마#

정책 강제를 사용자 지정하려면 정책의 범위를 정의하여 지정한 프로젝트, 그룹 또는 컴플라이언스 프레임워크 레이블을 포함하거나 제외할 수 있습니다. 자세한 내용은 범위를 참고합니다.

Note

policy_scope 필드를 빈 컬렉션(예: including: [])으로 설정하면 해당 필드를 생략한 것과 같게 취급되므로, 정책이 해당 범위 차원의 모든 프로젝트에 적용됩니다. 정책을 완전히 비활성화하려면 enabled: false를 사용합니다. 자세한 내용은 policy_scope의 빈 컬렉션을 참고합니다.

CI/CD 구성에 대한 접근 관리#

프로젝트에 파이프라인 실행 정책을 강제하면, 파이프라인을 트리거하는 사용자는 정책 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다. 프로젝트 접근 권한은 수동 또는 자동으로 부여할 수 있습니다.

접근 권한 수동 부여#

사용자나 그룹이 파이프라인 실행 정책이 강제되는 파이프라인을 실행할 수 있게 하려면, 정책 CI/CD 구성이 있는 프로젝트에 해당 사용자나 그룹을 초대할 수 있습니다.

접근 권한 자동 부여#

파이프라인 실행 정책이 강제되는 프로젝트에서 파이프라인을 실행하는 모든 사용자에게 정책 CI/CD 구성에 대한 접근 권한을 자동으로 부여할 수 있습니다.

사전 요구 사항:

  • 파이프라인 실행 정책 CI/CD 구성이 보안 정책 프로젝트에 저장되어 있는지 확인합니다.
  • 보안 정책 프로젝트의 일반 설정에서 Pipeline execution policies 설정을 활성화합니다.

보안 정책 프로젝트가 아직 없고 첫 번째 파이프라인 실행 정책을 만들려면, 빈 프로젝트를 만들어 보안 정책 프로젝트로 연결합니다. 프로젝트를 연결하려면 다음을 수행합니다.

  1. 정책을 강제하려는 그룹 또는 프로젝트에서 Secure > Policies > Edit policy project를 선택합니다.
  2. 보안 정책 프로젝트를 선택합니다.

이 프로젝트가 보안 정책 프로젝트가 되고 해당 설정을 사용할 수 있게 됩니다.

Note

$CI_JOB_TOKEN을 사용해 다운스트림 파이프라인을 만들려면 프로젝트와 그룹이 보안 정책 프로젝트를 요청할 수 있도록 승인되어 있는지 확인해야 합니다. 보안 정책 프로젝트에서 Settings > CI/CD > Job token permissions로 이동하여 승인된 그룹과 프로젝트를 허용 목록에 추가합니다. CI/CD 설정이 보이지 않으면 Settings > General > Visibility, project features, permissions로 이동하여 CI/CD를 활성화합니다.

구성#

  1. 정책 프로젝트에서 Settings > General > Visibility, project features, permissions를 선택합니다.

  2. Pipeline execution policies 설정을 활성화합니다.

  3. 정책 프로젝트에서 정책 CI/CD 구성을 위한 파일을 만듭니다.

    # policy-ci.yml
    
    policy-job:
      script: ...
    
  4. 정책을 강제하려는 그룹 또는 프로젝트에서 파이프라인 실행 정책을 만들고 보안 정책 프로젝트의 CI/CD 구성 파일을 지정합니다.

    pipeline_execution_policy:
    - name: My pipeline execution policy
      description: Enforces CI/CD jobs
      enabled: true
      pipeline_config_strategy: inject_policy
      content:
        include:
         - project: my-group/my-security-policy-project
           file: policy-ci.yml
    

비공개 또는 내부 프로젝트에 대한 접근 허용#

정책의 include: 값이 보안 정책 프로젝트가 아닌 다른 비공개 또는 내부 프로젝트에 저장된 CI/CD 구성 파일을 참조할 수 있습니다. 이 경우 파이프라인 실행 정책이 강제되는 프로젝트에서 파이프라인을 트리거하는 사용자에게 접근 권한을 허용할 수 있습니다.

구성 단계는 비공개 또는 내부 프로젝트에 대한 접근 허용을 참고합니다.

파이프라인 구성 전략#

파이프라인 구성 전략은 정책 구성을 프로젝트 파이프라인과 병합하는 방법을 정의합니다. 파이프라인 실행 정책은 .gitlab-ci.yml 파일에 정의된 job을 격리된 파이프라인에서 실행하고, 이 파이프라인은 대상 프로젝트의 파이프라인에 병합됩니다.

inject_policy 유형#

히스토리
  • GitLab 17.9에서 도입되었습니다.

이 전략은 프로젝트의 원래 CI/CD 구성을 완전히 대체하지 않고 기존 프로젝트 파이프라인에 사용자 지정 CI/CD 구성을 추가합니다. 새 보안 스캔, 컴플라이언스 검사, 사용자 지정 스크립트 같은 추가 단계로 현재 파이프라인을 강화하거나 확장하려는 경우에 적합합니다.

더 이상 사용되지 않는 inject_ci 전략과 달리 inject_policy는 파이프라인에 사용자 지정 정책 stage를 주입할 수 있으므로, CI/CD 워크플로의 어느 위치에 정책 규칙을 적용할지 더 세밀하게 제어할 수 있습니다.

정책을 여러 개 활성화하면 이 전략은 각 정책의 모든 job을 주입합니다.

이 전략을 사용하면 각 파이프라인이 격리된 YAML 구성을 가지므로, 프로젝트 CI/CD 구성이 정책 파이프라인에 정의된 어떤 동작도 재정의할 수 없습니다.

.gitlab-ci.yml 파일이 없는 프로젝트의 경우 이 전략은 .gitlab-ci.yml 파일을 암묵적으로 생성합니다. 실행되는 파이프라인에는 파이프라인 실행 정책에 정의된 job만 포함됩니다.

Note

파이프라인 실행 정책이 정책 job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 프로젝트의 CI/CD job뿐입니다. 프로젝트가 프로젝트 CI/CD job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 파이프라인 실행 정책 job뿐입니다.

즉, 프로젝트 파이프라인이 실행되지 않도록 막는 프로젝트의 workflow:rules 구성이 정책 파이프라인의 생성까지 막지는 않습니다. 정책에 Dependency-Scanning.v2.gitlab-ci.yml이 포함되어 있으면, 정책은 정책 컨텍스트에서 사용할 수 있는 값에 따라 의존성 스캔 머지 리퀘스트 파이프라인을 여전히 생성할 수 있습니다.

Stage 주입#

정책 파이프라인의 stage는 일반적인 CI/CD 구성을 따릅니다. 사용자 지정 stage의 앞과 뒤에 올 stage를 지정하면, 사용자 지정 정책 stage가 프로젝트 파이프라인에 주입되는 순서를 정의할 수 있습니다.

프로젝트 파이프라인과 정책 파이프라인의 stage는 방향성 비순환 그래프(Directed Acyclic Graph, DAG)로 표현되며, 노드는 stage이고 간선은 의존 관계를 나타냅니다. 파이프라인을 결합하면 개별 DAG가 하나의 더 큰 DAG로 병합됩니다. 그 후 위상 정렬을 수행하여 모든 파이프라인의 stage가 실행되어야 하는 순서를 결정합니다. 이 정렬은 최종 순서에서 모든 의존 관계가 지켜지도록 보장합니다. 의존 관계가 충돌하면 파이프라인이 실행되지 않습니다. 의존 관계를 바로잡으려면 프로젝트와 정책에서 사용하는 stage가 서로 일치하도록 맞춥니다.

정책 파이프라인 구성에 stage가 명시적으로 정의되어 있지 않으면 파이프라인은 기본 stage인 stages: [build, test, deploy]를 사용합니다. 이 stage를 포함하되 다른 순서로 나열하면 파이프라인이 Cyclic dependencies detected when enforcing policies 오류와 함께 실패합니다.

다음 예시는 이 동작을 보여 줍니다. 모든 예시는 다음과 같은 프로젝트 CI/CD 구성을 가정합니다.

# .gitlab-ci.yml
stages: [build, test, deploy]

project-build-job:
  stage: build
  script: ...

project-test-job:
  stage: test
  script: ...

project-deploy-job:
  stage: deploy
  script: ...
예시 1#
# policy-ci.yml
stages: [test, policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • test stage가 있으면 그 뒤에 주입되어야 합니다.
  • deploy stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [build, deploy, test]로 지정했다면 제약 조건을 충족할 수 없으므로 파이프라인이 Cyclic dependencies detected when enforcing policies 오류와 함께 실패합니다. 실패를 해결하려면 프로젝트 구성을 조정하여 stage를 정책과 일치시킵니다.
  • .gitlab-ci.yml에서 stage를 [build]로 지정했다면 결과 파이프라인의 stage는 [build, policy-stage]입니다.
예시 2#
# policy-ci.yml
stages: [policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • deploy stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [build, deploy, test]로 지정했다면 결과 파이프라인의 stage는 [build, policy-stage, deploy, test]가 됩니다.
  • 프로젝트 파이프라인에 deploy stage가 없으면 policy-stage stage는 파이프라인의 끝, 즉 .pipeline-policy-post 바로 앞에 주입됩니다.
예시 3#
# policy-ci.yml
stages: [test, policy-stage]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • test stage가 있으면 그 뒤에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, deploy, policy-stage] stage가 포함됩니다.

특수한 경우:

  • 프로젝트 파이프라인에 test stage가 없으면 policy-stage stage는 파이프라인의 끝, 즉 .pipeline-policy-post 바로 앞에 주입됩니다.
예시 4#
# policy-ci.yml
stages: [policy-stage]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage에는 제약 조건이 없습니다.

결과: 파이프라인에는 [build, test, deploy, policy-stage] stage가 포함됩니다.

예시 5#
# policy-ci.yml
stages: [check, lint, test, policy-stage, deploy, verify, publish]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • check, lint, test stage가 있으면 그 뒤에 주입되어야 합니다.
  • deploy, verify, publish stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [check, publish]로 지정했다면 결과 파이프라인의 stage는 [check, policy-stage, publish]입니다.

기본 stage 순서#

정책에 stage가 정의되어 있지 않으면 GitLab은 다음 기본 stage 순서를 강제합니다.

  1. .pre
  2. build
  3. test
  4. deploy
  5. .post.

기본 순서는 이러한 기본 stage를 다른 순서로 사용하는 프로젝트와 충돌할 수 있습니다. 예를 들어 stages: [test, build, deploy]처럼 test를 build보다 앞에 두는 경우입니다.

순환 의존성 방지#

순환 의존성 오류는 정책의 stage 순서가 프로젝트의 stage 순서와 충돌할 때 발생합니다. 이러한 오류를 피하려면 다음을 따릅니다.

  • 정책의 stage를 항상 명시적으로 정의하여 stage 순서가 분명하고 프로젝트와 호환되도록 합니다. 정책이 기본 stage인 build, test, deploy를 사용하면 그 순서가 모든 프로젝트에 강제된다는 점에 유의합니다.
  • 예약된 stage(.pipeline-policy-pre와 .pipeline-policy-post)만 사용하는 경우에는 이러한 예약된 stage가 항상 파이프라인의 맨 앞과 맨 끝에 배치되므로 정책에 기본 stage를 정의할 필요가 없습니다.

이 지침을 따르면 stage 구성이 서로 다른 프로젝트에서도 안정적으로 동작하는 정책을 만들 수 있습니다.

inject_ci(더 이상 사용되지 않음)#

Warning

이 기능은 GitLab 17.9에서 더 이상 사용되지 않게 되었습니다. 사용자 지정 정책 stage의 강제를 지원하는 inject_policy를 대신 사용합니다.

이 전략은 프로젝트의 원래 CI/CD 구성을 완전히 대체하지 않고 기존 프로젝트 파이프라인에 사용자 지정 CI/CD 구성을 추가합니다. 새 보안 스캔, 컴플라이언스 검사, 사용자 지정 스크립트 같은 추가 단계로 현재 파이프라인을 강화하거나 확장하려는 경우에 적합합니다.

정책을 여러 개 활성화하면 모든 job이 누적하여 주입됩니다.

이 전략을 사용하면 각 파이프라인이 격리된 YAML 구성을 가지므로, 프로젝트 CI/CD 구성이 정책 파이프라인에 정의된 어떤 동작도 재정의할 수 없습니다.

.gitlab-ci.yml 파일이 없는 프로젝트의 경우 이 전략은 .gitlab-ci.yml 파일을 암묵적으로 생성합니다. 이를 통해 파이프라인 실행 정책에 정의된 job만 포함하는 파이프라인이 실행될 수 있습니다.

Note

파이프라인 실행 정책이 정책 job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 프로젝트의 CI/CD job뿐입니다. 프로젝트가 프로젝트 CI/CD job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 파이프라인 실행 정책 job뿐입니다.

override_project_ci#

히스토리
  • workflow 규칙 처리 방식 업데이트:
  • GitLab 17.8에서 policies_always_override_project_ci라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 17.10에서 정식 출시되었습니다. 기능 플래그 policies_always_override_project_ci가 제거되었습니다.
  • GitLab 17.9에서 스캔 실행 정책이 파이프라인 실행 정책과 함께 실행될 수 있도록 override_project_ci 처리 방식이 변경되었습니다.

이 전략은 프로젝트의 기존 CI/CD 구성을 파이프라인 실행 정책이 정의한 새 구성으로 대체합니다. 이 전략은 전체 파이프라인을 표준화하거나 교체해야 할 때, 예를 들어 규제가 엄격한 산업에서 조직 전체의 CI/CD 표준이나 컴플라이언스 요구 사항을 강제하려는 경우에 이상적입니다. 파이프라인 구성을 재정의하려면 CI/CD job을 정의하고 include:project를 사용하지 않습니다.

이 전략은 inject_ci 또는 inject_policy 전략을 사용하는 다른 정책보다 우선합니다. override_project_ci가 있는 정책이 적용되면 프로젝트 CI/CD 구성은 무시됩니다. 다만 다른 보안 정책 구성은 재정의되지 않습니다.

파이프라인 실행 정책에서 override_project_ci를 스캔 실행 정책과 함께 사용하면 CI/CD 구성이 병합되고 두 정책이 모두 결과 파이프라인에 적용됩니다.

또는 프로젝트의 CI/CD 구성을 재정의하는 대신 프로젝트의 .gitlab-ci.yml과 병합할 수도 있습니다. 구성을 병합하려면 include:project를 사용합니다. 이 전략을 사용하면 사용자가 프로젝트 CI/CD 구성을 파이프라인 실행 정책 구성에 포함하여 정책 job을 사용자 지정할 수 있습니다. 예를 들어 정책과 프로젝트 CI/CD 구성을 하나의 YAML 파일로 결합하여 before_script 구성을 재정의하거나, 스캔할 컨테이너의 필수 경로를 정의하는 CS_IMAGE 같은 필수 변수를 정의할 수 있습니다. 이 동작에 대한 짧은 데모가 있습니다. 다음 다이어그램은 프로젝트 수준과 정책 수준에서 정의한 변수가 결과 파이프라인에서 어떻게 선택되는지 보여 줍니다.

Mermaid 다이어그램 (89줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
    accTitle: Variable precedence in pipeline execution policies
    accDescr: Policy variables take precedence over project variables when jobs are combined into the resulting pipeline.

classDef yaml text-align:left

ActualPolicyYAML["<pre> variables: MY_VAR: 'policy' policy-job: stage: test </pre>"]

class ActualPolicyYAML yaml

ActualProjectYAML["<pre> variables: MY_VAR: 'project' project-job: stage: test </pre>"]

class ActualProjectYAML yaml

PolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"]

class PolicyVariablesYAML yaml

ProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"]

class ProjectVariablesYAML yaml

ResultingPolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"]

class ResultingPolicyVariablesYAML yaml

ResultingProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"]

class ResultingProjectVariablesYAML yaml

PolicyCiYAML(Policy CI YAML) --> ActualPolicyYAML ProjectCiYAML(<code>.gitlab-ci.yml</code>) --> ActualProjectYAML

subgraph "Policy Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code>" PolicyVariablesYAML end end end

subgraph "Project Pipeline" subgraph "Test stage" subgraph "<code>project-job</code>" ProjectVariablesYAML end end end

ActualPolicyYAML -- "Used as source" --> PolicyVariablesYAML ActualProjectYAML -- "Used as source" --> ProjectVariablesYAML

subgraph "Resulting Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code> " ResultingPolicyVariablesYAML end

subgraph "&lt;code&gt;project-job&lt;/code&gt; "
  ResultingProjectVariablesYAML
end

end end

PolicyVariablesYAML -- "Inject <code>policy-job</code> if Test Stage exists" --> ResultingPolicyVariablesYAML ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVariablesYAML

Note

파이프라인 실행 정책의 workflow 규칙은 프로젝트의 원래 CI/CD 구성을 재정의합니다. 정책에 workflow 규칙을 정의하면 브랜치 파이프라인 사용 금지처럼 연결된 모든 프로젝트에 강제되는 규칙을 설정할 수 있습니다.

파이프라인 이름#

override_project_ci 전략을 사용하는 파이프라인 실행 정책은 프로젝트의 원래 CI/CD 구성에 정의된 파이프라인 이름을 재정의합니다.

파이프라인 이름은 파이프라인 실행 정책 구성에서 정의할 수 있습니다.

override_project_ci 전략을 사용하는 파이프라인 실행 정책이 여러 개 있으면 그룹 계층에서 가장 낮은 곳의 정책이 적용됩니다. 예를 들어 프로젝트의 정책은 해당 프로젝트가 속한 그룹의 정책을 재정의합니다. 하위 그룹의 정책은 그 하위 그룹이 속한 그룹의 정책보다 우선합니다.

프로젝트의 CI/CD 구성을 파이프라인 실행 정책 구성에 포함#

override_project_ci 전략을 사용할 때 프로젝트 구성을 파이프라인 실행 정책 구성에 포함할 수 있습니다.

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
    rules:
      - exists:
          paths:
            - '$CI_CONFIG_PATH'
          project: '$CI_PROJECT_PATH'
          ref: '$CI_COMMIT_SHA'

compliance_job:
 ...
Note

프로젝트의 .gitlab-ci.yml 구성이 include:project를 사용해 override_project_ci 정책에 포함되면, 프로젝트 구성이 정책 파이프라인의 일부가 됩니다. 이 경우 포함된 프로젝트 구성은 예약된 stage(.pipeline-policy-pre와 .pipeline-policy-post)에 job을 할당할 수 있습니다. 정책 파이프라인 안에서는 예약된 stage의 사용이 허용되기 때문입니다. 이 예외를 제외하면 job을 예약된 stage에 할당할 수 없습니다.

CI/CD 변수#

Warning

변수는 Git 리포지터리에 있는 정책 구성의 일부로 일반 텍스트로 저장되므로, 민감한 정보나 자격 증명을 변수에 저장하지 마십시오.

기본적으로 파이프라인 실행 정책은 격리된 상태로 실행되므로 정책 밖에서 정의된 변수를 적용하지 않습니다. 이 격리는 프로젝트 또는 그룹 CI/CD 변수를 사용해 파이프라인 유형을 선택하는 보안 스캔 템플릿에도 영향을 줍니다. 예를 들어 파이프라인 실행 정책이 Dependency-Scanning.v2.gitlab-ci.yml을 주입하면, 정책 job은 프로젝트나 그룹의 AST_ENABLE_MR_PIPELINES를 자동으로 받지 못합니다. 이 변수를 사용할 수 없으면 값이 null이 되고, 의존성 스캔 v2 템플릿은 null을 "true"와 같게 취급합니다. 그 결과 프로젝트나 그룹 변수가 AST_ENABLE_MR_PIPELINES: "false"로 설정되어 있어도 정책 job이 머지 리퀘스트 파이프라인에서 실행될 수 있습니다.

이 동작을 제어하려면 정책 CI/CD 구성에서 AST_ENABLE_MR_PIPELINES를 정의하거나, variables_override로 해당 변수를 허용합니다.

variables_override:
  allowed: false
  exceptions:
    - AST_ENABLE_MR_PIPELINES

allowed: false로 설정하면 exceptions에 나열된 변수를 제외한 모든 프로젝트 및 그룹 변수가 차단됩니다. 반대로 allowed: true로 설정하면 exceptions에 변수를 나열했을 때 그 변수를 허용하는 것이 아니라 차단합니다.

variables_override 설정을 활성화하면 파이프라인 실행 정책은 다음과 같은 사용자 정의 변수에 접근할 수 있습니다.

  • 그룹 CI/CD 설정의 변수.
  • 프로젝트 CI/CD 설정의 변수.
  • 사용자가 새 파이프라인을 실행할 때 지정한 변수.

그러나 variables_override 설정을 활성화하더라도 파이프라인 실행 정책은 다음 유형의 변수에는 접근할 수 없습니다.

  • 다른 정책에 정의된 변수.
  • 프로젝트의 .gitlab-ci.yml 파일에 정의된 변수.

variables_override 설정을 활성화하면 정책은 표준 CI/CD 변수 우선순위 규칙에 따라 변수에 접근하고 적용할 수 있습니다.

그러나 파이프라인 실행 정책을 사용할 때는 우선순위 규칙이 파이프라인 실행 정책 전략에 따라 달라질 수 있어 더 복잡합니다.

  • inject_policy 전략: 변수가 파이프라인 실행 정책에 정의되어 있으면 job은 항상 이 값을 사용합니다. 변수가 파이프라인 실행 정책에 정의되어 있지 않으면 job은 그룹 또는 프로젝트 설정의 값을 적용합니다.
  • inject_ci 전략: 변수가 파이프라인 실행 정책에 정의되어 있으면 job은 항상 이 값을 사용합니다. 변수가 파이프라인 실행 정책에 정의되어 있지 않으면 job은 그룹 또는 프로젝트 설정의 값을 적용합니다.
  • override_project_ci 전략: 결과 파이프라인의 모든 job이 정책 job으로 취급됩니다. 정책에 정의된 변수(포함된 파일의 변수 포함)는 프로젝트 및 그룹 변수보다 우선합니다. 즉, 포함된 프로젝트의 CI/CD 구성에 있는 job의 변수가 프로젝트 및 그룹 설정에 정의된 변수보다 우선합니다.

파이프라인 실행 정책의 변수에 대한 자세한 내용은 파이프라인 실행 정책의 변수 우선순위를 참고합니다.

UI에서 프로젝트 또는 그룹 변수를 정의할 수 있습니다.

파이프라인 실행 정책의 변수 우선순위#

파이프라인 실행 정책을 사용할 때, 특히 override_project_ci 전략에서는 여러 위치에 정의된 변수 값의 우선순위가 표준 GitLab CI/CD 파이프라인과 다를 수 있습니다. 이해해야 할 중요한 사항은 다음과 같습니다.

  • override_project_ci를 사용하면 포함된 프로젝트의 CI/CD 구성에서 온 job을 포함해 결과 파이프라인의 모든 job이 정책 job으로 간주됩니다.
  • 정책 파이프라인에 정의된 변수(인스턴스 전체 또는 job 단위)는 프로젝트 또는 그룹 설정에 정의된 변수보다 우선합니다.
  • 이 동작은 프로젝트의 CI/CD 구성 파일(.gitlab-ci.yml)에서 포함된 job을 포함해 모든 job에 적용됩니다.

예시#

프로젝트의 CI/CD 구성에 있는 변수와 포함된 .gitlab-ci.yml 파일에 정의된 job 변수의 이름이 같으면, override_project_ci를 사용할 때 job 변수가 우선합니다.

프로젝트의 CI/CD 설정에 MY_VAR 변수가 정의되어 있습니다.

  • Key: MY_VAR
  • Value: Project configuration variable value

포함된 프로젝트의 .gitlab-ci.yml에 같은 변수가 정의되어 있습니다.

project-job:
  variables:
    MY_VAR: "Project job variable value"
  script:
    - echo $MY_VAR  # This will output "Project job variable value"

이 경우 job 변수 값인 Project job variable value가 우선합니다.

수동으로 실행하는 파이프라인의 변수 미리 채우기#

히스토리
  • GitLab 18.5에서 도입되었습니다.
Warning

이 기능은 GitLab 18.5 이전에 생성된 파이프라인 실행 정책에서는 동작하지 않습니다. 이전 파이프라인 실행 정책에서 이 기능을 사용하려면 다음 중 하나를 수행합니다.

  • 파이프라인 실행 정책의 기존 YAML 구성 파일을 아무거나 변경합니다.
  • 정책을 복사하고 삭제한 다음 다시 만듭니다.

자세한 내용은 파이프라인 실행 정책 재생성을 참고합니다.

description, value, options 키워드를 사용해 사용자가 수동으로 파이프라인을 실행할 때 미리 채워지는 CI/CD 변수를 정의할 수 있습니다. 설명에는 변수의 용도와 허용되는 값이 무엇인지 같은 관련 정보를 작성합니다.

job별 변수는 미리 채울 수 없습니다.

수동으로 트리거하는 파이프라인에서 New pipeline 페이지는 적용 가능한 모든 정책의 CI/CD 구성에서 description이 정의된 모든 파이프라인 변수를 표시합니다.

미리 채워진 변수는 variables_override를 사용해 허용하도록 구성해야 합니다. 그렇지 않으면 파이프라인을 수동으로 트리거할 때 사용한 값이 무시됩니다.

override_project_ci에서 미리 채워진 변수가 표시되지 않는 문제#

프로젝트에 override_project_ci 전략을 사용하는 파이프라인 실행 정책이 할당되면 New pipeline 페이지에 정책의 미리 채워진 변수가 표시되지 않을 수 있습니다. 이 문제는 프로젝트의 .gitlab-ci.yml 파일이 그 자체로는 유효한 CI/CD 구성이 아닐 때 발생합니다. 예를 들어 variables: 블록만 있고 job이 없는 파일은, GitLab이 미리 채워진 변수를 나열하려 할 때 jobs config should contain at least one visible job 오류를 반환합니다.

파이프라인을 생성할 때 정책이 빠진 job을 제공하므로 파이프라인 자체는 계속 올바르게 실행됩니다. 이 문제는 New pipeline 페이지의 미리 채워진 변수 표시에만 영향을 줍니다.

해결 방법으로, 프로젝트의 .gitlab-ci.yml 파일에 눈에 보이는 job을 추가하여 그 파일이 단독으로도 유효하게 만듭니다. 이 job에 when: never가 있는 rules: 절을 지정하면 파이프라인에 실제로 추가되지 않습니다.

variables:
  SOME_VAR: "value"

placeholder-job:
  script:
    - echo "Placeholder job that keeps this configuration valid on its own."
  rules:
    - when: never

구성에는 눈에 보이는 job이 하나 이상 있어야 하므로, 숨겨진 job(이름이 마침표로 시작하는 job)은 대체 수단으로 동작하지 않습니다.

프로젝트가 job을 제공하는 일을 정책에 의존하는 경우에만 이 해결 방법을 사용합니다. 정책이 어떤 브랜치에 적용되지 않으면, 유일한 job이 실행되지 않는 구성은 파이프라인을 생성하지 않습니다.

자세한 내용은 이슈 600124를 참고합니다.

파이프라인 실행 정책 재생성#

파이프라인 실행 정책을 재생성하려면 다음을 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Policies를 선택합니다.
  3. 재생성하려는 파이프라인 실행 정책을 선택합니다.
  4. 오른쪽 사이드바에서 YAML 탭을 선택하고 정책 파일 전체의 내용을 복사합니다.
  5. 정책 표 옆에서 세로 줄임표(⋮)를 선택한 다음 Delete를 선택합니다.
  6. 생성된 머지 리퀘스트를 머지합니다.
  7. Secure > Policies로 돌아가서 New policy를 선택합니다.
  8. Pipeline execution policy 섹션에서 Select policy를 선택합니다.
  9. .yaml mode에서 이전 정책의 내용을 붙여넣습니다.
  10. Update via merge request를 선택하고 생성된 머지 리퀘스트를 머지합니다.

보안상 중요한 정책의 실행 보장#

보안 및 컴플라이언스 목적으로 파이프라인 실행 정책을 구현할 때는 정책이 우회되거나 훼손되지 않도록 다음 모범 사례를 고려합니다.

보안상 중요한 job에서는 changes: 규칙 사용 피하기#

보안상 중요한 파이프라인 정책에서는 브랜치 파이프라인에서 예기치 않은 결과를 낼 수 있으므로 changes: 규칙 사용을 피합니다. changes: 키워드는 SHA 기반 diff에 의존하므로 git commit --amend 후 강제 푸시를 하는 경우처럼 특정 상황에서는 우회될 수 있습니다.

git commit --amend 후 강제 푸시를 하면 GitLab은 변경된 파일을 다르게 계산합니다.

  1. 첫 번째 푸시(표준 커밋):

    1. GitLab이 새 커밋을 부모 커밋과 비교합니다.
    2. GitLab이 대상 파일이 변경되었음을 감지합니다.
    3. changes: [filename] 규칙이 올바르게 트리거됩니다.
  2. 두 번째 푸시(--force를 사용한 amend 커밋):

    1. amend된 커밋이 이전 커밋을 새 SHA로 완전히 대체합니다.
    2. GitLab이 브랜치의 이전 커밋과 비교하는 git diff HEAD~로 변경 사항을 계산합니다.
    3. 브랜치의 이전 커밋에도 같은 파일 변경이 있었으므로 diff에는 새로운 변경 사항이 없는 것으로 나타납니다.
    4. changes: 규칙이 트리거되지 않습니다.

대신 우회할 수 없는 조건을 사용합니다.

check-critical-files:
  stage: .pipeline-policy-pre
  script:
    - |
      # Check if critical files differ from the target branch
      if git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --name-only | grep -q "Makefile\|\.gitlab-ci\.yml"; then
        echo "Critical files have been modified"
        exit 1
      fi
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always

또는 changes: 조건 없이 모든 파이프라인에서 정책 검사를 실행합니다.

security-check:
  stage: .pipeline-policy-pre
  script:
    - echo "Running security checks"
    - ./run-security-checks.sh
  rules:
    - when: always

changes: 동작에 대한 자세한 내용은 changes를 사용할 때 job 또는 파이프라인이 예기치 않게 실행됨을 참고합니다.

중요한 보안 검사에는 .pipeline-policy-pre stage 사용#

.pipeline-policy-pre stage의 job은 보안 및 컴플라이언스 사용 사례를 위해 설계되었습니다. 파이프라인의 다른 모든 job은 이 stage가 완료될 때까지 기다린 후에 시작됩니다. .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뜁니다.

중복된 보안 구성 감지#

.pipeline-policy-pre를 사용해 기존 보안 구성을 확인하고 안내를 제공하는 사용자 지정 검증 job을 만들 수 있습니다. 예를 들어 파이프라인 실행 정책으로 조직 전체에 보안 스캔을 강제하는데 일부 프로젝트에 이미 자체 보안 스캔 구현이 있는 경우, .pipeline-policy-pre를 사용해 중복된 스캔을 식별할 수 있습니다.

정책 CI/CD 구성 예시:

# policy-ci.yml
check-duplicate-scans:
  stage: .pipeline-policy-pre
  script:
    - |
      echo "Checking for duplicate security scan configurations..."
      if [ -f ".gitlab-ci.yml" ]; then
        if grep -q "secret_detection:" .gitlab-ci.yml || \
           grep -q "sast:" .gitlab-ci.yml || \
           grep -q "dependency_scanning:" .gitlab-ci.yml || \
           grep -q "container_scanning:" .gitlab-ci.yml; then
          echo "WARNING: Duplicate security scans detected."
          echo ""
          echo "This project has security scans defined in .gitlab-ci.yml"
          echo "that might duplicate the scans enforced by pipeline execution policies."
          echo ""
          echo "To avoid redundant scans and reduce pipeline time:"
          echo "1. Review your .gitlab-ci.yml for security scanning jobs."
          echo "2. Remove duplicate jobs (secret_detection, sast, dependency_scanning, and so on)."
          echo "3. The pipeline execution policy ensures these scans still run."
          echo ""
          echo "For questions, contact your security team."
        else
          echo "No duplicate security scans detected."
        fi
      fi
  allow_failure: true
  rules:
    - when: always

이 구성은 다음과 같습니다.

  • 파이프라인을 차단하지 않고 잠재적인 중복 구성을 감지합니다.
  • 개발 팀에 실행 가능한 안내를 제공합니다.
  • 정리가 필요한 프로젝트를 계속 파악할 수 있게 합니다.
  • 의도하지 않은 결과를 낳을 수 있는 job 자동 제거의 복잡성을 피합니다.

이 예시를 확장하여 다른 구성 문제를 확인하거나, 보안 팀이 프로젝트 전반의 컴플라이언스를 추적할 수 있도록 보고서를 생성할 수 있습니다.

변수 재정의 제어#

variables_override 구성을 사용하면 사용자가 보안 스캔을 비활성화하거나 중요한 보안 구성을 수정하는 방식으로 중요한 보안 변수를 재정의하지 못하게 할 수 있습니다.

variables_override:
  allowed: false
  exceptions:
    - CS_IMAGE  # Allow customization of container image only

안전한 job 이름 지정#

고유하고 설명적인 job 이름에 접두사를 붙이면 충돌을 방지하고, 해당 job이 보안 정책으로 강제된다는 점을 사용자에게 분명히 알릴 수 있습니다.

# Good: Clear security policy job name
security-policy:sast-scan:
  stage: .pipeline-policy-pre
  script: ...

# Avoid: Generic name that could conflict
sast:
  stage: .pipeline-policy-pre
  script: ...

[no_pipeline] 사용 시 동작#

기본적으로 일반 파이프라인이 생성되지 않게 하려면 사용자가 푸시 옵션에 [no_pipeline]을 넣어 보호된 브랜치에 커밋을 푸시할 수 있습니다. 그러나 파이프라인 실행 정책으로 정의된 job은 정책이 [no_pipeline] 지시문을 무시하므로 항상 트리거됩니다. 이렇게 하면 개발자가 정책에 정의된 job의 실행을 건너뛰는 일을 막아 중요한 보안 및 컴플라이언스 검사가 항상 수행되도록 보장합니다.

[no_pipeline] 동작을 더 유연하게 제어하려면 no_pipeline 유형 절을 참고합니다.

[skip ci] 사용 시 동작#

기본적으로 일반 파이프라인이 트리거되지 않게 하려면 사용자가 커밋 메시지에 [skip ci]를 넣어 보호된 브랜치에 커밋을 푸시할 수 있습니다. 그러나 파이프라인 실행 정책으로 정의된 job은 정책이 [skip ci] 지시문을 무시하므로 항상 트리거됩니다. 이렇게 하면 개발자가 정책에 정의된 job의 실행을 건너뛰는 일을 막아 중요한 보안 및 컴플라이언스 검사가 항상 수행되도록 보장합니다.

[skip ci] 동작을 더 유연하게 제어하려면 skip_ci 유형 절을 참고합니다.

예시#

다음 예시는 파이프라인 실행 정책으로 할 수 있는 일을 보여 줍니다.

파이프라인 실행 정책#

보안 정책 프로젝트에 저장된 .gitlab/security-policies/policy.yml 파일에서 다음 예시를 사용할 수 있습니다.

---
pipeline_execution_policy:
- name: My pipeline execution policy
  description: Enforces CI/CD jobs
  enabled: true
  pipeline_config_strategy: override_project_ci
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
      ref: main # optional
  policy_scope:
    projects:
      including:
      - id: 361

프로젝트 변수에 따라 강제되는 job 사용자 지정#

파이프라인 실행 정책은 프로젝트별 변수에 따라 동작을 조정합니다. 합리적인 기본값을 제공하면서 개별 프로젝트가 강제되는 job의 특정 부분을 사용자 지정할 수 있도록 허용하는 유연한 정책을 만들 수 있습니다.

변수 평가#

파이프라인 실행 정책의 규칙(예: if: $PROJECT_CS_IMAGE)은 프로젝트의 컨텍스트가 아니라 정책 실행 중에 평가됩니다. 이는 다음을 의미합니다.

  • 프로젝트 변수는 표준 이름(예: $PROJECT_CS_IMAGE)으로 정책에서 사용할 수 있습니다.
  • 프로젝트 변수가 정책에 정의된 변수보다 우선할 수 있습니다.
  • 어떤 변수를 사용할지에 대한 평가는 GitLab이 정책 파이프라인을 구성할 때 이루어집니다.

변수 이름 지정 패턴#

사용자 지정이 가능한 정책을 만들 때는 다음 이름 지정 규칙을 따릅니다.

  • 정책 변수: 기본값에는 표준 이름(예: CS_IMAGE)을 사용합니다.
  • 프로젝트 재정의 변수: 용도를 분명히 나타내도록 설명적인 접두사(예: PROJECT_CS_IMAGE)를 사용합니다.

이 패턴은 이름 충돌을 방지하고 의도를 분명하게 합니다.

예시: 이미지를 사용자 지정할 수 있는 컨테이너 스캔#

이 예시는 기본 컨테이너 이미지를 사용하되 프로젝트가 자체 이미지를 지정할 수 있도록 허용하는 정책을 만드는 방법을 보여 줍니다.

variables:
  CS_ANALYZER_IMAGE: "$CI_TEMPLATE_REGISTRY_HOST/security-products/container-scanning:8"
  CS_IMAGE: alpine:latest  # Default fallback value

policy::container-security:
  stage: .pipeline-policy-pre
  rules:
    - if: $PROJECT_CS_IMAGE  # Check if project defined a custom image
      variables:
        CS_IMAGE: $PROJECT_CS_IMAGE  # Use project's custom image
    - when: always  # Always run the job (with default or custom image)
  script:
    - echo "CS_ANALYZER_IMAGE:$CS_ANALYZER_IMAGE"
    - echo "CS_IMAGE:$CS_IMAGE"

동작 방식은 다음과 같습니다.

  1. 기본 동작: 프로젝트에 PROJECT_CS_IMAGE가 정의되어 있지 않으면 CS_IMAGE는 alpine:latest로 유지됩니다.
  2. 사용자 지정 동작: 프로젝트가 PROJECT_CS_IMAGE를 정의하면 그 값이 CS_IMAGE를 재정의합니다.
  3. 규칙 평가: if: $PROJECT_CS_IMAGE 조건은 정책 컨텍스트에서 평가되며 프로젝트 변수에 접근할 수 있습니다.
  4. 변수 우선순위: 정책의 변수 할당이 기본값보다 우선합니다.

컨테이너 이미지를 사용자 지정하려면 프로젝트에서 PROJECT_CS_IMAGE를 .gitlab-ci.yml 파일에 지정하지 말고 프로젝트 변수로 정의해야 합니다.

변수 고려 사항 요약#

변수 소스:

  • 프로젝트 변수는 .gitlab-ci.yml이 아니라 프로젝트의 CI/CD 설정에 정의해야 합니다.
  • 정책은 그룹 변수와 인스턴스 변수도 표준 이름으로 사용할 수 있습니다.
  • 정책 변수와 프로젝트 변수가 같은 이름으로 정의되어 있으면 정책 변수가 프로젝트 변수보다 우선합니다.

규칙 평가:

  • 파이프라인 실행 정책의 모든 rules: 조건은 정책이 실행될 때 평가됩니다. 즉, 정책은 프로젝트별 변수에 접근하고 그에 반응할 수 있습니다.
  • 평가는 어떤 job이든 실행되기 전인 파이프라인 구성 중에 이루어집니다.

모범 사례:

  • 프로젝트 재정의에는 접두사가 있는 설명적인 변수 이름(예: PROJECT_*)을 사용합니다.
  • 정책에 항상 합리적인 기본값을 제공합니다.
  • 사용자를 위해 사용할 수 있는 사용자 지정 변수를 문서화합니다.

.gitlab-ci.yml과 아티팩트를 사용해 강제되는 job 사용자 지정#

정책 파이프라인은 격리되어 실행되므로 파이프라인 실행 정책은 .gitlab-ci.yml의 변수를 직접 읽을 수 없습니다. 프로젝트의 CI/CD 구성에 변수를 정의하는 대신 .gitlab-ci.yml의 변수를 사용하려면, 아티팩트를 사용해 .gitlab-ci.yml 구성에서 파이프라인 실행 정책의 파이프라인으로 변수를 전달할 수 있습니다.

# .gitlab-ci.yml

build-job:
  stage: build
  script:
    - echo "BUILD_VARIABLE=value_from_build_job" >> build.env
  artifacts:
    reports:
      dotenv: build.env
stages:
- build
- test

test-job:
  stage: test
  script:
    - echo "$BUILD_VARIABLE" # Prints "value_from_build_job"

프로젝트 구성에서 before_script로 보안 스캐너의 동작 사용자 지정#

프로젝트의 .gitlab-ci.yml에서 정책이 강제하는 보안 job의 동작을 사용자 지정하려면 before_script를 재정의할 수 있습니다. 이렇게 하려면 정책에서 override_project_ci 전략을 사용하고 프로젝트의 CI/CD 구성을 포함합니다. 파이프라인 실행 정책 구성 예시:

# policy.yml
type: pipeline_execution_policy
name: Secret detection
description: >
  This policy enforces secret detection and allows projects to override the
  behavior of the scanner.
enabled: true
pipeline_config_strategy: override_project_ci
content:
  include:
    - project: gitlab-org/pipeline-execution-policies/compliance-project
      file: secret-detection.yml
# secret-detection.yml
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
  - template: Jobs/Secret-Detection.gitlab-ci.yml

프로젝트의 .gitlab-ci.yml에서 스캐너에 대한 before_script를 정의할 수 있습니다.

include:
  - template: Jobs/Secret-Detection.gitlab-ci.yml

secret_detection:
  before_script:
    - echo "Before secret detection"

override_project_ci를 사용하고 프로젝트의 구성을 포함하면 YAML 구성을 병합할 수 있습니다.

리소스별 변수 제어 구성#

팀이 파이프라인 실행 정책 변수를 재정의할 수 있는 전역 변수를 설정하도록 허용하면서, job별 재정의도 계속 허용할 수 있습니다. 이렇게 하면 팀이 보안 스캔에는 적절한 기본값을 설정하고 다른 job에는 적절한 리소스를 사용할 수 있습니다.

resource-optimized-scans.yml에 다음을 포함합니다.

variables:
  # Default resource settings for all jobs
  KUBERNETES_MEMORY_REQUEST: 4Gi
  KUBERNETES_MEMORY_LIMIT: 4Gi
  # Default values that teams can override via project variables
  SAST_KUBERNETES_MEMORY_REQUEST: 4Gi

sast:
  variables:
    SAST_EXCLUDED_ANALYZERS: 'spotbugs'
    KUBERNETES_MEMORY_REQUEST: $SAST_KUBERNETES_MEMORY_REQUEST
    KUBERNETES_MEMORY_LIMIT: $SAST_KUBERNETES_MEMORY_REQUEST

policy.yml에 다음을 포함합니다.

pipeline_execution_policy:
- name: Resource-Optimized Security Policy
  description: Enforces security scans with efficient resource management
  enabled: true
  pipeline_config_strategy: inject_ci
  content:
    include:
    - project: security/policy-templates
      file: resource-optimized-scans.yml
      ref: main

  variables_override:
    allowed: false
    exceptions:
      # Allow scan-specific resource overrides
      - SAST_KUBERNETES_MEMORY_REQUEST
      - SECRET_DETECTION_KUBERNETES_MEMORY_REQUEST
      - CS_KUBERNETES_MEMORY_REQUEST
      # Allow necessary scan customization
      - CS_IMAGE
      - SAST_EXCLUDED_PATHS

이 방식을 사용하면 팀이 파이프라인의 모든 job에 영향을 주지 않고 변수 재정의로 스캔별 리소스 변수(예: SAST_KUBERNETES_MEMORY_REQUEST)를 설정할 수 있으므로 대규모 프로젝트에서 더 나은 리소스 관리가 가능합니다. 이 예시는 개발자에게 확장해 줄 수 있는 다른 일반적인 스캔 사용자 지정 옵션의 사용도 함께 보여 줍니다. 개발 팀이 활용할 수 있도록 사용 가능한 변수를 반드시 문서화합니다.

파이프라인 실행 정책에서 그룹 또는 프로젝트 변수 사용#

파이프라인 실행 정책에서 그룹 또는 프로젝트 변수를 사용할 수 있습니다.

PROJECT_VAR="I'm a project"라는 프로젝트 변수가 있으면 다음 파이프라인 실행 정책 job의 결과는 I'm a project입니다.

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

프로젝트 구성의 변수를 파이프라인 실행 정책에 포함#

파이프라인 실행 정책은 자체의 격리된 컨텍스트에서 실행되므로 프로젝트의 .gitlab-ci.yml 파일에 정의된 변수는 정책 job에서 자동으로 사용할 수 없습니다. 하지만 프로젝트에 있는 별도의 변수 파일을 참조하면 프로젝트에서 정의한 변수를 포함할 수 있습니다.

이 방식은 다음과 같은 경우에 사용합니다.

  • Docker 컨테이너에 사용자 지정 이름 지정 규칙을 사용해야 하는 경우.
  • 정책이 존중해야 하는 프로젝트별 구성을 유지하려는 경우.
  • 이름은 다르지만 같은 프로젝트에서 빌드된 컨테이너가 여러 개 있는 경우.

예시: 프로젝트 변수 파일 포함#

프로젝트 리포지터리에 변수 파일을 만듭니다(예: gitlab-variables.yml).

# gitlab-variables.yml
variables:
  DOCKER_TLS_CERTDIR: "/certs"
  CS_IMAGE: ${CI_REGISTRY_IMAGE}:build
  CUSTOM_VARIABLE: "custom-value"

파이프라인 실행 정책 구성에서 이 변수 파일을 포함합니다.

# Pipeline execution policy configuration
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: 'gitlab-variables.yml'
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  stage: test
  before_script:
    - echo "CS_IMAGE = $CS_IMAGE"
    - echo "CUSTOM_VARIABLE = $CUSTOM_VARIABLE"

이 구성은 다음과 같습니다.

  1. 스캔 대상 프로젝트의 gitlab-variables.yml 파일을 포함합니다.
  2. 해당 파일에 정의된 변수를 정책 job에서 사용할 수 있게 합니다.
  3. 일관된 정책 구조를 유지하면서 각 프로젝트가 자체 변수 값을 정의할 수 있게 합니다.

중요한 고려 사항#

  • 변수 우선순위: 프로젝트 파일에서 포함한 변수는 파이프라인 실행 정책의 표준 변수 우선순위 규칙을 따릅니다.
  • 파일 위치: 변수 파일은 프로젝트 리포지터리의 어느 위치에나 둘 수 있습니다. 찾고 유지 관리하기 쉽도록 설명적인 이름과 위치를 사용합니다.
  • 전체 CI/CD 구성 포함 지양: 이 방식을 사용할 때는 전체 .gitlab-ci.yml이 아니라 변수 파일만 포함합니다. 전체 CI/CD 구성을 포함하면 job이 중복될 수 있습니다.
  • 보안: 변수 파일에 민감한 정보를 저장하지 마십시오. 민감한 데이터에는 프로젝트 또는 그룹 설정에 정의한 CI/CD 변수를 사용합니다.

대안: 프로젝트 CI/CD 설정 사용#

동적으로 설정되는 변수가 필요하지 않다면 별도 파일을 사용하는 대신 프로젝트의 CI/CD 설정(Settings > CI/CD > Variables)에서 상수를 설정할 수 있습니다. 이러한 변수는 추가 구성 없이 파이프라인 실행 정책 job에서 자동으로 사용할 수 있습니다.

파이프라인 실행 정책으로 변수 값 강제#

파이프라인 실행 정책에 정의된 변수의 값은 이름이 같은 그룹 또는 정책 변수의 값을 재정의합니다. 이 예시에서는 프로젝트의 변수 PROJECT_VAR 값이 덮어쓰여 job의 결과가 I'm a pipeline execution policy가 됩니다.

variables:
  PROJECT_VAR: "I'm a pipeline execution policy"

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

보안 정책 범위가 포함된 policy.yml 예시#

이 예시에서 보안 정책의 policy_scope는 다음과 같습니다.

  • ID가 9인 컴플라이언스 프레임워크가 적용된 모든 프로젝트를 포함합니다.
  • ID가 456인 프로젝트를 제외합니다.
pipeline_execution_policy:
- name: Pipeline execution policy
  description: ''
  enabled: true
  pipeline_config_strategy: inject_policy
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
  policy_scope:
    compliance_frameworks:
    - id: 9
    projects:
      excluding:
      - id: 456

파이프라인 실행 정책에서 ci_skip 구성#

다음 예시에서는 파이프라인 실행 정책이 강제되며, ID가 75인 사용자를 제외하고는 CI 건너뛰기가 허용되지 않습니다.

pipeline_execution_policy:
  - name: My pipeline execution policy with ci.skip exceptions
    description: 'Enforces CI/CD jobs'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: group-a/project1
          file: README.md
    skip_ci:
      allowed: false
      allowlist:
        users:
          - id: 75

파이프라인 실행 정책에서 ci_no_pipeline 구성#

다음 예시에서는 파이프라인 실행 정책이 강제되며, ID가 75인 사용자를 제외하고는 CI 생성 안 함이 허용되지 않습니다.

pipeline_execution_policy:
  - name: My pipeline execution policy with ci.no_pipeline exceptions
    description: 'Enforces CI/CD jobs'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: group-a/project1
          file: README.md
    no_pipeline:
      allowed: false
      allowlist:
        users:
          - id: 75

exists 조건 구성#

exists 규칙을 사용하면 특정 파일이 존재할 때 프로젝트의 CI/CD 구성 파일을 포함하도록 파이프라인 실행 정책을 구성할 수 있습니다.

다음 예시에서 파이프라인 실행 정책은 Dockerfile이 있으면 프로젝트의 CI/CD 구성을 포함합니다. exists 규칙의 project에는 반드시 '$CI_PROJECT_PATH'를 사용하도록 설정해야 합니다. 그렇지 않으면 GitLab은 보안 정책 CI/CD 구성을 보관하는 프로젝트에서 파일이 존재하는지를 평가합니다.

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
    rules:
      - exists:
          paths:
            - 'Dockerfile'
          project: '$CI_PROJECT_PATH'

이 방식을 사용하려면 그룹 또는 프로젝트가 override_project_ci 전략을 사용해야 합니다.

CI_JOB_TOKEN으로 파이프라인 stage와 job 검증#

.pipeline-policy-pre job에서 CI_JOB_TOKEN을 사용해 GitLab API를 호출하고, 파이프라인의 stage와 job이 승인된 stage 또는 job 목록에 있는지 검증할 수 있습니다. 이 패턴은 프로젝트가 승인되지 않은 CI/CD stage와 job을 사용하지 못하게 하려는 경우에 유용합니다.

다음 예시 스크립트는 API에서 파이프라인의 job을 가져와 고유한 stage와 job 이름을 추출하고, 각각을 APPROVED_STAGES와 APPROVED_JOBS 변수와 대조합니다. 승인되지 않은 stage나 job이 발견되면 다른 job이 실행되기 전에 파이프라인이 실패합니다.

APPROVED_STAGES와 APPROVED_JOBS는 프로젝트, 그룹 또는 정책 구성에서 CI/CD 변수로 정의합니다.

validate-pipeline:
  stage: .pipeline-policy-pre
  image: alpine:latest
  before_script:
    - apk add --no-cache curl jq bash
  script:
    - |
      #!/bin/bash

      echo "Checking pipeline stages and jobs..."

      # Fetch pipeline jobs using CI_JOB_TOKEN
      api_url="$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$CI_PIPELINE_ID/jobs"
      echo "API URL: $api_url"

      jobs=$(curl --silent --header "JOB-TOKEN: $CI_JOB_TOKEN" "$api_url")
      echo "Fetched Jobs: $jobs"

      if [[ "$jobs" == *"404 Project Not Found"* ]]; then
        echo "Failed to authenticate with GitLab API: Project not found"
        exit 1
      fi

      # Extract stages and jobs
      pipeline_stages=$(echo "$jobs" | jq -r '.[].stage' | sort | uniq | tr '\n' ',')
      pipeline_jobs=$(echo "$jobs" | jq -r '.[].name' | sort | uniq | tr '\n' ',')

      echo "Pipeline Stages: $pipeline_stages"
      echo "Pipeline Jobs: $pipeline_jobs"

      # Check if pipeline stages are approved
      for stage in $(echo $pipeline_stages | tr ',' ' '); do
        echo "Checking stage: $stage"
        if ! [[ ",$APPROVED_STAGES," =~ ",$stage," ]]; then
          echo "Stage $stage is not approved."
          exit 1
        fi
      done

      # Check if pipeline jobs are approved
      for job in $(echo $pipeline_jobs | tr ',' ' '); do
        echo "Checking job: $job"
        if ! [[ ",$APPROVED_JOBS," =~ ",$job," ]]; then
          echo "Job $job is not approved."
          exit 1
        fi
      done

파이프라인 실행 정책으로 컨테이너 스캔 component 강제#

보안 스캔 컴포넌트를 사용하면 버전 관리의 처리와 강제를 개선할 수 있습니다.

include:
  - component: gitlab.com/components/container-scanning/container-scanning@main
    inputs:
      cs_image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

container_scanning: # override component with additional configuration
  variables:
    CS_REGISTRY_USER: $CI_REGISTRY_USER
    CS_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
    SECURE_LOG_LEVEL: debug # add for verbose debugging of the container scanner
  before_script:
  - echo $CS_IMAGE # optionally add a before_script for additional debugging

파이프라인 실행 정책

GitLab v19.4
Tier: Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기

요약

파이프라인 실행 정책을 사용하면 하나의 구성으로 여러 프로젝트의 CI/CD job을 관리하고 강제할 수 있습니다. 같은 프로젝트에 있는 기존 컴플라이언스 파이프라인을 마이그레이션하기 전에는 파이프라인 실행 정책을 활성화하지 마십시오.

히스토리
  • GitLab 17.2에서 pipeline_execution_policy_type이라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 17.3에서 정식 출시되었습니다. 기능 플래그 pipeline_execution_policy_type이 제거되었습니다.

파이프라인 실행 정책을 사용하면 하나의 구성으로 여러 프로젝트의 CI/CD job을 관리하고 강제할 수 있습니다.

Warning

같은 프로젝트에 있는 기존 컴플라이언스 파이프라인을 마이그레이션하기 전에는 파이프라인 실행 정책을 활성화하지 마십시오. 둘 다 구성되어 있으면 컴플라이언스 파이프라인이 표준 프로젝트 파이프라인을 대체하지만, 파이프라인 실행 정책은 원래의 프로젝트 파이프라인을 기준으로 적용됩니다. 이 때문에 파이프라인 실행 정책 전략과 CI/CD 구성에 따라 동작을 예측할 수 없게 되며, job이 중복되거나 파이프라인이 실패하거나 중요한 보안 및 컴플라이언스 검사가 누락될 수 있습니다. 컴플라이언스 파이프라인은 더 이상 사용되지 않습니다. 기존 컴플라이언스 파이프라인은 가능한 한 빨리 마이그레이션하고, 모든 신규 구현에는 파이프라인 실행 정책을 사용해야 합니다.

스키마#

히스토리
  • GitLab 17.4에서 suffix 필드가 활성화되었습니다.
  • GitLab 17.7에서 이후 stage가 .pipeline-policy-pre stage의 완료를 기다리도록 파이프라인 실행 방식이 변경되었습니다.
  • GitLab 18.10에서 .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뛰도록 파이프라인 실행 방식이 변경되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 19.0에서 새 파이프라인 실행 방식이 정식 출시되었습니다. 기능 플래그 ensure_pipeline_policy_pre_succeeds가 제거되었습니다.

파이프라인 실행 정책이 담긴 YAML 파일은 pipeline_execution_policy 키 아래에 중첩된, 파이프라인 실행 정책 스키마와 일치하는 객체 배열로 구성됩니다. 보안 정책 프로젝트당 pipeline_execution_policy 키 아래에 최대 5개의 정책을 구성할 수 있습니다. 처음 5개 이후에 구성한 정책은 적용되지 않습니다.

새 정책을 저장하면 GitLab이 이 JSON 스키마에 대해 내용을 검증합니다. JSON 스키마를 읽는 방법에 익숙하지 않다면 다음 절과 표를 대신 참고할 수 있습니다.

필드 유형 필수 설명
pipeline_execution_policy array of pipeline execution policy true 파이프라인 실행 정책 목록 (최대 5개)

pipeline_execution_policy 스키마#

필드 유형 필수 설명
name string true 정책 이름. 최대 255자입니다.
description (선택 사항) string true 정책 설명.
enabled boolean true 정책을 활성화(true)하거나 비활성화(false)하는 플래그.
content object of content true 프로젝트 파이프라인에 주입할 CI/CD 구성에 대한 참조.
pipeline_config_strategy string false inject_policy, inject_ci(더 이상 사용되지 않음), override_project_ci 중 하나일 수 있습니다. 자세한 내용은 파이프라인 전략을 참고합니다.
policy_scope object of policy_scope false 지정한 프로젝트, 그룹 또는 컴플라이언스 프레임워크 레이블을 기준으로 정책의 범위를 지정합니다.
suffix string false on_conflict(기본값) 또는 never일 수 있습니다. job 이름 충돌을 처리하는 동작을 정의합니다. on_conflict는 고유성을 깨뜨리는 job의 이름에 고유한 접미사를 붙입니다. never는 프로젝트와 적용 가능한 모든 정책에 걸쳐 job 이름이 고유하지 않으면 파이프라인을 실패시킵니다.
skip_ci object of skip_ci false 사용자가 skip-ci 지시문을 적용할 수 있는지 여부를 정의합니다. 기본적으로 skip-ci 사용은 무시되며, 그 결과 파이프라인 실행 정책이 적용된 파이프라인은 건너뛸 수 없습니다.
no_pipeline object of no_pipeline false 사용자가 no_pipeline 지시문을 적용할 수 있는지 여부를 정의합니다. 기본적으로 no_pipeline 사용은 무시되며, 그 결과 파이프라인 실행 정책이 적용된 파이프라인은 생성되지 않도록 막을 수 없습니다.
variables_override object of variables_override false 사용자가 정책이 생성한 job에서 정책 변수의 동작을 재정의할 수 있는지 제어합니다. 기본적으로 정책 변수는 가장 높은 우선순위로 강제되며 사용자가 재정의할 수 없습니다.

다음 사항에 유의합니다.

  • 파이프라인을 트리거하는 사용자는 파이프라인 실행 정책에 지정된 파이프라인 실행 파일에 대해 최소한 읽기 권한이 있어야 합니다. 그렇지 않으면 파이프라인이 시작되지 않습니다.
  • 파이프라인 실행 파일이 삭제되거나 이름이 바뀌면 해당 정책이 적용된 프로젝트의 파이프라인이 동작하지 않을 수 있습니다.
  • 파이프라인 실행 정책 job은 예약된 두 stage 중 하나에 할당할 수 있습니다.
    • .pipeline-policy-pre: 파이프라인의 시작 부분에 있으며 .pre stage보다 앞에 위치합니다.
    • .pipeline-policy-post: 파이프라인의 맨 끝에 있으며 .post stage 뒤에 위치합니다.
  • 예약된 stage에 job을 주입하는 것은 항상 동작하도록 보장됩니다. 실행 정책 job은 표준 stage(build, test, deploy)나 사용자가 선언한 stage에도 할당할 수 있습니다. 다만 이 경우 프로젝트 파이프라인 구성에 따라 job이 무시될 수 있습니다.
  • 파이프라인 실행 정책 밖에서는 job을 예약된 stage에 할당할 수 없습니다.
  • 파이프라인 실행 정책에는 고유한 job 이름을 선택합니다. 일부 CI/CD 구성은 job 이름을 기준으로 동작하므로, 같은 파이프라인에 같은 이름의 job이 여러 개 있으면 원치 않는 결과가 생길 수 있습니다. 예를 들어 needs 키워드는 한 job이 다른 job에 의존하도록 만듭니다. 이름이 example인 job이 여러 개 있으면, example job 이름을 needs하는 job은 example job 인스턴스 중 하나에만 무작위로 의존합니다.
  • 프로젝트에 CI/CD 구성 파일이 없어도 파이프라인 실행 정책은 계속 유효합니다.
  • 적용되는 접미사에는 정책의 순서가 영향을 줍니다.
  • 특정 프로젝트에 적용된 정책 중 하나라도 suffix: never이면, 파이프라인에 이름이 같은 다른 job이 이미 있을 때 파이프라인이 실패합니다.
  • 파이프라인 실행 정책은 모든 브랜치와 파이프라인 소스에 강제됩니다. 다만 머지 리퀘스트 파이프라인에서는 일부 rules: 또는 workflow:rules 구성이 job 실행을 막을 수 있습니다. 파이프라인 실행 정책이 강제되는 시점을 제어하려면 workflow 규칙을 사용합니다.

보안 정책 파이프라인 검사#

히스토리

프로젝트에 파이프라인 실행 정책이나 스캔 실행 정책이 구성되어 있으면, 보안 정책 파이프라인 검사는 머지 리퀘스트를 머지하기 전에 최신 커밋의 모든 파이프라인이 성공하도록 요구합니다. 이 검사는 보안 정책이 만든 파이프라인만이 아니라 해당 커밋 때문에 실행되는 모든 파이프라인에 적용됩니다.

보안 정책 파이프라인 검사는 머지 리퀘스트 파이프라인은 통과했지만 다른 파이프라인(예: 보안 정책이 만든 브랜치 파이프라인)이 실패한 경우 머지를 막습니다. 이런 검사가 없으면 검증되지 않은 코드가 머지될 수 있습니다.

보안 정책 파이프라인 검사는 다음과 같이 동작합니다.

  • 프로젝트 설정 Pipelines must succeed가 활성화되어 있으면, 파이프라인 실패는 머지를 막는 강한 차단으로 이어집니다.
  • Pipelines must succeed가 활성화되어 있지 않으면, 파이프라인 실패는 경고로 표시됩니다. 머지 리퀘스트는 여전히 자동 머지로 설정할 수 있습니다.
  • 프로젝트 설정 Skipped pipelines are considered successful가 활성화되어 있으면, 건너뛴 파이프라인은 통과한 것으로 취급됩니다.
Warning

프로젝트를 마이그레이션하면 가져온 파이프라인이 원본의 상태를 그대로 유지하므로, 다시 실행하지 않고도 대상 인스턴스에서 보안 정책 파이프라인 검사를 충족할 수 있습니다. 가져온 머지 리퀘스트는 머지하기 전에 새 파이프라인을 실행합니다.

.pipeline-policy-pre stage#

히스토리
  • GitLab 18.10에서 .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뛰도록 파이프라인 실행 방식이 변경되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 19.0에서 새 파이프라인 실행 방식이 정식 출시되었습니다. 기능 플래그 ensure_pipeline_policy_pre_succeeds가 제거되었습니다.

.pipeline-policy-pre stage의 job은 항상 실행됩니다. 이 stage는 보안 및 컴플라이언스 사용 사례를 위해 설계되었습니다. 파이프라인의 job은 .pipeline-policy-pre stage가 완료될 때까지 시작되지 않습니다.

.pipeline-policy-pre stage가 실패하거나 이 stage의 모든 job을 건너뛰면, 다음을 포함해 이후 stage의 모든 job을 건너뜁니다.

  • needs: []가 있는 job.
  • when: always가 있는 job.

워크플로에서 이 동작이 필요하지 않다면 대신 .pre stage나 사용자 지정 stage를 사용합니다.

Note

GitLab 18.9 이전 버전에서는 needs: [] 또는 when: always가 있는 job이 실패한 .pipeline-policy-pre stage를 우회할 수 있었습니다. 이 동작은 GitLab 18.10에서 기본값이 되었고 GitLab 19.0부터 영구 적용됩니다.

Job 이름 모범 사례#

히스토리
  • GitLab 17.4에서 이름 충돌 처리가 도입되었습니다.

job이 보안 정책으로 생성되었음을 나타내는 표시는 눈에 보이지 않습니다. 정책이 만든 job을 쉽게 식별하고 job 이름 충돌을 피하려면 job 이름에 고유한 접두사나 접미사를 추가합니다.

예시:

  • 사용: policy1:deployments:sast. 이 이름은 다른 모든 정책과 프로젝트에서 고유할 가능성이 높습니다.
  • 사용하지 않음: sast. 이 이름은 다른 정책과 프로젝트에서 중복될 가능성이 높습니다.

파이프라인 실행 정책은 suffix 속성에 따라 이름 충돌을 처리합니다. 이름이 같은 job이 여러 개 있는 경우는 다음과 같습니다.

  • on_conflict(기본값)를 사용하면, job 이름이 파이프라인의 다른 job과 충돌할 때 해당 job에 접미사가 추가됩니다.
  • never를 사용하면, 충돌이 발생해도 접미사가 추가되지 않고 파이프라인이 실패합니다.

접미사는 job이 메인 파이프라인에 병합되는 순서에 따라 추가됩니다.

순서는 다음과 같습니다.

  1. 프로젝트 파이프라인 job
  2. 프로젝트 정책 job (해당하는 경우)
  3. 그룹 정책 job (해당하는 경우, 계층 구조 순으로 정렬되며 최상위 그룹이 마지막에 적용됨)

적용되는 접미사의 형식은 다음과 같습니다.

:policy-<security-policy-project-id>-<policy-index>.

결과 job의 예: sast:policy-123456-0.

하나의 보안 정책 프로젝트에서 여러 정책이 같은 job 이름을 정의하면, 숫자 접미사는 충돌하는 정책의 인덱스에 해당합니다.

결과 job의 예:

  • sast:policy-123456-0
  • sast:policy-123456-1

Job stage 모범 사례#

파이프라인 실행 정책에 정의된 job은 프로젝트의 CI/CD 구성에 정의된 모든 stage와 예약된 stage인 .pipeline-policy-pre, .pipeline-policy-post를 사용할 수 있습니다.

Note

정책에 .pre와 .post stage의 job만 있으면 정책의 파이프라인은 empty로 평가됩니다. 이 경우 프로젝트의 파이프라인에 병합되지 않습니다.

파이프라인 실행 정책에서 .pre와 .post stage를 사용하려면 다른 stage에서 실행되는 job을 하나 이상 포함해야 합니다. 예: .pipeline-policy-pre.

inject_policy 파이프라인 전략을 사용할 때 대상 프로젝트에 자체 .gitlab-ci.yml 파일이 없으면 모든 정책 stage가 파이프라인에 주입됩니다.

(더 이상 사용되지 않는) inject_ci 파이프라인 전략을 사용할 때 대상 프로젝트에 자체 .gitlab-ci.yml 파일이 없으면 사용할 수 있는 stage는 기본 파이프라인 stage와 예약된 stage뿐입니다.

수정할 권한이 없는 CI/CD 구성이 있는 프로젝트에 파이프라인 실행 정책을 강제할 때는 .pipeline-policy-pre와 .pipeline-policy-post stage에 job을 정의해야 합니다. 이 stage는 프로젝트의 CI/CD 구성과 관계없이 항상 사용할 수 있습니다.

여러 파이프라인 실행 정책과 사용자 지정 stage에 override_project_ci 파이프라인 전략을 함께 사용하면, 서로 호환되도록 stage를 같은 상대적 순서로 정의해야 합니다.

유효한 구성 예시:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [test, deploy]

유효하지 않은 구성 예시:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [deploy, test]

override_project_ci 정책 중 하나 이상의 stages 구성이 유효하지 않으면 파이프라인이 실패합니다.

content 유형#

필드 유형 필수 설명
project string true 같은 GitLab 인스턴스에 있는 프로젝트의 전체 GitLab 프로젝트 경로.
file string true 루트 디렉터리(/)를 기준으로 한 전체 파일 경로. YAML 파일의 확장자는 .yml 또는 .yaml이어야 합니다.
ref string false 파일을 가져올 ref. 지정하지 않으면 프로젝트의 HEAD가 기본값입니다.

정책에서 content 유형을 사용하면 다른 리포지터리에 저장된 CI/CD 구성을 참조할 수 있습니다. 따라서 여러 정책에서 같은 CI/CD 구성을 재사용할 수 있어 이러한 구성을 유지 관리하는 부담이 줄어듭니다. 예를 들어 정책 A와 정책 B에 강제하려는 사용자 지정 시크릿 탐지 CI/CD 구성이 있다면, YAML 구성 파일을 하나만 만들고 두 정책에서 그 구성을 참조하면 됩니다.

사전 요구 사항:

  • content 유형이 포함된 정책이 강제되는 프로젝트에서 파이프라인을 실행하는 사용자는 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다.

  • 파이프라인 실행 정책을 강제하는 프로젝트에서, 사용자가 파이프라인을 트리거하려면 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다.

    GitLab 17.4 이상에서는 content 유형을 사용해 보안 정책 프로젝트에 지정된 CI/CD 구성 파일에 필요한 읽기 전용 접근 권한을 부여할 수 있습니다. 이렇게 하려면 보안 정책 프로젝트의 일반 설정에서 Pipeline execution policies 설정을 활성화합니다. 이 설정을 활성화하면 파이프라인을 트리거한 사용자가 파이프라인 실행 정책이 강제하는 CI/CD 구성 파일을 읽을 수 있습니다. 이 설정은 구성 파일이 저장된 프로젝트의 다른 부분에는 사용자에게 접근 권한을 부여하지 않습니다. 자세한 내용은 접근 권한 자동 부여를 참고합니다.

skip_ci 유형#

히스토리
  • GitLab 17.7에서 도입되었습니다.

파이프라인 실행 정책으로 [skip ci] 지시문을 사용할 수 있는 사용자를 제어할 수 있습니다. 중요한 보안 및 컴플라이언스 검사는 계속 수행되도록 하면서, 특정 사용자나 서비스 계정에만 [skip ci] 사용을 허용할 수 있습니다.

skip_ci 키워드를 사용해 사용자가 skip_ci 지시문을 적용해 파이프라인을 건너뛸 수 있는지 지정합니다. 이 키워드를 지정하지 않으면 skip_ci 지시문은 무시되어 모든 사용자가 파이프라인 실행 정책을 우회할 수 없습니다.

필드 유형 가능한 값 설명
allowed boolean true, false 파이프라인 실행 정책이 강제되는 파이프라인에서 skip-ci 지시문 사용을 허용(true)하거나 금지(false)하는 플래그.
allowlist object users allowed 플래그와 관계없이 항상 skip-ci 지시문을 사용할 수 있는 사용자를 지정합니다. users: 다음에 사용자 ID를 나타내는 id 키를 가진 객체 배열을 사용합니다.

no_pipeline 유형#

파이프라인 실행 정책으로 [no_pipeline] 지시문을 사용할 수 있는 사용자를 제어할 수 있습니다. 중요한 보안 및 컴플라이언스 검사는 계속 수행되도록 하면서, 특정 사용자나 서비스 계정에만 [no_pipeline] 사용을 허용할 수 있습니다.

no_pipeline 키워드를 사용해 사용자가 no_pipeline 지시문을 적용해 파이프라인을 생성하지 않을 수 있는지 지정합니다. 이 키워드를 지정하지 않으면 no_pipeline 지시문은 무시되어 모든 사용자가 파이프라인 실행 정책을 우회할 수 없습니다.

필드 유형 가능한 값 설명
allowed boolean true, false 파이프라인 실행 정책이 강제되는 파이프라인에서 no_pipeline 지시문 사용을 허용(true)하거나 금지(false)하는 플래그.
allowlist object users allowed 플래그와 관계없이 항상 no_pipeline 지시문을 사용할 수 있는 사용자를 지정합니다. users: 다음에 사용자 ID를 나타내는 id 키를 가진 객체 배열을 사용합니다.

variables_override 유형#

히스토리
  • GitLab 18.1에서 도입되었습니다.
필드 유형 가능한 값 설명
allowed boolean true, false true이면 다른 구성이 정책 변수를 재정의할 수 있습니다. false이면 다른 구성이 정책 변수를 재정의할 수 없습니다.
exceptions array array of string 전역 규칙의 예외가 되는 변수. allowed: false일 때 exceptions는 허용 목록입니다. allowed: true일 때 exceptions는 거부 목록입니다.
dotenv string respect_policy, allow_override dotenv 아티팩트 변수가 variables_override 정책 규칙을 따르는지 제어합니다. 기본적으로(지정하지 않았거나 respect_policy로 설정한 경우) dotenv 변수는 다른 변수와 같은 재정의 규칙을 적용받습니다. dotenv 변수가 정책 규칙을 우회하도록 하려면 allow_override로 설정합니다. 이 옵션은 dotenv 아티팩트가 정책 변수를 재정의하는 데 의존하는 워크플로와의 하위 호환성을 위해 제공됩니다. allow_override를 사용하면 variables_override가 제공하는 보안 보장이 약해지므로 권장하지 않습니다.

이 옵션은 정책이 강제되는 파이프라인에서 사용자 정의 변수를 처리하는 방식을 제어합니다. 이 기능으로 다음을 할 수 있습니다.

  • 기본적으로 사용자 정의 변수를 거부합니다(권장). 보안이 더 강력하지만, 사용자가 변경할 수 있어야 하는 모든 변수를 exceptions 허용 목록에 추가해야 합니다.
  • 기본적으로 사용자 정의 변수를 허용합니다. 유연성은 더 높지만 보안은 낮아집니다. 정책 강제에 영향을 줄 수 있는 변수를 exceptions 거부 목록에 추가해야 하기 때문입니다.
  • allowed 전역 규칙에 대한 예외를 정의합니다.

사용자 정의 변수는 파이프라인에 있는 모든 정책 job의 동작에 영향을 줄 수 있으며 다양한 소스에서 올 수 있습니다.

variables_override 옵션을 지정하지 않으면 "가장 높은 우선순위" 동작이 유지됩니다. 이 동작에 대한 자세한 내용은 파이프라인 실행 정책의 변수 우선순위를 참고합니다.

파이프라인 실행 정책이 변수 우선순위를 제어하면 job 로그에 구성된 variables_override 옵션과 정책 이름이 포함됩니다. 이 로그를 보려면 gitlab-runner를 버전 18.1 이상으로 업데이트해야 합니다.

variables_override 구성 예시#

파이프라인 실행 정책 구성에 variables_override 옵션을 추가합니다.

pipeline_execution_policy:
  - name: Security Scans
    description: 'Enforce security scanning'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: gitlab-org/security-policies
          file: security-scans.yml
    variables_override:
      allowed: false
      exceptions:
        - CS_IMAGE
        - SAST_EXCLUDED_ANALYZERS
컨테이너 사용자 지정은 허용하면서 보안 스캔 강제 (허용 목록 방식)#

보안 스캔은 강제하되 프로젝트 팀이 자체 컨테이너 이미지를 지정하도록 허용하려면 다음과 같이 합니다.

variables_override:
  allowed: false
  exceptions:
    - CS_IMAGE

이 구성은 CS_IMAGE를 제외한 모든 사용자 정의 변수를 차단하므로, 보안 스캔을 비활성화할 수 없도록 보장하면서 팀이 컨테이너 이미지를 사용자 지정할 수 있게 합니다.

특정 보안 변수의 재정의 방지 (거부 목록 방식)#

대부분의 변수는 허용하되 보안 스캔의 비활성화를 막으려면 다음과 같이 합니다.

variables_override:
  allowed: true
  exceptions:
    - SECRET_DETECTION_DISABLED
    - SAST_DISABLED
    - DEPENDENCY_SCANNING_DISABLED
    - DAST_DISABLED
    - CONTAINER_SCANNING_DISABLED

이 구성은 보안 스캔을 비활성화할 수 있는 변수를 제외한 모든 사용자 정의 변수를 허용합니다.

Warning

이 구성은 유연성을 제공할 수 있지만 보안상의 영향 때문에 권장하지 않습니다. exceptions에 명시적으로 나열되지 않은 변수는 모두 사용자가 주입할 수 있습니다. 그 결과 정책 구성은 allowlist 방식을 사용할 때만큼 잘 보호되지 않습니다.

policy scope 스키마#

정책 강제를 사용자 지정하려면 정책의 범위를 정의하여 지정한 프로젝트, 그룹 또는 컴플라이언스 프레임워크 레이블을 포함하거나 제외할 수 있습니다. 자세한 내용은 범위를 참고합니다.

Note

policy_scope 필드를 빈 컬렉션(예: including: [])으로 설정하면 해당 필드를 생략한 것과 같게 취급되므로, 정책이 해당 범위 차원의 모든 프로젝트에 적용됩니다. 정책을 완전히 비활성화하려면 enabled: false를 사용합니다. 자세한 내용은 policy_scope의 빈 컬렉션을 참고합니다.

CI/CD 구성에 대한 접근 관리#

프로젝트에 파이프라인 실행 정책을 강제하면, 파이프라인을 트리거하는 사용자는 정책 CI/CD 구성이 있는 프로젝트에 최소한 읽기 전용 접근 권한이 있어야 합니다. 프로젝트 접근 권한은 수동 또는 자동으로 부여할 수 있습니다.

접근 권한 수동 부여#

사용자나 그룹이 파이프라인 실행 정책이 강제되는 파이프라인을 실행할 수 있게 하려면, 정책 CI/CD 구성이 있는 프로젝트에 해당 사용자나 그룹을 초대할 수 있습니다.

접근 권한 자동 부여#

파이프라인 실행 정책이 강제되는 프로젝트에서 파이프라인을 실행하는 모든 사용자에게 정책 CI/CD 구성에 대한 접근 권한을 자동으로 부여할 수 있습니다.

사전 요구 사항:

  • 파이프라인 실행 정책 CI/CD 구성이 보안 정책 프로젝트에 저장되어 있는지 확인합니다.
  • 보안 정책 프로젝트의 일반 설정에서 Pipeline execution policies 설정을 활성화합니다.

보안 정책 프로젝트가 아직 없고 첫 번째 파이프라인 실행 정책을 만들려면, 빈 프로젝트를 만들어 보안 정책 프로젝트로 연결합니다. 프로젝트를 연결하려면 다음을 수행합니다.

  1. 정책을 강제하려는 그룹 또는 프로젝트에서 Secure > Policies > Edit policy project를 선택합니다.
  2. 보안 정책 프로젝트를 선택합니다.

이 프로젝트가 보안 정책 프로젝트가 되고 해당 설정을 사용할 수 있게 됩니다.

Note

$CI_JOB_TOKEN을 사용해 다운스트림 파이프라인을 만들려면 프로젝트와 그룹이 보안 정책 프로젝트를 요청할 수 있도록 승인되어 있는지 확인해야 합니다. 보안 정책 프로젝트에서 Settings > CI/CD > Job token permissions로 이동하여 승인된 그룹과 프로젝트를 허용 목록에 추가합니다. CI/CD 설정이 보이지 않으면 Settings > General > Visibility, project features, permissions로 이동하여 CI/CD를 활성화합니다.

구성#

  1. 정책 프로젝트에서 Settings > General > Visibility, project features, permissions를 선택합니다.

  2. Pipeline execution policies 설정을 활성화합니다.

  3. 정책 프로젝트에서 정책 CI/CD 구성을 위한 파일을 만듭니다.

    # policy-ci.yml
    
    policy-job:
      script: ...
    
  4. 정책을 강제하려는 그룹 또는 프로젝트에서 파이프라인 실행 정책을 만들고 보안 정책 프로젝트의 CI/CD 구성 파일을 지정합니다.

    pipeline_execution_policy:
    - name: My pipeline execution policy
      description: Enforces CI/CD jobs
      enabled: true
      pipeline_config_strategy: inject_policy
      content:
        include:
         - project: my-group/my-security-policy-project
           file: policy-ci.yml
    

비공개 또는 내부 프로젝트에 대한 접근 허용#

정책의 include: 값이 보안 정책 프로젝트가 아닌 다른 비공개 또는 내부 프로젝트에 저장된 CI/CD 구성 파일을 참조할 수 있습니다. 이 경우 파이프라인 실행 정책이 강제되는 프로젝트에서 파이프라인을 트리거하는 사용자에게 접근 권한을 허용할 수 있습니다.

구성 단계는 비공개 또는 내부 프로젝트에 대한 접근 허용을 참고합니다.

파이프라인 구성 전략#

파이프라인 구성 전략은 정책 구성을 프로젝트 파이프라인과 병합하는 방법을 정의합니다. 파이프라인 실행 정책은 .gitlab-ci.yml 파일에 정의된 job을 격리된 파이프라인에서 실행하고, 이 파이프라인은 대상 프로젝트의 파이프라인에 병합됩니다.

inject_policy 유형#

히스토리
  • GitLab 17.9에서 도입되었습니다.

이 전략은 프로젝트의 원래 CI/CD 구성을 완전히 대체하지 않고 기존 프로젝트 파이프라인에 사용자 지정 CI/CD 구성을 추가합니다. 새 보안 스캔, 컴플라이언스 검사, 사용자 지정 스크립트 같은 추가 단계로 현재 파이프라인을 강화하거나 확장하려는 경우에 적합합니다.

더 이상 사용되지 않는 inject_ci 전략과 달리 inject_policy는 파이프라인에 사용자 지정 정책 stage를 주입할 수 있으므로, CI/CD 워크플로의 어느 위치에 정책 규칙을 적용할지 더 세밀하게 제어할 수 있습니다.

정책을 여러 개 활성화하면 이 전략은 각 정책의 모든 job을 주입합니다.

이 전략을 사용하면 각 파이프라인이 격리된 YAML 구성을 가지므로, 프로젝트 CI/CD 구성이 정책 파이프라인에 정의된 어떤 동작도 재정의할 수 없습니다.

.gitlab-ci.yml 파일이 없는 프로젝트의 경우 이 전략은 .gitlab-ci.yml 파일을 암묵적으로 생성합니다. 실행되는 파이프라인에는 파이프라인 실행 정책에 정의된 job만 포함됩니다.

Note

파이프라인 실행 정책이 정책 job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 프로젝트의 CI/CD job뿐입니다. 프로젝트가 프로젝트 CI/CD job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 파이프라인 실행 정책 job뿐입니다.

즉, 프로젝트 파이프라인이 실행되지 않도록 막는 프로젝트의 workflow:rules 구성이 정책 파이프라인의 생성까지 막지는 않습니다. 정책에 Dependency-Scanning.v2.gitlab-ci.yml이 포함되어 있으면, 정책은 정책 컨텍스트에서 사용할 수 있는 값에 따라 의존성 스캔 머지 리퀘스트 파이프라인을 여전히 생성할 수 있습니다.

Stage 주입#

정책 파이프라인의 stage는 일반적인 CI/CD 구성을 따릅니다. 사용자 지정 stage의 앞과 뒤에 올 stage를 지정하면, 사용자 지정 정책 stage가 프로젝트 파이프라인에 주입되는 순서를 정의할 수 있습니다.

프로젝트 파이프라인과 정책 파이프라인의 stage는 방향성 비순환 그래프(Directed Acyclic Graph, DAG)로 표현되며, 노드는 stage이고 간선은 의존 관계를 나타냅니다. 파이프라인을 결합하면 개별 DAG가 하나의 더 큰 DAG로 병합됩니다. 그 후 위상 정렬을 수행하여 모든 파이프라인의 stage가 실행되어야 하는 순서를 결정합니다. 이 정렬은 최종 순서에서 모든 의존 관계가 지켜지도록 보장합니다. 의존 관계가 충돌하면 파이프라인이 실행되지 않습니다. 의존 관계를 바로잡으려면 프로젝트와 정책에서 사용하는 stage가 서로 일치하도록 맞춥니다.

정책 파이프라인 구성에 stage가 명시적으로 정의되어 있지 않으면 파이프라인은 기본 stage인 stages: [build, test, deploy]를 사용합니다. 이 stage를 포함하되 다른 순서로 나열하면 파이프라인이 Cyclic dependencies detected when enforcing policies 오류와 함께 실패합니다.

다음 예시는 이 동작을 보여 줍니다. 모든 예시는 다음과 같은 프로젝트 CI/CD 구성을 가정합니다.

# .gitlab-ci.yml
stages: [build, test, deploy]

project-build-job:
  stage: build
  script: ...

project-test-job:
  stage: test
  script: ...

project-deploy-job:
  stage: deploy
  script: ...
예시 1#
# policy-ci.yml
stages: [test, policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • test stage가 있으면 그 뒤에 주입되어야 합니다.
  • deploy stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [build, deploy, test]로 지정했다면 제약 조건을 충족할 수 없으므로 파이프라인이 Cyclic dependencies detected when enforcing policies 오류와 함께 실패합니다. 실패를 해결하려면 프로젝트 구성을 조정하여 stage를 정책과 일치시킵니다.
  • .gitlab-ci.yml에서 stage를 [build]로 지정했다면 결과 파이프라인의 stage는 [build, policy-stage]입니다.
예시 2#
# policy-ci.yml
stages: [policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • deploy stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [build, deploy, test]로 지정했다면 결과 파이프라인의 stage는 [build, policy-stage, deploy, test]가 됩니다.
  • 프로젝트 파이프라인에 deploy stage가 없으면 policy-stage stage는 파이프라인의 끝, 즉 .pipeline-policy-post 바로 앞에 주입됩니다.
예시 3#
# policy-ci.yml
stages: [test, policy-stage]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • test stage가 있으면 그 뒤에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, deploy, policy-stage] stage가 포함됩니다.

특수한 경우:

  • 프로젝트 파이프라인에 test stage가 없으면 policy-stage stage는 파이프라인의 끝, 즉 .pipeline-policy-post 바로 앞에 주입됩니다.
예시 4#
# policy-ci.yml
stages: [policy-stage]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage에는 제약 조건이 없습니다.

결과: 파이프라인에는 [build, test, deploy, policy-stage] stage가 포함됩니다.

예시 5#
# policy-ci.yml
stages: [check, lint, test, policy-stage, deploy, verify, publish]

policy-job:
  stage: policy-stage
  script: ...

이 예시에서 policy-stage stage는 다음과 같습니다.

  • check, lint, test stage가 있으면 그 뒤에 주입되어야 합니다.
  • deploy, verify, publish stage가 있으면 그 앞에 주입되어야 합니다.

결과: 파이프라인에는 [build, test, policy-stage, deploy] stage가 포함됩니다.

특수한 경우:

  • .gitlab-ci.yml에서 stage를 [check, publish]로 지정했다면 결과 파이프라인의 stage는 [check, policy-stage, publish]입니다.

기본 stage 순서#

정책에 stage가 정의되어 있지 않으면 GitLab은 다음 기본 stage 순서를 강제합니다.

  1. .pre
  2. build
  3. test
  4. deploy
  5. .post.

기본 순서는 이러한 기본 stage를 다른 순서로 사용하는 프로젝트와 충돌할 수 있습니다. 예를 들어 stages: [test, build, deploy]처럼 test를 build보다 앞에 두는 경우입니다.

순환 의존성 방지#

순환 의존성 오류는 정책의 stage 순서가 프로젝트의 stage 순서와 충돌할 때 발생합니다. 이러한 오류를 피하려면 다음을 따릅니다.

  • 정책의 stage를 항상 명시적으로 정의하여 stage 순서가 분명하고 프로젝트와 호환되도록 합니다. 정책이 기본 stage인 build, test, deploy를 사용하면 그 순서가 모든 프로젝트에 강제된다는 점에 유의합니다.
  • 예약된 stage(.pipeline-policy-pre와 .pipeline-policy-post)만 사용하는 경우에는 이러한 예약된 stage가 항상 파이프라인의 맨 앞과 맨 끝에 배치되므로 정책에 기본 stage를 정의할 필요가 없습니다.

이 지침을 따르면 stage 구성이 서로 다른 프로젝트에서도 안정적으로 동작하는 정책을 만들 수 있습니다.

inject_ci(더 이상 사용되지 않음)#

Warning

이 기능은 GitLab 17.9에서 더 이상 사용되지 않게 되었습니다. 사용자 지정 정책 stage의 강제를 지원하는 inject_policy를 대신 사용합니다.

이 전략은 프로젝트의 원래 CI/CD 구성을 완전히 대체하지 않고 기존 프로젝트 파이프라인에 사용자 지정 CI/CD 구성을 추가합니다. 새 보안 스캔, 컴플라이언스 검사, 사용자 지정 스크립트 같은 추가 단계로 현재 파이프라인을 강화하거나 확장하려는 경우에 적합합니다.

정책을 여러 개 활성화하면 모든 job이 누적하여 주입됩니다.

이 전략을 사용하면 각 파이프라인이 격리된 YAML 구성을 가지므로, 프로젝트 CI/CD 구성이 정책 파이프라인에 정의된 어떤 동작도 재정의할 수 없습니다.

.gitlab-ci.yml 파일이 없는 프로젝트의 경우 이 전략은 .gitlab-ci.yml 파일을 암묵적으로 생성합니다. 이를 통해 파이프라인 실행 정책에 정의된 job만 포함하는 파이프라인이 실행될 수 있습니다.

Note

파이프라인 실행 정책이 정책 job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 프로젝트의 CI/CD job뿐입니다. 프로젝트가 프로젝트 CI/CD job의 실행을 막는 workflow 규칙을 사용하면, 실행되는 job은 파이프라인 실행 정책 job뿐입니다.

override_project_ci#

히스토리
  • workflow 규칙 처리 방식 업데이트:
  • GitLab 17.8에서 policies_always_override_project_ci라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 17.10에서 정식 출시되었습니다. 기능 플래그 policies_always_override_project_ci가 제거되었습니다.
  • GitLab 17.9에서 스캔 실행 정책이 파이프라인 실행 정책과 함께 실행될 수 있도록 override_project_ci 처리 방식이 변경되었습니다.

이 전략은 프로젝트의 기존 CI/CD 구성을 파이프라인 실행 정책이 정의한 새 구성으로 대체합니다. 이 전략은 전체 파이프라인을 표준화하거나 교체해야 할 때, 예를 들어 규제가 엄격한 산업에서 조직 전체의 CI/CD 표준이나 컴플라이언스 요구 사항을 강제하려는 경우에 이상적입니다. 파이프라인 구성을 재정의하려면 CI/CD job을 정의하고 include:project를 사용하지 않습니다.

이 전략은 inject_ci 또는 inject_policy 전략을 사용하는 다른 정책보다 우선합니다. override_project_ci가 있는 정책이 적용되면 프로젝트 CI/CD 구성은 무시됩니다. 다만 다른 보안 정책 구성은 재정의되지 않습니다.

파이프라인 실행 정책에서 override_project_ci를 스캔 실행 정책과 함께 사용하면 CI/CD 구성이 병합되고 두 정책이 모두 결과 파이프라인에 적용됩니다.

또는 프로젝트의 CI/CD 구성을 재정의하는 대신 프로젝트의 .gitlab-ci.yml과 병합할 수도 있습니다. 구성을 병합하려면 include:project를 사용합니다. 이 전략을 사용하면 사용자가 프로젝트 CI/CD 구성을 파이프라인 실행 정책 구성에 포함하여 정책 job을 사용자 지정할 수 있습니다. 예를 들어 정책과 프로젝트 CI/CD 구성을 하나의 YAML 파일로 결합하여 before_script 구성을 재정의하거나, 스캔할 컨테이너의 필수 경로를 정의하는 CS_IMAGE 같은 필수 변수를 정의할 수 있습니다. 이 동작에 대한 짧은 데모가 있습니다. 다음 다이어그램은 프로젝트 수준과 정책 수준에서 정의한 변수가 결과 파이프라인에서 어떻게 선택되는지 보여 줍니다.

Mermaid 다이어그램 (89줄)
소스 코드 보기
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
    accTitle: Variable precedence in pipeline execution policies
    accDescr: Policy variables take precedence over project variables when jobs are combined into the resulting pipeline.

classDef yaml text-align:left

ActualPolicyYAML["<pre> variables: MY_VAR: 'policy' policy-job: stage: test </pre>"]

class ActualPolicyYAML yaml

ActualProjectYAML["<pre> variables: MY_VAR: 'project' project-job: stage: test </pre>"]

class ActualProjectYAML yaml

PolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"]

class PolicyVariablesYAML yaml

ProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"]

class ProjectVariablesYAML yaml

ResultingPolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"]

class ResultingPolicyVariablesYAML yaml

ResultingProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"]

class ResultingProjectVariablesYAML yaml

PolicyCiYAML(Policy CI YAML) --> ActualPolicyYAML ProjectCiYAML(<code>.gitlab-ci.yml</code>) --> ActualProjectYAML

subgraph "Policy Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code>" PolicyVariablesYAML end end end

subgraph "Project Pipeline" subgraph "Test stage" subgraph "<code>project-job</code>" ProjectVariablesYAML end end end

ActualPolicyYAML -- "Used as source" --> PolicyVariablesYAML ActualProjectYAML -- "Used as source" --> ProjectVariablesYAML

subgraph "Resulting Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code> " ResultingPolicyVariablesYAML end

subgraph "&lt;code&gt;project-job&lt;/code&gt; "
  ResultingProjectVariablesYAML
end

end end

PolicyVariablesYAML -- "Inject <code>policy-job</code> if Test Stage exists" --> ResultingPolicyVariablesYAML ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVariablesYAML

Note

파이프라인 실행 정책의 workflow 규칙은 프로젝트의 원래 CI/CD 구성을 재정의합니다. 정책에 workflow 규칙을 정의하면 브랜치 파이프라인 사용 금지처럼 연결된 모든 프로젝트에 강제되는 규칙을 설정할 수 있습니다.

파이프라인 이름#

override_project_ci 전략을 사용하는 파이프라인 실행 정책은 프로젝트의 원래 CI/CD 구성에 정의된 파이프라인 이름을 재정의합니다.

파이프라인 이름은 파이프라인 실행 정책 구성에서 정의할 수 있습니다.

override_project_ci 전략을 사용하는 파이프라인 실행 정책이 여러 개 있으면 그룹 계층에서 가장 낮은 곳의 정책이 적용됩니다. 예를 들어 프로젝트의 정책은 해당 프로젝트가 속한 그룹의 정책을 재정의합니다. 하위 그룹의 정책은 그 하위 그룹이 속한 그룹의 정책보다 우선합니다.

프로젝트의 CI/CD 구성을 파이프라인 실행 정책 구성에 포함#

override_project_ci 전략을 사용할 때 프로젝트 구성을 파이프라인 실행 정책 구성에 포함할 수 있습니다.

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
    rules:
      - exists:
          paths:
            - '$CI_CONFIG_PATH'
          project: '$CI_PROJECT_PATH'
          ref: '$CI_COMMIT_SHA'

compliance_job:
 ...
Note

프로젝트의 .gitlab-ci.yml 구성이 include:project를 사용해 override_project_ci 정책에 포함되면, 프로젝트 구성이 정책 파이프라인의 일부가 됩니다. 이 경우 포함된 프로젝트 구성은 예약된 stage(.pipeline-policy-pre와 .pipeline-policy-post)에 job을 할당할 수 있습니다. 정책 파이프라인 안에서는 예약된 stage의 사용이 허용되기 때문입니다. 이 예외를 제외하면 job을 예약된 stage에 할당할 수 없습니다.

CI/CD 변수#

Warning

변수는 Git 리포지터리에 있는 정책 구성의 일부로 일반 텍스트로 저장되므로, 민감한 정보나 자격 증명을 변수에 저장하지 마십시오.

기본적으로 파이프라인 실행 정책은 격리된 상태로 실행되므로 정책 밖에서 정의된 변수를 적용하지 않습니다. 이 격리는 프로젝트 또는 그룹 CI/CD 변수를 사용해 파이프라인 유형을 선택하는 보안 스캔 템플릿에도 영향을 줍니다. 예를 들어 파이프라인 실행 정책이 Dependency-Scanning.v2.gitlab-ci.yml을 주입하면, 정책 job은 프로젝트나 그룹의 AST_ENABLE_MR_PIPELINES를 자동으로 받지 못합니다. 이 변수를 사용할 수 없으면 값이 null이 되고, 의존성 스캔 v2 템플릿은 null을 "true"와 같게 취급합니다. 그 결과 프로젝트나 그룹 변수가 AST_ENABLE_MR_PIPELINES: "false"로 설정되어 있어도 정책 job이 머지 리퀘스트 파이프라인에서 실행될 수 있습니다.

이 동작을 제어하려면 정책 CI/CD 구성에서 AST_ENABLE_MR_PIPELINES를 정의하거나, variables_override로 해당 변수를 허용합니다.

variables_override:
  allowed: false
  exceptions:
    - AST_ENABLE_MR_PIPELINES

allowed: false로 설정하면 exceptions에 나열된 변수를 제외한 모든 프로젝트 및 그룹 변수가 차단됩니다. 반대로 allowed: true로 설정하면 exceptions에 변수를 나열했을 때 그 변수를 허용하는 것이 아니라 차단합니다.

variables_override 설정을 활성화하면 파이프라인 실행 정책은 다음과 같은 사용자 정의 변수에 접근할 수 있습니다.

  • 그룹 CI/CD 설정의 변수.
  • 프로젝트 CI/CD 설정의 변수.
  • 사용자가 새 파이프라인을 실행할 때 지정한 변수.

그러나 variables_override 설정을 활성화하더라도 파이프라인 실행 정책은 다음 유형의 변수에는 접근할 수 없습니다.

  • 다른 정책에 정의된 변수.
  • 프로젝트의 .gitlab-ci.yml 파일에 정의된 변수.

variables_override 설정을 활성화하면 정책은 표준 CI/CD 변수 우선순위 규칙에 따라 변수에 접근하고 적용할 수 있습니다.

그러나 파이프라인 실행 정책을 사용할 때는 우선순위 규칙이 파이프라인 실행 정책 전략에 따라 달라질 수 있어 더 복잡합니다.

  • inject_policy 전략: 변수가 파이프라인 실행 정책에 정의되어 있으면 job은 항상 이 값을 사용합니다. 변수가 파이프라인 실행 정책에 정의되어 있지 않으면 job은 그룹 또는 프로젝트 설정의 값을 적용합니다.
  • inject_ci 전략: 변수가 파이프라인 실행 정책에 정의되어 있으면 job은 항상 이 값을 사용합니다. 변수가 파이프라인 실행 정책에 정의되어 있지 않으면 job은 그룹 또는 프로젝트 설정의 값을 적용합니다.
  • override_project_ci 전략: 결과 파이프라인의 모든 job이 정책 job으로 취급됩니다. 정책에 정의된 변수(포함된 파일의 변수 포함)는 프로젝트 및 그룹 변수보다 우선합니다. 즉, 포함된 프로젝트의 CI/CD 구성에 있는 job의 변수가 프로젝트 및 그룹 설정에 정의된 변수보다 우선합니다.

파이프라인 실행 정책의 변수에 대한 자세한 내용은 파이프라인 실행 정책의 변수 우선순위를 참고합니다.

UI에서 프로젝트 또는 그룹 변수를 정의할 수 있습니다.

파이프라인 실행 정책의 변수 우선순위#

파이프라인 실행 정책을 사용할 때, 특히 override_project_ci 전략에서는 여러 위치에 정의된 변수 값의 우선순위가 표준 GitLab CI/CD 파이프라인과 다를 수 있습니다. 이해해야 할 중요한 사항은 다음과 같습니다.

  • override_project_ci를 사용하면 포함된 프로젝트의 CI/CD 구성에서 온 job을 포함해 결과 파이프라인의 모든 job이 정책 job으로 간주됩니다.
  • 정책 파이프라인에 정의된 변수(인스턴스 전체 또는 job 단위)는 프로젝트 또는 그룹 설정에 정의된 변수보다 우선합니다.
  • 이 동작은 프로젝트의 CI/CD 구성 파일(.gitlab-ci.yml)에서 포함된 job을 포함해 모든 job에 적용됩니다.

예시#

프로젝트의 CI/CD 구성에 있는 변수와 포함된 .gitlab-ci.yml 파일에 정의된 job 변수의 이름이 같으면, override_project_ci를 사용할 때 job 변수가 우선합니다.

프로젝트의 CI/CD 설정에 MY_VAR 변수가 정의되어 있습니다.

  • Key: MY_VAR
  • Value: Project configuration variable value

포함된 프로젝트의 .gitlab-ci.yml에 같은 변수가 정의되어 있습니다.

project-job:
  variables:
    MY_VAR: "Project job variable value"
  script:
    - echo $MY_VAR  # This will output "Project job variable value"

이 경우 job 변수 값인 Project job variable value가 우선합니다.

수동으로 실행하는 파이프라인의 변수 미리 채우기#

히스토리
  • GitLab 18.5에서 도입되었습니다.
Warning

이 기능은 GitLab 18.5 이전에 생성된 파이프라인 실행 정책에서는 동작하지 않습니다. 이전 파이프라인 실행 정책에서 이 기능을 사용하려면 다음 중 하나를 수행합니다.

  • 파이프라인 실행 정책의 기존 YAML 구성 파일을 아무거나 변경합니다.
  • 정책을 복사하고 삭제한 다음 다시 만듭니다.

자세한 내용은 파이프라인 실행 정책 재생성을 참고합니다.

description, value, options 키워드를 사용해 사용자가 수동으로 파이프라인을 실행할 때 미리 채워지는 CI/CD 변수를 정의할 수 있습니다. 설명에는 변수의 용도와 허용되는 값이 무엇인지 같은 관련 정보를 작성합니다.

job별 변수는 미리 채울 수 없습니다.

수동으로 트리거하는 파이프라인에서 New pipeline 페이지는 적용 가능한 모든 정책의 CI/CD 구성에서 description이 정의된 모든 파이프라인 변수를 표시합니다.

미리 채워진 변수는 variables_override를 사용해 허용하도록 구성해야 합니다. 그렇지 않으면 파이프라인을 수동으로 트리거할 때 사용한 값이 무시됩니다.

override_project_ci에서 미리 채워진 변수가 표시되지 않는 문제#

프로젝트에 override_project_ci 전략을 사용하는 파이프라인 실행 정책이 할당되면 New pipeline 페이지에 정책의 미리 채워진 변수가 표시되지 않을 수 있습니다. 이 문제는 프로젝트의 .gitlab-ci.yml 파일이 그 자체로는 유효한 CI/CD 구성이 아닐 때 발생합니다. 예를 들어 variables: 블록만 있고 job이 없는 파일은, GitLab이 미리 채워진 변수를 나열하려 할 때 jobs config should contain at least one visible job 오류를 반환합니다.

파이프라인을 생성할 때 정책이 빠진 job을 제공하므로 파이프라인 자체는 계속 올바르게 실행됩니다. 이 문제는 New pipeline 페이지의 미리 채워진 변수 표시에만 영향을 줍니다.

해결 방법으로, 프로젝트의 .gitlab-ci.yml 파일에 눈에 보이는 job을 추가하여 그 파일이 단독으로도 유효하게 만듭니다. 이 job에 when: never가 있는 rules: 절을 지정하면 파이프라인에 실제로 추가되지 않습니다.

variables:
  SOME_VAR: "value"

placeholder-job:
  script:
    - echo "Placeholder job that keeps this configuration valid on its own."
  rules:
    - when: never

구성에는 눈에 보이는 job이 하나 이상 있어야 하므로, 숨겨진 job(이름이 마침표로 시작하는 job)은 대체 수단으로 동작하지 않습니다.

프로젝트가 job을 제공하는 일을 정책에 의존하는 경우에만 이 해결 방법을 사용합니다. 정책이 어떤 브랜치에 적용되지 않으면, 유일한 job이 실행되지 않는 구성은 파이프라인을 생성하지 않습니다.

자세한 내용은 이슈 600124를 참고합니다.

파이프라인 실행 정책 재생성#

파이프라인 실행 정책을 재생성하려면 다음을 수행합니다.

  1. 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Policies를 선택합니다.
  3. 재생성하려는 파이프라인 실행 정책을 선택합니다.
  4. 오른쪽 사이드바에서 YAML 탭을 선택하고 정책 파일 전체의 내용을 복사합니다.
  5. 정책 표 옆에서 세로 줄임표(⋮)를 선택한 다음 Delete를 선택합니다.
  6. 생성된 머지 리퀘스트를 머지합니다.
  7. Secure > Policies로 돌아가서 New policy를 선택합니다.
  8. Pipeline execution policy 섹션에서 Select policy를 선택합니다.
  9. .yaml mode에서 이전 정책의 내용을 붙여넣습니다.
  10. Update via merge request를 선택하고 생성된 머지 리퀘스트를 머지합니다.

보안상 중요한 정책의 실행 보장#

보안 및 컴플라이언스 목적으로 파이프라인 실행 정책을 구현할 때는 정책이 우회되거나 훼손되지 않도록 다음 모범 사례를 고려합니다.

보안상 중요한 job에서는 changes: 규칙 사용 피하기#

보안상 중요한 파이프라인 정책에서는 브랜치 파이프라인에서 예기치 않은 결과를 낼 수 있으므로 changes: 규칙 사용을 피합니다. changes: 키워드는 SHA 기반 diff에 의존하므로 git commit --amend 후 강제 푸시를 하는 경우처럼 특정 상황에서는 우회될 수 있습니다.

git commit --amend 후 강제 푸시를 하면 GitLab은 변경된 파일을 다르게 계산합니다.

  1. 첫 번째 푸시(표준 커밋):

    1. GitLab이 새 커밋을 부모 커밋과 비교합니다.
    2. GitLab이 대상 파일이 변경되었음을 감지합니다.
    3. changes: [filename] 규칙이 올바르게 트리거됩니다.
  2. 두 번째 푸시(--force를 사용한 amend 커밋):

    1. amend된 커밋이 이전 커밋을 새 SHA로 완전히 대체합니다.
    2. GitLab이 브랜치의 이전 커밋과 비교하는 git diff HEAD~로 변경 사항을 계산합니다.
    3. 브랜치의 이전 커밋에도 같은 파일 변경이 있었으므로 diff에는 새로운 변경 사항이 없는 것으로 나타납니다.
    4. changes: 규칙이 트리거되지 않습니다.

대신 우회할 수 없는 조건을 사용합니다.

check-critical-files:
  stage: .pipeline-policy-pre
  script:
    - |
      # Check if critical files differ from the target branch
      if git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --name-only | grep -q "Makefile\|\.gitlab-ci\.yml"; then
        echo "Critical files have been modified"
        exit 1
      fi
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always

또는 changes: 조건 없이 모든 파이프라인에서 정책 검사를 실행합니다.

security-check:
  stage: .pipeline-policy-pre
  script:
    - echo "Running security checks"
    - ./run-security-checks.sh
  rules:
    - when: always

changes: 동작에 대한 자세한 내용은 changes를 사용할 때 job 또는 파이프라인이 예기치 않게 실행됨을 참고합니다.

중요한 보안 검사에는 .pipeline-policy-pre stage 사용#

.pipeline-policy-pre stage의 job은 보안 및 컴플라이언스 사용 사례를 위해 설계되었습니다. 파이프라인의 다른 모든 job은 이 stage가 완료될 때까지 기다린 후에 시작됩니다. .pipeline-policy-pre stage가 실패하면 이후의 모든 job을 건너뜁니다.

중복된 보안 구성 감지#

.pipeline-policy-pre를 사용해 기존 보안 구성을 확인하고 안내를 제공하는 사용자 지정 검증 job을 만들 수 있습니다. 예를 들어 파이프라인 실행 정책으로 조직 전체에 보안 스캔을 강제하는데 일부 프로젝트에 이미 자체 보안 스캔 구현이 있는 경우, .pipeline-policy-pre를 사용해 중복된 스캔을 식별할 수 있습니다.

정책 CI/CD 구성 예시:

# policy-ci.yml
check-duplicate-scans:
  stage: .pipeline-policy-pre
  script:
    - |
      echo "Checking for duplicate security scan configurations..."
      if [ -f ".gitlab-ci.yml" ]; then
        if grep -q "secret_detection:" .gitlab-ci.yml || \
           grep -q "sast:" .gitlab-ci.yml || \
           grep -q "dependency_scanning:" .gitlab-ci.yml || \
           grep -q "container_scanning:" .gitlab-ci.yml; then
          echo "WARNING: Duplicate security scans detected."
          echo ""
          echo "This project has security scans defined in .gitlab-ci.yml"
          echo "that might duplicate the scans enforced by pipeline execution policies."
          echo ""
          echo "To avoid redundant scans and reduce pipeline time:"
          echo "1. Review your .gitlab-ci.yml for security scanning jobs."
          echo "2. Remove duplicate jobs (secret_detection, sast, dependency_scanning, and so on)."
          echo "3. The pipeline execution policy ensures these scans still run."
          echo ""
          echo "For questions, contact your security team."
        else
          echo "No duplicate security scans detected."
        fi
      fi
  allow_failure: true
  rules:
    - when: always

이 구성은 다음과 같습니다.

  • 파이프라인을 차단하지 않고 잠재적인 중복 구성을 감지합니다.
  • 개발 팀에 실행 가능한 안내를 제공합니다.
  • 정리가 필요한 프로젝트를 계속 파악할 수 있게 합니다.
  • 의도하지 않은 결과를 낳을 수 있는 job 자동 제거의 복잡성을 피합니다.

이 예시를 확장하여 다른 구성 문제를 확인하거나, 보안 팀이 프로젝트 전반의 컴플라이언스를 추적할 수 있도록 보고서를 생성할 수 있습니다.

변수 재정의 제어#

variables_override 구성을 사용하면 사용자가 보안 스캔을 비활성화하거나 중요한 보안 구성을 수정하는 방식으로 중요한 보안 변수를 재정의하지 못하게 할 수 있습니다.

variables_override:
  allowed: false
  exceptions:
    - CS_IMAGE  # Allow customization of container image only

안전한 job 이름 지정#

고유하고 설명적인 job 이름에 접두사를 붙이면 충돌을 방지하고, 해당 job이 보안 정책으로 강제된다는 점을 사용자에게 분명히 알릴 수 있습니다.

# Good: Clear security policy job name
security-policy:sast-scan:
  stage: .pipeline-policy-pre
  script: ...

# Avoid: Generic name that could conflict
sast:
  stage: .pipeline-policy-pre
  script: ...

[no_pipeline] 사용 시 동작#

기본적으로 일반 파이프라인이 생성되지 않게 하려면 사용자가 푸시 옵션에 [no_pipeline]을 넣어 보호된 브랜치에 커밋을 푸시할 수 있습니다. 그러나 파이프라인 실행 정책으로 정의된 job은 정책이 [no_pipeline] 지시문을 무시하므로 항상 트리거됩니다. 이렇게 하면 개발자가 정책에 정의된 job의 실행을 건너뛰는 일을 막아 중요한 보안 및 컴플라이언스 검사가 항상 수행되도록 보장합니다.

[no_pipeline] 동작을 더 유연하게 제어하려면 no_pipeline 유형 절을 참고합니다.

[skip ci] 사용 시 동작#

기본적으로 일반 파이프라인이 트리거되지 않게 하려면 사용자가 커밋 메시지에 [skip ci]를 넣어 보호된 브랜치에 커밋을 푸시할 수 있습니다. 그러나 파이프라인 실행 정책으로 정의된 job은 정책이 [skip ci] 지시문을 무시하므로 항상 트리거됩니다. 이렇게 하면 개발자가 정책에 정의된 job의 실행을 건너뛰는 일을 막아 중요한 보안 및 컴플라이언스 검사가 항상 수행되도록 보장합니다.

[skip ci] 동작을 더 유연하게 제어하려면 skip_ci 유형 절을 참고합니다.

예시#

다음 예시는 파이프라인 실행 정책으로 할 수 있는 일을 보여 줍니다.

파이프라인 실행 정책#

보안 정책 프로젝트에 저장된 .gitlab/security-policies/policy.yml 파일에서 다음 예시를 사용할 수 있습니다.

---
pipeline_execution_policy:
- name: My pipeline execution policy
  description: Enforces CI/CD jobs
  enabled: true
  pipeline_config_strategy: override_project_ci
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
      ref: main # optional
  policy_scope:
    projects:
      including:
      - id: 361

프로젝트 변수에 따라 강제되는 job 사용자 지정#

파이프라인 실행 정책은 프로젝트별 변수에 따라 동작을 조정합니다. 합리적인 기본값을 제공하면서 개별 프로젝트가 강제되는 job의 특정 부분을 사용자 지정할 수 있도록 허용하는 유연한 정책을 만들 수 있습니다.

변수 평가#

파이프라인 실행 정책의 규칙(예: if: $PROJECT_CS_IMAGE)은 프로젝트의 컨텍스트가 아니라 정책 실행 중에 평가됩니다. 이는 다음을 의미합니다.

  • 프로젝트 변수는 표준 이름(예: $PROJECT_CS_IMAGE)으로 정책에서 사용할 수 있습니다.
  • 프로젝트 변수가 정책에 정의된 변수보다 우선할 수 있습니다.
  • 어떤 변수를 사용할지에 대한 평가는 GitLab이 정책 파이프라인을 구성할 때 이루어집니다.

변수 이름 지정 패턴#

사용자 지정이 가능한 정책을 만들 때는 다음 이름 지정 규칙을 따릅니다.

  • 정책 변수: 기본값에는 표준 이름(예: CS_IMAGE)을 사용합니다.
  • 프로젝트 재정의 변수: 용도를 분명히 나타내도록 설명적인 접두사(예: PROJECT_CS_IMAGE)를 사용합니다.

이 패턴은 이름 충돌을 방지하고 의도를 분명하게 합니다.

예시: 이미지를 사용자 지정할 수 있는 컨테이너 스캔#

이 예시는 기본 컨테이너 이미지를 사용하되 프로젝트가 자체 이미지를 지정할 수 있도록 허용하는 정책을 만드는 방법을 보여 줍니다.

variables:
  CS_ANALYZER_IMAGE: "$CI_TEMPLATE_REGISTRY_HOST/security-products/container-scanning:8"
  CS_IMAGE: alpine:latest  # Default fallback value

policy::container-security:
  stage: .pipeline-policy-pre
  rules:
    - if: $PROJECT_CS_IMAGE  # Check if project defined a custom image
      variables:
        CS_IMAGE: $PROJECT_CS_IMAGE  # Use project's custom image
    - when: always  # Always run the job (with default or custom image)
  script:
    - echo "CS_ANALYZER_IMAGE:$CS_ANALYZER_IMAGE"
    - echo "CS_IMAGE:$CS_IMAGE"

동작 방식은 다음과 같습니다.

  1. 기본 동작: 프로젝트에 PROJECT_CS_IMAGE가 정의되어 있지 않으면 CS_IMAGE는 alpine:latest로 유지됩니다.
  2. 사용자 지정 동작: 프로젝트가 PROJECT_CS_IMAGE를 정의하면 그 값이 CS_IMAGE를 재정의합니다.
  3. 규칙 평가: if: $PROJECT_CS_IMAGE 조건은 정책 컨텍스트에서 평가되며 프로젝트 변수에 접근할 수 있습니다.
  4. 변수 우선순위: 정책의 변수 할당이 기본값보다 우선합니다.

컨테이너 이미지를 사용자 지정하려면 프로젝트에서 PROJECT_CS_IMAGE를 .gitlab-ci.yml 파일에 지정하지 말고 프로젝트 변수로 정의해야 합니다.

변수 고려 사항 요약#

변수 소스:

  • 프로젝트 변수는 .gitlab-ci.yml이 아니라 프로젝트의 CI/CD 설정에 정의해야 합니다.
  • 정책은 그룹 변수와 인스턴스 변수도 표준 이름으로 사용할 수 있습니다.
  • 정책 변수와 프로젝트 변수가 같은 이름으로 정의되어 있으면 정책 변수가 프로젝트 변수보다 우선합니다.

규칙 평가:

  • 파이프라인 실행 정책의 모든 rules: 조건은 정책이 실행될 때 평가됩니다. 즉, 정책은 프로젝트별 변수에 접근하고 그에 반응할 수 있습니다.
  • 평가는 어떤 job이든 실행되기 전인 파이프라인 구성 중에 이루어집니다.

모범 사례:

  • 프로젝트 재정의에는 접두사가 있는 설명적인 변수 이름(예: PROJECT_*)을 사용합니다.
  • 정책에 항상 합리적인 기본값을 제공합니다.
  • 사용자를 위해 사용할 수 있는 사용자 지정 변수를 문서화합니다.

.gitlab-ci.yml과 아티팩트를 사용해 강제되는 job 사용자 지정#

정책 파이프라인은 격리되어 실행되므로 파이프라인 실행 정책은 .gitlab-ci.yml의 변수를 직접 읽을 수 없습니다. 프로젝트의 CI/CD 구성에 변수를 정의하는 대신 .gitlab-ci.yml의 변수를 사용하려면, 아티팩트를 사용해 .gitlab-ci.yml 구성에서 파이프라인 실행 정책의 파이프라인으로 변수를 전달할 수 있습니다.

# .gitlab-ci.yml

build-job:
  stage: build
  script:
    - echo "BUILD_VARIABLE=value_from_build_job" >> build.env
  artifacts:
    reports:
      dotenv: build.env
stages:
- build
- test

test-job:
  stage: test
  script:
    - echo "$BUILD_VARIABLE" # Prints "value_from_build_job"

프로젝트 구성에서 before_script로 보안 스캐너의 동작 사용자 지정#

프로젝트의 .gitlab-ci.yml에서 정책이 강제하는 보안 job의 동작을 사용자 지정하려면 before_script를 재정의할 수 있습니다. 이렇게 하려면 정책에서 override_project_ci 전략을 사용하고 프로젝트의 CI/CD 구성을 포함합니다. 파이프라인 실행 정책 구성 예시:

# policy.yml
type: pipeline_execution_policy
name: Secret detection
description: >
  This policy enforces secret detection and allows projects to override the
  behavior of the scanner.
enabled: true
pipeline_config_strategy: override_project_ci
content:
  include:
    - project: gitlab-org/pipeline-execution-policies/compliance-project
      file: secret-detection.yml
# secret-detection.yml
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
  - template: Jobs/Secret-Detection.gitlab-ci.yml

프로젝트의 .gitlab-ci.yml에서 스캐너에 대한 before_script를 정의할 수 있습니다.

include:
  - template: Jobs/Secret-Detection.gitlab-ci.yml

secret_detection:
  before_script:
    - echo "Before secret detection"

override_project_ci를 사용하고 프로젝트의 구성을 포함하면 YAML 구성을 병합할 수 있습니다.

리소스별 변수 제어 구성#

팀이 파이프라인 실행 정책 변수를 재정의할 수 있는 전역 변수를 설정하도록 허용하면서, job별 재정의도 계속 허용할 수 있습니다. 이렇게 하면 팀이 보안 스캔에는 적절한 기본값을 설정하고 다른 job에는 적절한 리소스를 사용할 수 있습니다.

resource-optimized-scans.yml에 다음을 포함합니다.

variables:
  # Default resource settings for all jobs
  KUBERNETES_MEMORY_REQUEST: 4Gi
  KUBERNETES_MEMORY_LIMIT: 4Gi
  # Default values that teams can override via project variables
  SAST_KUBERNETES_MEMORY_REQUEST: 4Gi

sast:
  variables:
    SAST_EXCLUDED_ANALYZERS: 'spotbugs'
    KUBERNETES_MEMORY_REQUEST: $SAST_KUBERNETES_MEMORY_REQUEST
    KUBERNETES_MEMORY_LIMIT: $SAST_KUBERNETES_MEMORY_REQUEST

policy.yml에 다음을 포함합니다.

pipeline_execution_policy:
- name: Resource-Optimized Security Policy
  description: Enforces security scans with efficient resource management
  enabled: true
  pipeline_config_strategy: inject_ci
  content:
    include:
    - project: security/policy-templates
      file: resource-optimized-scans.yml
      ref: main

  variables_override:
    allowed: false
    exceptions:
      # Allow scan-specific resource overrides
      - SAST_KUBERNETES_MEMORY_REQUEST
      - SECRET_DETECTION_KUBERNETES_MEMORY_REQUEST
      - CS_KUBERNETES_MEMORY_REQUEST
      # Allow necessary scan customization
      - CS_IMAGE
      - SAST_EXCLUDED_PATHS

이 방식을 사용하면 팀이 파이프라인의 모든 job에 영향을 주지 않고 변수 재정의로 스캔별 리소스 변수(예: SAST_KUBERNETES_MEMORY_REQUEST)를 설정할 수 있으므로 대규모 프로젝트에서 더 나은 리소스 관리가 가능합니다. 이 예시는 개발자에게 확장해 줄 수 있는 다른 일반적인 스캔 사용자 지정 옵션의 사용도 함께 보여 줍니다. 개발 팀이 활용할 수 있도록 사용 가능한 변수를 반드시 문서화합니다.

파이프라인 실행 정책에서 그룹 또는 프로젝트 변수 사용#

파이프라인 실행 정책에서 그룹 또는 프로젝트 변수를 사용할 수 있습니다.

PROJECT_VAR="I'm a project"라는 프로젝트 변수가 있으면 다음 파이프라인 실행 정책 job의 결과는 I'm a project입니다.

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

프로젝트 구성의 변수를 파이프라인 실행 정책에 포함#

파이프라인 실행 정책은 자체의 격리된 컨텍스트에서 실행되므로 프로젝트의 .gitlab-ci.yml 파일에 정의된 변수는 정책 job에서 자동으로 사용할 수 없습니다. 하지만 프로젝트에 있는 별도의 변수 파일을 참조하면 프로젝트에서 정의한 변수를 포함할 수 있습니다.

이 방식은 다음과 같은 경우에 사용합니다.

  • Docker 컨테이너에 사용자 지정 이름 지정 규칙을 사용해야 하는 경우.
  • 정책이 존중해야 하는 프로젝트별 구성을 유지하려는 경우.
  • 이름은 다르지만 같은 프로젝트에서 빌드된 컨테이너가 여러 개 있는 경우.

예시: 프로젝트 변수 파일 포함#

프로젝트 리포지터리에 변수 파일을 만듭니다(예: gitlab-variables.yml).

# gitlab-variables.yml
variables:
  DOCKER_TLS_CERTDIR: "/certs"
  CS_IMAGE: ${CI_REGISTRY_IMAGE}:build
  CUSTOM_VARIABLE: "custom-value"

파이프라인 실행 정책 구성에서 이 변수 파일을 포함합니다.

# Pipeline execution policy configuration
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: 'gitlab-variables.yml'
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  stage: test
  before_script:
    - echo "CS_IMAGE = $CS_IMAGE"
    - echo "CUSTOM_VARIABLE = $CUSTOM_VARIABLE"

이 구성은 다음과 같습니다.

  1. 스캔 대상 프로젝트의 gitlab-variables.yml 파일을 포함합니다.
  2. 해당 파일에 정의된 변수를 정책 job에서 사용할 수 있게 합니다.
  3. 일관된 정책 구조를 유지하면서 각 프로젝트가 자체 변수 값을 정의할 수 있게 합니다.

중요한 고려 사항#

  • 변수 우선순위: 프로젝트 파일에서 포함한 변수는 파이프라인 실행 정책의 표준 변수 우선순위 규칙을 따릅니다.
  • 파일 위치: 변수 파일은 프로젝트 리포지터리의 어느 위치에나 둘 수 있습니다. 찾고 유지 관리하기 쉽도록 설명적인 이름과 위치를 사용합니다.
  • 전체 CI/CD 구성 포함 지양: 이 방식을 사용할 때는 전체 .gitlab-ci.yml이 아니라 변수 파일만 포함합니다. 전체 CI/CD 구성을 포함하면 job이 중복될 수 있습니다.
  • 보안: 변수 파일에 민감한 정보를 저장하지 마십시오. 민감한 데이터에는 프로젝트 또는 그룹 설정에 정의한 CI/CD 변수를 사용합니다.

대안: 프로젝트 CI/CD 설정 사용#

동적으로 설정되는 변수가 필요하지 않다면 별도 파일을 사용하는 대신 프로젝트의 CI/CD 설정(Settings > CI/CD > Variables)에서 상수를 설정할 수 있습니다. 이러한 변수는 추가 구성 없이 파이프라인 실행 정책 job에서 자동으로 사용할 수 있습니다.

파이프라인 실행 정책으로 변수 값 강제#

파이프라인 실행 정책에 정의된 변수의 값은 이름이 같은 그룹 또는 정책 변수의 값을 재정의합니다. 이 예시에서는 프로젝트의 변수 PROJECT_VAR 값이 덮어쓰여 job의 결과가 I'm a pipeline execution policy가 됩니다.

variables:
  PROJECT_VAR: "I'm a pipeline execution policy"

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

보안 정책 범위가 포함된 policy.yml 예시#

이 예시에서 보안 정책의 policy_scope는 다음과 같습니다.

  • ID가 9인 컴플라이언스 프레임워크가 적용된 모든 프로젝트를 포함합니다.
  • ID가 456인 프로젝트를 제외합니다.
pipeline_execution_policy:
- name: Pipeline execution policy
  description: ''
  enabled: true
  pipeline_config_strategy: inject_policy
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
  policy_scope:
    compliance_frameworks:
    - id: 9
    projects:
      excluding:
      - id: 456

파이프라인 실행 정책에서 ci_skip 구성#

다음 예시에서는 파이프라인 실행 정책이 강제되며, ID가 75인 사용자를 제외하고는 CI 건너뛰기가 허용되지 않습니다.

pipeline_execution_policy:
  - name: My pipeline execution policy with ci.skip exceptions
    description: 'Enforces CI/CD jobs'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: group-a/project1
          file: README.md
    skip_ci:
      allowed: false
      allowlist:
        users:
          - id: 75

파이프라인 실행 정책에서 ci_no_pipeline 구성#

다음 예시에서는 파이프라인 실행 정책이 강제되며, ID가 75인 사용자를 제외하고는 CI 생성 안 함이 허용되지 않습니다.

pipeline_execution_policy:
  - name: My pipeline execution policy with ci.no_pipeline exceptions
    description: 'Enforces CI/CD jobs'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: group-a/project1
          file: README.md
    no_pipeline:
      allowed: false
      allowlist:
        users:
          - id: 75

exists 조건 구성#

exists 규칙을 사용하면 특정 파일이 존재할 때 프로젝트의 CI/CD 구성 파일을 포함하도록 파이프라인 실행 정책을 구성할 수 있습니다.

다음 예시에서 파이프라인 실행 정책은 Dockerfile이 있으면 프로젝트의 CI/CD 구성을 포함합니다. exists 규칙의 project에는 반드시 '$CI_PROJECT_PATH'를 사용하도록 설정해야 합니다. 그렇지 않으면 GitLab은 보안 정책 CI/CD 구성을 보관하는 프로젝트에서 파일이 존재하는지를 평가합니다.

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
    rules:
      - exists:
          paths:
            - 'Dockerfile'
          project: '$CI_PROJECT_PATH'

이 방식을 사용하려면 그룹 또는 프로젝트가 override_project_ci 전략을 사용해야 합니다.

CI_JOB_TOKEN으로 파이프라인 stage와 job 검증#

.pipeline-policy-pre job에서 CI_JOB_TOKEN을 사용해 GitLab API를 호출하고, 파이프라인의 stage와 job이 승인된 stage 또는 job 목록에 있는지 검증할 수 있습니다. 이 패턴은 프로젝트가 승인되지 않은 CI/CD stage와 job을 사용하지 못하게 하려는 경우에 유용합니다.

다음 예시 스크립트는 API에서 파이프라인의 job을 가져와 고유한 stage와 job 이름을 추출하고, 각각을 APPROVED_STAGES와 APPROVED_JOBS 변수와 대조합니다. 승인되지 않은 stage나 job이 발견되면 다른 job이 실행되기 전에 파이프라인이 실패합니다.

APPROVED_STAGES와 APPROVED_JOBS는 프로젝트, 그룹 또는 정책 구성에서 CI/CD 변수로 정의합니다.

validate-pipeline:
  stage: .pipeline-policy-pre
  image: alpine:latest
  before_script:
    - apk add --no-cache curl jq bash
  script:
    - |
      #!/bin/bash

      echo "Checking pipeline stages and jobs..."

      # Fetch pipeline jobs using CI_JOB_TOKEN
      api_url="$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$CI_PIPELINE_ID/jobs"
      echo "API URL: $api_url"

      jobs=$(curl --silent --header "JOB-TOKEN: $CI_JOB_TOKEN" "$api_url")
      echo "Fetched Jobs: $jobs"

      if [[ "$jobs" == *"404 Project Not Found"* ]]; then
        echo "Failed to authenticate with GitLab API: Project not found"
        exit 1
      fi

      # Extract stages and jobs
      pipeline_stages=$(echo "$jobs" | jq -r '.[].stage' | sort | uniq | tr '\n' ',')
      pipeline_jobs=$(echo "$jobs" | jq -r '.[].name' | sort | uniq | tr '\n' ',')

      echo "Pipeline Stages: $pipeline_stages"
      echo "Pipeline Jobs: $pipeline_jobs"

      # Check if pipeline stages are approved
      for stage in $(echo $pipeline_stages | tr ',' ' '); do
        echo "Checking stage: $stage"
        if ! [[ ",$APPROVED_STAGES," =~ ",$stage," ]]; then
          echo "Stage $stage is not approved."
          exit 1
        fi
      done

      # Check if pipeline jobs are approved
      for job in $(echo $pipeline_jobs | tr ',' ' '); do
        echo "Checking job: $job"
        if ! [[ ",$APPROVED_JOBS," =~ ",$job," ]]; then
          echo "Job $job is not approved."
          exit 1
        fi
      done

파이프라인 실행 정책으로 컨테이너 스캔 component 강제#

보안 스캔 컴포넌트를 사용하면 버전 관리의 처리와 강제를 개선할 수 있습니다.

include:
  - component: gitlab.com/components/container-scanning/container-scanning@main
    inputs:
      cs_image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

container_scanning: # override component with additional configuration
  variables:
    CS_REGISTRY_USER: $CI_REGISTRY_USER
    CS_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
    SECURE_LOG_LEVEL: debug # add for verbose debugging of the container scanner
  before_script:
  - echo $CS_IMAGE # optionally add a before_script for additional debugging