Merge request approval policies
GitLab v19.4Offering: GitLab Self-Managed, GitLab Dedicated
요약
머지 리퀘스트 승인 정책은 다음을 포함한 다양한 용도로 사용할 수 있습니다. 보호된 브랜치가 생성되거나 삭제되면, 정책 승인 규칙은 1분의 지연 후 동기화됩니다. 다음 동영상은 GitLab 머지 리퀘스트 승인 정책(이전 이름: 스캔 결과 정책)에 대한 개요를 제공합니다.
머지 리퀘스트 승인 정책은 다음을 포함한 다양한 용도로 사용할 수 있습니다.
- 보안 및 라이선스 스캐너의 결과를 감지하여 승인 규칙을 적용합니다. 예를 들어, 머지 리퀘스트 정책의 한 유형인 보안 승인 정책은 하나 이상의 보안 스캔 job의 결과를 기반으로 승인이 요구되도록 설정할 수 있습니다. 머지 리퀘스트 승인 정책은 CI 스캔 job이 완전히 실행된 후 평가되며, 취약점 유형 및 라이선스 유형 정책 모두 완료된 파이프라인에 게시된 job 아티팩트 보고서를 기반으로 평가됩니다.
- 특정 조건을 충족하는 모든 머지 리퀘스트에 승인 규칙을 적용합니다. 예를 들어, 기본 브랜치를 대상으로 하는 모든 MR에 대해 Developer 및 Maintainer 권한을 가진 여러 사용자가 검토하도록 강제합니다.
- 프로젝트에 보안 및 컴플라이언스 설정을 적용합니다. 예를 들어, MR에 변경 내용을 작성하거나 커밋한 사용자가 해당 MR을 승인하지 못하도록 방지합니다. 또는 모든 변경 사항이 MR을 통해 이루어지도록 사용자가 기본 브랜치에 푸시하거나 강제 푸시하지 못하도록 방지합니다.
보호된 브랜치가 생성되거나 삭제되면, 정책 승인 규칙은 1분의 지연 후 동기화됩니다.
다음 동영상은 GitLab 머지 리퀘스트 승인 정책(이전 이름: 스캔 결과 정책)에 대한 개요를 제공합니다.
제한 사항#
- 머지 리퀘스트 승인 정책은 보호된 대상 브랜치에서만 적용할 수 있습니다.
- 각 정책에 최대 5개의 규칙을 할당할 수 있습니다.
- 각 보안 정책 프로젝트에 최대 5개의 머지 리퀘스트 승인 정책을 할당할 수 있습니다.
- 그룹 또는 하위 그룹에 대해 생성된 정책은 그룹 내 모든 머지 리퀘스트에 적용되기까지 시간이 걸릴 수 있습니다. 소요 시간은 프로젝트 수와 해당 프로젝트의 머지 리퀘스트 수에 따라 결정됩니다. 일반적으로 수 초가 소요됩니다. 이전 관측에 따르면 수천 개의 프로젝트와 머지 리퀘스트가 있는 그룹의 경우 몇 분이 걸릴 수 있습니다.
- 머지 리퀘스트 승인 정책은 아티팩트 보고서에서 생성된 스캔 결과의 무결성이나 진위 여부를 확인하지 않습니다.
- 머지 리퀘스트 승인 정책은 규칙에 따라 평가됩니다. 기본적으로 규칙이
유효하지 않거나 평가할 수 없는 경우 승인이 요구됩니다. 이 동작은
fallback_behavior필드를 통해 변경할 수 있습니다.
파이프라인 요구 사항#
히스토리
- 실패한 스캔 job 차단 기능이 GitLab 19.3에서
approval_policies_block_on_failed_scan_job이라는 - GitLab 19.4에서 기본적으로 활성화됨.
실패한 스캔 job 차단 동작의 제공 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참조합니다.
머지 리퀘스트 승인 정책은 파이프라인의 결과에 따라 적용됩니다. 머지 리퀘스트 승인 정책을 구현할 때 다음 사항을 고려합니다.
-
머지 리퀘스트 승인 정책은 완료된 파이프라인 job을 평가하며 수동 job은 무시합니다. 수동 job이 실행되면 정책은 머지 리퀘스트의 job을 재평가합니다.
-
보안 스캐너의 결과를 평가하는 머지 리퀘스트 승인 정책의 경우, 지정된 모든 스캐너가 보안 보고서를 출력해야 합니다. 그렇지 않으면 취약점이 유입되는 위험을 최소화하기 위해 승인이 강제됩니다. 이 동작은 다음에 영향을 줄 수 있습니다.
- 보안 스캔이 아직 설정되지 않은 신규 프로젝트.
- 보안 스캔이 구성되기 전에 생성된 브랜치.
- 브랜치 간 스캐너 구성이 일관되지 않은 프로젝트.
-
파이프라인은 소스 브랜치와 대상 브랜치 모두에서 활성화된 모든 스캐너에 대한 아티팩트를 생성해야 합니다. 그렇지 않으면 비교 기준이 없으므로 정책을 안정적으로 평가할 수 없습니다. 자세한 내용은 보안 스캔 누락을 참조합니다. 이 요구 사항을 적용하려면 스캔 실행 정책을 사용해야 합니다.
-
정책 평가는 성공적으로 완료된 병합 베이스 파이프라인에 의존합니다. 병합 베이스 파이프라인이 건너뛰어지면 해당 병합 베이스 파이프라인이 있는 머지 리퀘스트가 차단됩니다.
-
정책에 지정된 보안 스캐너는 정책이 적용되는 프로젝트에서 구성 및 활성화되어 있어야 합니다. 그렇지 않으면 머지 리퀘스트 승인 정책을 평가할 수 없으며 해당 승인이 요구됩니다.
-
정책 규칙에서 요구하는 스캐너의 CI job이 성공하지 못하고 종료되어 보안 보고서를 생성하지 못하면, 동일 파이프라인의 다른 스캐너가 성공했더라도 승인이 필요합니다 — 이 검사를 트리거하는 job 상태는
failed,canceled,canceling뿐입니다. 비종료 상태(created,pending,running)와manual또는skippedjob은 트리거하지 않습니다. 이 검사는 규칙이 실제로 나열한 스캐너로 범위가 제한됩니다. 이 검사는 기존fallback_behavior경로를 거칩니다.fail: closed(기본값)는 머지 리퀘스트를 차단하고,fail: open은 차단하지 않지만 권고 메시지를 표시합니다. 취소되거나 실패한 스캔 job은 불완전한 결과를 낼 수 있으므로 모든 보안 스캔 job이 성공적으로 완료되었는지 확인합니다.[!note] Dependency Scanning v2의 경우, 확인(resolution) job(예:
dependency-scanning:maven-resolution)은.pre스테이지에서 실행되며artifacts:paths만 선언하고artifacts:reports:는 선언하지 않습니다. 따라서 확인 job의 실패는 이 검사에 보이지 않으며, 하위dependency-scanningjob은 그래도 성공하여 보고서를 업로드할 수 있습니다. 이는 DS v2 토폴로지의 예상된 동작이며 이슈 607109에서 추적됩니다.
머지 리퀘스트 승인 정책과 함께 보안 스캐너를 사용하기 위한 모범 사례#
새 프로젝트를 생성할 때 해당 프로젝트에 머지 리퀘스트 승인 정책과 보안 스캔을 모두 적용할 수 있습니다. 그러나 잘못 구성된 보안 스캐너는 머지 리퀘스트 승인 정책에 영향을 줄 수 있습니다.
새 프로젝트에서 보안 스캔을 구성하는 방법은 여러 가지가 있습니다.
- 초기
.gitlab-ci.yml구성 파일에 스캐너를 추가하여 프로젝트의 CI/CD 구성에서 설정합니다. - 스캔 실행 정책을 통해 파이프라인이 특정 보안 스캐너를 실행하도록 강제합니다.
- 파이프라인 실행 정책을 통해 파이프라인에서 실행해야 하는 job을 제어합니다.
간단한 사용 사례의 경우 프로젝트의 CI/CD 구성을 사용할 수 있습니다. 포괄적인 보안 전략을 위해서는 머지 리퀘스트 승인 정책을 다른 정책 유형과 결합하는 것을 고려합니다.
불필요한 승인 요구 사항을 최소화하고 정확한 보안 평가를 보장하려면 다음을 따릅니다.
- 먼저 기본 브랜치에서 보안 스캔 실행: 피처 브랜치를 생성하기 전에 기본 브랜치에서 보안 스캔이 성공적으로 실행되었는지 확인합니다.
- 일관된 스캐너 구성 사용: 소스 브랜치와 대상 브랜치 모두에서 동일한 스캐너를 실행하며, 가능하면 단일 파이프라인에서 실행합니다.
- 스캔이 아티팩트를 생성하는지 확인: 스캔이 성공적으로 완료되어 비교를 위한 아티팩트가 생성되는지 확인합니다.
- 브랜치를 동기화 상태로 유지: 기본 브랜치의 변경 사항을 피처 브랜치에 정기적으로 병합합니다.
- 파이프라인 구성 고려: 새 프로젝트의 경우, 초기
.gitlab-ci.yml구성에 보안 스캐너를 포함합니다.
머지 리퀘스트 승인 정책을 적용하기 전에 보안 스캐너 검증#
새 프로젝트에 머지 리퀘스트 승인 정책을 적용하기 전에 보안 스캔을 구현해 두면, 머지 리퀘스트 승인 정책에 의존하기 전에 보안 스캐너가 일관되게 실행되도록 보장할 수 있으며, 보안 스캔 누락으로 인해 머지 리퀘스트가 차단되는 상황을 방지하는 데 도움이 됩니다.
보안 스캐너와 머지 리퀘스트 승인 정책을 함께 생성하고 검증하려면 다음 권장 워크플로를 사용합니다.
- 프로젝트를 생성합니다.
.gitlab-ci.yml구성, 스캔 실행 정책, 또는 파이프라인 실행 정책을 사용하여 보안 스캐너를 구성합니다.- 기본 브랜치에서 초기 파이프라인이 완료될 때까지 기다립니다. 문제를 해결하고 파이프라인을 재실행하여 계속 진행하기 전에 성공적으로 완료되는지 확인합니다.
- 동일한 보안 스캐너가 구성된 피처 브랜치를 사용하여 머지 리퀘스트를 생성합니다. 마찬가지로 보안 스캐너가 성공적으로 완료되는지 확인합니다.
- 머지 리퀘스트 승인 정책을 적용합니다.
여러 파이프라인이 있는 머지 리퀘스트#
히스토리
- GitLab 16.11에서
approval_policy_parent_child_pipeline이라는 기능 플래그와 함께 부모-자식 파이프라인 지원이 도입됨. 기본적으로 비활성화됨. - GitLab 17.0에서 GitLab.com에서 활성화됨.
- GitLab 17.1에서 일반적으로 사용 가능해짐. 기능 플래그
approval_policy_parent_child_pipeline제거됨.
프로젝트에는 여러 파이프라인 유형이 구성될 수 있습니다. 단일 커밋은 여러 파이프라인을 시작할 수 있으며, 각 파이프라인에는 보안 스캔이 포함될 수 있습니다.
머지 리퀘스트의 소스 브랜치와 대상 브랜치의 최신 커밋에 대해 완료된 모든 파이프라인의 결과가 평가되어 머지 리퀘스트 승인 정책을 적용하는 데 사용됩니다. 온디맨드 DAST 파이프라인은 고려되지 않습니다.
프로젝트에서 머지 리퀘스트 파이프라인을 사용하는 경우, 파이프라인에 보안 스캐닝 job이 포함되도록 CI/CD 변수 AST_ENABLE_MR_PIPELINES를 "true"로 설정해야 합니다.
자세한 내용은 머지 리퀘스트 파이프라인에서 보안 스캐닝 도구 사용을 참조합니다.
최신 커밋에서 많은 파이프라인이 실행된 프로젝트(예: 휴면 프로젝트)의 경우, 정책 평가는 머지 리퀘스트의 소스 브랜치와 대상 브랜치에서 최대 1,000개의 파이프라인을 고려합니다.
부모-자식 파이프라인의 경우, 정책 평가는 최대 1,000개의 자식 파이프라인을 고려합니다.
머지 리퀘스트 승인 정책 편집기#
Security Policy Project를 선택할 수 있는 권한은 프로젝트 Owner에게만 있습니다.
정책이 완료되면, 편집기 하단의 Configure with a merge request를 선택하여 저장합니다. 이렇게 하면 프로젝트에 구성된 보안 정책 프로젝트의 머지 리퀘스트로 리디렉션됩니다. 보안 정책 프로젝트가 프로젝트에 연결되어 있지 않으면 GitLab이 해당 프로젝트를 생성합니다. 편집기 인터페이스에서 Delete policy를 선택하여 기존 정책을 제거할 수도 있습니다.
대부분의 정책 변경 사항은 머지 리퀘스트가 병합되는 즉시 적용됩니다. 머지 리퀘스트를 거치지 않고 기본 브랜치에 직접 커밋되는 변경 사항은 정책 변경이 적용되기까지 최대 10분이 소요될 수 있습니다.
정책 편집기는 YAML 모드와 규칙 모드를 지원합니다.
프로젝트가 많은 그룹에 대해 생성된 머지 리퀘스트 승인 정책을 전파하는 데는 시간이 걸립니다.
머지 리퀘스트 승인 정책 목록 스키마#
머지 리퀘스트 승인 정책이 포함된 YAML 파일은 approval_policy 키 아래에 중첩된 머지 리퀘스트 승인
정책 스키마와 일치하는 오브젝트 배열로 구성됩니다. approval_policy 키 아래에 최대 5개의 정책을 구성할 수 있습니다.
머지 리퀘스트 승인 정책은 scan_result_policy 키 아래에 정의되었습니다. GitLab 17.0까지는 두 키
모두에서 정책을 정의할 수 있습니다. GitLab 17.0부터는 approval_policy 키만 지원됩니다.
새 정책을 저장하면 GitLab은 이 JSON 스키마에 따라 내용을 검증합니다. JSON 스키마 읽는 방법에 익숙하지 않다면, 다음 섹션과 표를 참고합니다.
| 필드 | 유형 | 필수 여부 | 설명 |
|---|---|---|---|
approval_policy |
머지 리퀘스트 승인 정책 오브젝트의 array |
true | 머지 리퀘스트 승인 정책 목록(최대 5개). |
머지 리퀘스트 승인 정책 스키마#
히스토리
enforcement_type필드:security_policy_approval_warn_mode라는 기능 플래그와 함께 GitLab 18.4에서 도입됨.- GitLab 18.6에서 GitLab.com에서 활성화됨. 기능 플래그
security_policy_approval_warn_mode제거됨. - GitLab 18.9에서 일반적으로 사용 가능해짐. 기능 플래그
security_policy_approval_warn_mode제거됨.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
name |
string |
true | 정책 이름입니다. 최대 255자. | |
description |
string |
false | 정책 설명입니다. | |
enabled |
boolean |
true | true, false |
정책을 활성화(true)하거나 비활성화(false)하는 플래그입니다. |
rules |
rules의 array |
true | 정책이 적용하는 규칙 목록입니다. | |
actions |
actions의 array |
false | 정책이 적용하는 액션 목록입니다. | |
approval_settings |
object |
false | 정책이 재정의하는 프로젝트 설정입니다. | |
fallback_behavior |
object |
false | 유효하지 않거나 적용할 수 없는 규칙에 영향을 미치는 설정입니다. | |
policy_scope |
policy_scope의 object |
false | 지정한 프로젝트, 그룹 또는 컴플라이언스 프레임워크 레이블을 기반으로 정책 범위를 정의합니다. | |
policy_tuning |
object |
false | (실험 기능) 정책 비교 로직에 영향을 미치는 설정입니다. | |
bypass_settings |
object |
false | 특정 브랜치, 토큰 또는 계정이 정책을 우회할 수 있는 경우에 영향을 미치는 설정입니다. | |
enforcement_type |
string |
false | enforce, warn |
정책 적용 방식을 정의합니다. 기본값(지정하지 않은 경우)은 enforce로, 위반이 감지되면 머지 리퀘스트를 차단합니다. warn 값은 머지 리퀘스트가 진행되도록 허용하지만 경고와 봇 댓글을 표시합니다. |
scan_finding 규칙 유형#
히스토리
vulnerability_states옵션의newly_detected는 GitLab 17.0에서 제거되었으며, 이를 대체하는new_needs_triage와new_dismissed옵션이 추가되었습니다.
이 규칙은 보안 스캔 결과를 기반으로 정의된 액션을 적용합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
type |
string |
true | scan_finding |
규칙의 유형입니다. |
branches |
string의 array |
branch_type 필드가 없는 경우 true |
[] 또는 브랜치 이름 |
보호된 대상 브랜치에만 적용됩니다. 빈 배열 []은 모든 보호된 대상 브랜치에 규칙을 적용합니다. branch_type 필드와 함께 사용할 수 없습니다. |
branch_type |
string |
branches 필드가 없는 경우 true |
default 또는 protected |
해당 정책이 적용되는 보호된 브랜치의 유형입니다. branches 필드와 함께 사용할 수 없습니다. 기본 브랜치는 보호된 브랜치여야 합니다. |
branch_exceptions |
string의 array |
false | 브랜치 이름 | 이 규칙에서 제외할 대상 브랜치입니다. |
scanners |
string의 array 또는 scanner_with_attributes 오브젝트 |
true | [] 또는 sast, secret_detection, dependency_scanning, container_scanning, dast, coverage_fuzzing, api_fuzzing |
이 규칙에서 고려할 보안 스캐너입니다. sast는 SAST 및 SAST IaC 스캐너의 결과를 모두 포함합니다. 빈 배열 []은 모든 보안 스캐너에 규칙을 적용합니다. 스캐너는 문자열(규칙 수준 설정 적용)이나 오브젝트(스캐너별 severity_levels, vulnerabilities_allowed, vulnerability_attributes 재정의)로 지정합니다. |
vulnerabilities_allowed |
integer |
true | 0 이상 | 이 규칙이 적용되기 전에 허용되는 취약점 수입니다. |
severity_levels |
string의 array |
true | info, unknown, low, medium, high, critical |
이 규칙에서 고려할 심각도 수준입니다. |
vulnerability_states |
string의 array |
true | [] 또는 detected, confirmed, resolved, dismissed, new_needs_triage, new_dismissed |
모든 취약점은 두 가지 범주로 나뉩니다. 신규 탐지 취약점 - 머지 리퀘스트 브랜치에서는 식별되었지만 MR의 대상 브랜치에는 현재 존재하지 않는 취약점입니다. 이 정책 옵션은 취약점이 신규 탐지인지 여부를 판단할 수 있도록 규칙 평가 전에 파이프라인이 완료되어야 합니다. 파이프라인과 필요한 보안 스캔이 완료될 때까지 머지 리퀘스트가 차단됩니다. new_needs_triage 옵션은 다음 상태를 고려합니다.• Detected new_dismissed 옵션은 다음 상태를 고려합니다.• Dismissed 기존 취약점 - 이 정책 옵션은 즉시 평가되며 기본 브랜치에서 이전에 탐지된 취약점만 고려하므로 파이프라인 완료가 필요하지 않습니다. • Detected - 정책이 탐지됨 상태의 취약점을 찾습니다.• Confirmed - 정책이 확인됨 상태의 취약점을 찾습니다.• Dismissed - 정책이 기각됨 상태의 취약점을 찾습니다.• Resolved - 정책이 해결됨 상태의 취약점을 찾습니다. 빈 배열 []은 ['new_needs_triage', 'new_dismissed']와 동일한 상태를 포함합니다. |
vulnerability_attributes |
object |
false | vulnerability_attributes 오브젝트 |
기본적으로 모든 취약점 결과가 고려됩니다. 특정 기준과 일치하는 취약점 결과만 고려하려면 이 필터를 적용합니다. 자세한 내용은 vulnerability_attributes 오브젝트를 참조합니다. |
vulnerability_age |
object |
false | N/A | 기존 취약점 결과를 수명으로 필터링합니다. 취약점의 수명은 프로젝트에서 처음 탐지된 이후 경과한 시간으로 계산됩니다. 기준은 operator, value, interval입니다.- operator 기준은 수명 비교 방식이 이전(greater_than)인지 이후(less_than)인지를 지정합니다.- value 기준은 취약점 수명을 나타내는 숫자 값을 지정합니다.- interval 기준은 취약점 수명의 측정 단위(day, week, month, year)를 지정합니다.예: operator: greater_than, value: 30, interval: day. |
vulnerability_attributes 오브젝트#
히스토리
known_exploited,epss_score,enrichment_data_unavailable필드가security_policies_kev_filter라는 기능 플래그와 함께 GitLab 18.11에서 도입됨. 기본적으로 비활성화됨.- GitLab 19.1에서 일반적으로 사용 가능해짐. 기능 플래그
security_policies_kev_filter제거됨.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
false_positive |
boolean |
false | true, false |
거짓 양성 상태로 필터링합니다. true는 거짓 양성만 포함하고, false는 제외합니다. |
fix_available |
boolean |
false | true, false |
수정 가능 여부로 필터링합니다. true는 수정 가능한 취약점만 포함하고, false는 수정 불가능한 취약점만 포함합니다. |
known_exploited |
boolean |
false | true, false |
CISA의 알려진 악용 취약점(KEV) 카탈로그를 기반으로 필터링합니다. true이면 실제로 악용되고 있는 취약점만 포함합니다. false이면 알려진 악용 상태를 기준으로 취약점을 필터링하지 않습니다. |
epss_score |
object |
false | {operator, value} 오브젝트 |
익스플로잇 예측 스코어링 시스템(EPSS) 점수를 기반으로 필터링합니다. EPSS는 취약점이 악용될 확률(0operator는 greater_than 또는 less_than이 가능하며, value는 0.01.0 사이의 숫자입니다. 예: {operator: greater_than, value: 0.8}. |
enrichment_data_unavailable |
object |
false | {action: "block"} 또는 {action: "ignore"} |
EPSS 점수나 알려진 악용 상태 등 보강 데이터를 사용할 수 없는 CVE 취약점의 처리 방식을 정의합니다. block이면 보강 데이터가 없는 취약점은 규칙 수준 기준에 따라 평가됩니다. ignore이면 보강 데이터가 없는 취약점은 정책 평가에서 제외됩니다. |
scanner_with_attributes 오브젝트#
히스토리
atomic_scanner_rule_criteria라는 기능 플래그와 함께 GitLab 18.10에서 도입됨. 기본적으로 활성화됨. GitLab 18.11에서 일반적으로 사용 가능해짐. 기능 플래그 제거됨.
이 기능의 제공 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참조합니다.
스캐너를 문자열 대신 오브젝트로 지정하면 각 스캐너 유형이 자체 기준에 따라 독립적으로 평가됩니다. 스캐너 수준에서 지정되지 않은 필드는 규칙 수준 값으로 정의된 설정을 따릅니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
type |
string |
true | sast, secret_detection, dependency_scanning, container_scanning, dast, coverage_fuzzing, api_fuzzing |
스캐너 유형입니다. |
severity_levels |
string의 array |
false | info, unknown, low, medium, high, critical |
이 스캐너에 대해 규칙 수준의 severity_levels를 재정의합니다. |
vulnerabilities_allowed |
integer |
false | 0 이상 | 이 스캐너에 대해 규칙 수준의 vulnerabilities_allowed를 재정의합니다. |
vulnerability_attributes |
object |
false | vulnerability_attributes 오브젝트 |
이 스캐너에 대해 규칙 수준의 vulnerability_attributes를 재정의합니다. |
is_malicious |
boolean |
false | true, false |
true이면 이 스캐너가 악성 패키지로 식별한 결과는 severity_levels와 vulnerability_states 필터와 무관하게, 심지어 결과가 기각된 경우에도 위반으로 처리됩니다. dependency_scanning에만 유효합니다. 자세한 내용은 멀웨어 규칙으로 악성 패키지 차단을 참조합니다. |
스캐너별 기준을 사용하는 예시:
rules:
- type: scan_finding
branches: []
scanners:
- type: dependency_scanning
vulnerability_attributes:
fix_available: true
vulnerabilities_allowed: 0
severity_levels:
- critical
- high
- type: container_scanning
vulnerability_attributes:
known_exploited: true
epss_score:
value: 0.5
operator: greater_than
enrichment_data_unavailable:
action: block
vulnerabilities_allowed: 0
severity_levels:
- critical
vulnerabilities_allowed: 5
severity_levels:
- critical
- high
- medium
vulnerability_states:
- new_needs_triage
이 예시에서:
- **의존성 스캐닝(Dependency scanning)**은 수정 가능한 critical 또는 high 심각도 취약점이 탐지되면 승인을 요구합니다.
- **컨테이너 스캐닝(Container scanning)**은 critical이면서 실제로 악용되고 있는 취약점이 탐지되면 승인을 요구합니다.
- 각 스캐너는 자체 임계값에 따라 독립적으로 평가됩니다. 규칙 수준의
vulnerabilities_allowed: 5와severity_levels는 명시적 재정의가 없는 스캐너의 기본값으로 사용됩니다.
멀웨어 규칙으로 악성 패키지 차단#
히스토리
- GitLab 19.2에서
security_policies_malware_attribute라는 기능 플래그와 함께 도입됨. 기본적으로 비활성화됨. - GitLab 19.4에서 기본적으로 활성화됨.
이 기능의 제공 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참조합니다.
is_malicious 스캐너 속성을 사용하면 스캔에서 GitLab 멀웨어 권고에
등재된 패키지가 탐지되었을 때 머지 리퀘스트를 차단할 수 있습니다. 악성 결과는 즉각적인
위험을 초래하므로, 규칙의 다른 기준과 일치하지 않는 경우에도 항상 위반으로
처리됩니다. 이 규칙은 결과가 기각되었거나 severity_levels와
vulnerability_states 필터에서 벗어나 있는 경우에도 악성 결과를
차단합니다.
is_malicious 속성은 dependency_scanning과 container_scanning 스캐너에만 유효합니다.
악성 결과는 다른 취약점에 사용되는 CVE나 CWE 식별자가 아니라 GLAM- 식별자로
식별됩니다. 멀웨어 권고는 의존성 스캐닝이 지원하는 패키지 유형만 다루므로,
container_scanning 스캐너는 악성 결과를 생성하지 않습니다. 지원되는 전체
패키지 유형 목록은
지원되는 패키지 유형을 참조합니다.
스캐너에 is_malicious: true를 설정하면 규칙은 해당 스캐너를 OR 조건으로
평가합니다. 머지 리퀘스트는 멀웨어가 탐지되거나 결과가 다른 규칙 기준과
일치할 때, 또는 둘 다에 해당할 때 위반으로 처리됩니다. 예를 들어 다음 규칙은
의존성 스캐닝이 악성 패키지를 탐지하거나 critical 심각도의 결과를 탐지할 때
승인을 요구합니다.
rules:
- type: scan_finding
branches: []
scanners:
- type: dependency_scanning
is_malicious: true
- type: dependency_scanning
vulnerabilities_allowed: 0
severity_levels:
- critical
vulnerability_states:
- new_needs_triage
악성 결과는 다른 스캔 결과 위반과 함께 머지 리퀘스트 정책 봇 댓글에 위반으로 표시됩니다.
멀웨어 규칙과 경고 모드의 상호작용은 에픽 19465에서 제안되었습니다.
license_finding 규칙 유형#
이 규칙은 라이선스 결과를 기반으로 정의된 액션을 적용합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
type |
string |
true | license_finding |
규칙의 유형입니다. |
branches |
string의 array |
branch_type 필드가 없는 경우 true |
[] 또는 브랜치 이름 |
보호된 대상 브랜치에만 적용됩니다. 빈 배열 []은 모든 보호된 대상 브랜치에 규칙을 적용합니다. branch_type 필드와 함께 사용할 수 없습니다. |
branch_type |
string |
branches 필드가 없는 경우 true |
default 또는 protected |
해당 정책이 적용되는 보호된 브랜치의 유형입니다. branches 필드와 함께 사용할 수 없습니다. 기본 브랜치는 보호된 브랜치여야 합니다. |
branch_exceptions |
string의 array |
false | 브랜치 이름 | 이 규칙에서 제외할 대상 브랜치입니다. |
match_on_inclusion_license |
boolean |
licenses 필드가 없는 경우 true |
true, false |
규칙이 license_types에 나열된 라이선스의 포함 또는 제외 여부를 기준으로 매칭할지 결정합니다. |
license_types |
string의 array |
licenses 필드가 없는 경우 true |
라이선스 유형 | 매칭할 SPDX 라이선스 이름입니다. 예: Affero General Public License v1.0 또는 MIT License. |
license_states |
string의 array |
true | newly_detected, detected |
새로 탐지된 라이선스나 이전에 탐지된 라이선스를 매칭할지 여부입니다. newly_detected 상태는 새 패키지가 도입되거나 기존 패키지에 새 라이선스가 탐지될 때 승인을 트리거합니다. |
licenses |
object |
license_types 필드가 없는 경우 true |
licenses 오브젝트 |
패키지 예외를 포함하여 매칭할 SPDX 라이선스 이름입니다. |
licenses 오브젝트#
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
denied |
object |
allowed 필드가 없는 경우 true |
licenses_with_package_exclusion 오브젝트의 array |
패키지 예외를 포함한 거부된 라이선스 목록입니다. |
allowed |
object |
denied 필드가 없는 경우 true |
licenses_with_package_exclusion 오브젝트의 array |
패키지 예외를 포함한 허용된 라이선스 목록입니다. |
licenses_with_package_exclusion 오브젝트#
licenses_with_package_exclusion 오브젝트를 사용하여 라이선스 이름과 선택적
패키지 제외를 정의합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
name |
string |
true | SPDX 라이선스 이름 | SPDX 라이선스 이름입니다. |
packages |
object |
false | packages 오브젝트 |
지정된 라이선스에 대한 패키지 예외 목록입니다. |
name 필드는 유효한 SPDX 라이선스 이름이어야 합니다.
unknown 값은 인식되는 SPDX 라이선스 이름이 아니며 licenses 필드에서
지원되지 않습니다. unknown 라이선스에 대해 구성된 패키지 수준 제외는
머지 리퀘스트 승인 평가 시 무시됩니다. unknown 라이선스가 있는 패키지를
관리하려면 license_types 필드를 사용하거나 정책에서
unknown을 라이선스로 허용합니다. 자세한 내용은
라이선스 승인 정책이 unknown 라이선스로 인해 머지 리퀘스트를 차단하는 경우를 참조합니다.
packages 오브젝트#
packages 오브젝트를 사용하여 라이선스 항목에 대한 패키지 URL 제외를 정의합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
excluding |
object |
true | {purls: uri 형식을 사용하는 string의 array} |
지정된 라이선스에 대한 패키지 예외 목록입니다. purl 구성 요소 scheme:type/name@version을 사용하여 패키지 예외 목록을 정의합니다. scheme:type/name 구성 요소는 필수입니다. @와 version은 선택 사항입니다. 버전을 지정하면 해당 버전만 예외로 처리됩니다. 버전을 지정하지 않고 purl 끝에 @ 문자를 추가하면 정확히 그 이름의 패키지만 매칭으로 처리됩니다. 패키지 이름에 @ 문자를 추가하지 않으면 지정된 라이선스에 대해 동일한 접두사를 사용하는 모든 패키지가 매칭됩니다. 예를 들어 purl pkg:gem/bundler는 bundler와 bundler-stats 패키지가 동일한 라이선스를 사용하므로 두 패키지 모두와 매칭됩니다. purl pkg:gem/bundler@를 정의하면 bundler 패키지만 매칭됩니다. |
any_merge_request 규칙 유형#
이 규칙은 커밋 서명을 기반으로 모든 머지 리퀘스트에 대해 정의된 액션을 적용합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
type |
string |
true | any_merge_request |
규칙의 유형입니다. |
branches |
string의 array |
branch_type 필드가 없는 경우 true |
[] 또는 브랜치 이름 |
보호된 대상 브랜치에만 적용됩니다. 빈 배열 []은 모든 보호된 대상 브랜치에 규칙을 적용합니다. branch_type 필드와 함께 사용할 수 없습니다. |
branch_type |
string |
branches 필드가 없는 경우 true |
default 또는 protected |
해당 정책이 적용되는 보호된 브랜치의 유형입니다. branches 필드와 함께 사용할 수 없습니다. 기본 브랜치는 보호된 브랜치여야 합니다. |
branch_exceptions |
string의 array |
false | 브랜치 이름 | 이 규칙에서 제외할 대상 브랜치입니다. |
commits |
string |
true | any, unsigned |
규칙이 모든 커밋과 매칭할지, 머지 리퀘스트에서 서명되지 않은 커밋이 탐지된 경우에만 매칭할지 결정합니다. |
require_approval 액션 유형#
히스토리
- 최대 5개의 별도
require_approval액션 지정 지원: - GitLab 17.7에서
multiple_approval_actions라는 기능 플래그와 함께 추가됨. - GitLab 17.8에서 일반적으로 사용 가능해짐. 기능 플래그
multiple_approval_actions제거됨. role_approvers로 커스텀 권한을 지정하는 기능 지원:- GitLab 17.9에서
security_policy_custom_roles라는 기능 플래그와 함께 도입됨. 기본적으로 활성화됨. - GitLab 17.10에서 일반적으로 사용 가능해짐. 기능 플래그
security_policy_custom_roles제거됨.
이 액션은 정의된 정책의 규칙 중 적어도 하나에 대한 조건이 충족될 때 승인 규칙을 필수로 만듭니다.
동일한 require_approval 블록에 여러 승인자를 지정하면 적격한 승인자 중 누구든지 승인 요건을 충족할 수 있습니다. 예를 들어 두 개의 group_approvers와 approvals_required를 2로 지정하면 두 승인 모두 동일한 그룹에서 이루어질 수 있습니다. 고유한 승인자 유형으로부터 여러 승인을 요구하려면 여러 require_approval 액션을 사용합니다.
| 필드 | 유형 | 필수 여부 | 가능한 값 | 설명 |
|---|---|---|---|---|
type |
string |
true | require_approval |
액션의 유형입니다. |
approvals_required |
integer |
true | 0 이상 | 필요한 MR 승인 수입니다. |
user_approvers |
string의 array |
조건부 | 한 명 이상 사용자의 사용자 이름 | 승인자로 고려할 사용자입니다. 승인 자격을 얻으려면 사용자가 프로젝트에 접근 가능해야 합니다. |
user_approvers_ids |
integer의 array |
조건부 1 | 한 명 이상 사용자의 ID | 승인자로 고려할 사용자의 ID입니다. 승인 자격을 얻으려면 사용자가 프로젝트에 접근 가능해야 합니다. |
group_approvers |
string의 array |
조건부 1 | 한 개 이상 그룹의 경로 | 승인자로 고려할 그룹입니다. 그룹에 직접 소속된 사용자가 승인 자격을 가집니다. |
group_approvers_ids |
integer의 array |
조건부 1 | 한 개 이상 그룹의 ID | 승인자로 고려할 그룹의 ID입니다. 그룹에 직접 소속된 사용자가 승인 자격을 가집니다. |
role_approvers |
string의 array |
조건부 1 | 하나 이상의 권한(예: owner, maintainer). 머지 리퀘스트를 승인할 권한이 있는 커스텀 권한(또는 YAML 모드에서 커스텀 권한 식별자)도 role_approvers로 지정할 수 있습니다. 커스텀 권한은 사용자 및 그룹 승인자와 함께 선택할 수 있습니다. |
승인 자격이 있는 권한입니다. 지정한 정확한 권한을 가진 사용자, 또는 그 권한을 기반으로 하는 커스텀 권한을 가진 사용자만 승인할 수 있습니다. 더 높은 권한을 가진 사용자는 승인할 수 없습니다. 예를 들어 developer를 선택하면 Developer 권한을 가진 사용자가 승인할 수 있습니다. developer를 기반으로 하는 커스텀 권한이 있으면 해당 커스텀 권한을 가진 사용자도 승인할 수 있습니다. Maintainer와 Owner는 명시적으로 추가하지 않는 한 승인할 수 없습니다. |
각주:
- 승인자 필드(
user_approvers,user_approvers_ids,group_approvers,group_approvers_ids,role_approvers) 중 적어도 하나를 사용하여 승인자를 지정해야 합니다.
유효한 설정 예시#
유효한 user_approvers:
actions:
- type: require_approval
approvals_required: 2
user_approvers:
- alice
- bob
유효한 group_approvers:
actions:
- type: require_approval
approvals_required: 1
group_approvers:
- security-team
유효한 role_approvers:
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- maintainer
여러 승인자 유형을 사용하는 유효한 예시:
actions:
- type: require_approval
approvals_required: 2
user_approvers:
- alice
group_approvers:
- security-team
role_approvers:
- maintainer
유효하지 않은 설정 예시#
승인자가 지정되지 않아 유효하지 않은 예시:
actions:
- type: require_approval
approvals_required: 2
# ERROR: At least one approver field must be specified
# This configuration will fail validation
send_bot_message 액션 유형#
히스토리
- 프로젝트에 대한
send_bot_message액션 유형: approval_policy_disable_bot_comment라는 기능 플래그와 함께 GitLab 16.11에서 도입됨. 기본적으로 비활성화됨.- GitLab 17.0에서 GitLab Self-Managed 및 GitLab Dedicated에서 활성화됨.
- GitLab 17.3에서 일반적으로 사용 가능해짐. 기능 플래그
approval_policy_disable_bot_comment제거됨. - 그룹에 대한
send_bot_message액션 유형: approval_policy_disable_bot_comment_group이라는 기능 플래그와 함께 GitLab 17.2에서 도입됨. 기본적으로 비활성화됨.- GitLab 17.2에서 GitLab Self-Managed 및 GitLab Dedicated에서 활성화됨.
- GitLab 17.3에서 일반적으로 사용 가능해짐. 기능 플래그
approval_policy_disable_bot_comment_group제거됨. visibility필드가 GitLab 19.4에서 도입됨.
이 액션을 사용하면 정책 위반이 감지될 때 머지 리퀘스트의 봇 메시지를 구성할 수 있습니다.
액션을 지정하지 않으면 봇 메시지는 기본적으로 활성화됩니다. 여러 정책이 정의된 경우,
해당 정책 중 적어도 하나에서 send_bot_message 액션이 활성화되어 있으면 봇 메시지가 전송됩니다.
| Field | Type | Required | Possible values | Description |
|---|---|---|---|---|
type |
string |
true | send_bot_message |
액션의 유형입니다. |
enabled |
boolean |
true | true, false |
정책 위반이 감지될 때 봇 메시지를 생성할지 여부입니다. 기본값: true |
visibility |
string |
false | public, internal |
봇 메시지를 공개로 표시할지, 내부 노트로 표시하여 Reporter 이상 권한을 가진 프로젝트 멤버에게만 보이도록 할지 결정합니다. 기본값: public. 위반된 여러 정책이 동일한 머지 리퀘스트에 서로 다른 공개 범위 설정을 적용하는 경우, 그중 하나라도 internal을 설정했으면 댓글은 내부용이 됩니다. 정책 변경으로 기존 공개 댓글이 내부용으로 바뀌면, GitLab은 기존 댓글을 삭제하고 다음 정책 평가 시 새 내부용 댓글을 게시하며, 이 과정에서 해당 댓글에 달린 답글은 모두 사라집니다. GitLab은 기존 내부용 댓글을 다시 공개로 바꾸지는 않습니다. |
봇 메시지 예시#


경고 모드#
히스토리
security_policy_approval_warn_mode라는 기능 플래그와 함께 GitLab 17.8에서 도입됨. 기본적으로 비활성화됨- GitLab 18.6에서 GitLab.com, GitLab Self-Managed 및 GitLab Dedicated에서 활성화됨.
- 라이선스 스캐닝 지원:
security_policy_warn_mode_license_scanning이라는 기능 플래그와 함께 GitLab 18.7에서 도입됨. 기본적으로 활성화됨.- GitLab 18.9에서 일반적으로 사용 가능해짐. 기능 플래그
security_policy_approval_warn_mode제거됨.
이 기능의 제공 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참조합니다.
경고 모드를 사용하면 보안 팀이 전체 적용 전에 보안 정책의 영향을 테스트하고 검증할 수 있어, 새 보안 정책 적용 시 개발자와의 마찰을 줄일 수 있습니다. 정책이 enforcement_type: warn으로 구성되면, 머지 리퀘스트는 머지 리퀘스트 승인 정책 위반을 우회할 수 있는 옵션을 제공합니다.
경고 모드가 활성화된 상태(enforcement_type: warn)에서 머지 리퀘스트가 보안 정책 위반을 트리거하면, 정책 적용 방식이 여러 면에서 달라집니다.
- 차단하지 않는 유효성 검사: 정책은 정책 위반 목록을 나열하는 정보성 봇 댓글을 생성합니다.
- 선택적 승인: 사용자가 정책을 우회하고 우회 사유를 제공하면 승인은 선택 사항이 됩니다.
- 강화된 감사: 보안 정책이 우회된 상태로 머지 리퀘스트가 병합된 후 감사 이벤트가 생성됩니다. 감사 이벤트는 우회가 발생했다는 사실은 기록하지만, 우회 댓글이나 우회 사유는 포함하지 않습니다.
- 취약점 리포트 통합: 우회된 정책이 있는 머지 리퀘스트로 인해 취약점이 도입된 경우, 우회 세부 정보가 취약점 리포트에 표시됩니다.
- 의존성 목록 통합: 정책을 우회하는 머지 리퀘스트가 라이선스를 도입하면, 의존성 목록은 해당 라이선스 옆에 정책 위반 배지를 표시합니다. 정책 위반 배지는 프로젝트의 의존성 목록에서만 사용할 수 있습니다.
- 비활성화된 승인 설정: 승인 설정 재정의는 적용되지 않습니다.
경고 모드 설정#
머지 리퀘스트 승인 정책에 경고 모드를 활성화하려면 enforcement_type 필드를 warn으로 설정합니다.
approval_policy:
- name: Warn mode policy
description: ''
enabled: true
enforcement_type: warn
policy_scope:
projects:
excluding: []
rules:
- type: scan_finding
scanners:
- secret_detection
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- maintainer
- type: send_bot_message
enabled: true
approval_settings#
히스토리
block_group_branch_modification필드:scan_result_policy_block_group_branch_modification이라는 기능 플래그와 함께 GitLab 16.8에서 도입됨.- GitLab 17.6에서 GitLab.com 및 GitLab Self-Managed에서 활성화됨.
- GitLab 17.7에서 일반적으로 사용 가능해짐. 기능 플래그
scan_result_policy_block_group_branch_modification제거됨.
정책에 설정된 값은 프로젝트의 설정을 덮어씁니다.
| Field | Type | Required | Possible values | Applicable rule type | Description |
|---|---|---|---|---|---|
block_branch_modification |
boolean |
false | true, false |
All | 활성화하면, 해당 브랜치가 보안 정책에 포함된 경우 사용자가 보호된 브랜치 목록에서 브랜치를 제거하거나, 보호된 브랜치를 삭제하거나, 기본 브랜치를 변경하지 못하도록 막습니다. 이를 통해 사용자가 취약한 코드를 머지하기 위해 브랜치의 보호 상태를 제거할 수 없도록 합니다. branches, branch_type, policy_scope를 기준으로 적용되며, 탐지된 취약점 여부와는 무관합니다. |
block_group_branch_modification |
boolean or object |
false | true, false, { enabled: boolean, exceptions: [{ id: Integer}] } |
All | 활성화하면, 정책이 적용되는 모든 그룹에서 그룹 수준 보호된 브랜치를 제거하지 못하도록 막습니다. block_branch_modification이 true이면 암묵적으로 true가 기본값이 됩니다. 그룹 수준 보호된 브랜치를 지원하는 최상위 그룹을 exceptions로 추가합니다. |
prevent_approval_by_author |
boolean |
false | true, false |
Any merge request |
활성화하면, 머지 리퀘스트 작성자는 자신의 MR을 승인할 수 없습니다. 이를 통해 코드 작성자가 취약점을 도입하고 그 코드의 머지를 스스로 승인할 수 없도록 합니다. |
prevent_approval_by_commit_author |
boolean |
false | true, false |
Any merge request |
활성화하면, MR에 코드를 커밋한 사용자는 승인 자격이 없습니다. 이를 통해 코드 커미터가 취약점을 도입하고 그 코드의 머지를 스스로 승인할 수 없도록 합니다. |
remove_approvals_with_new_commit |
boolean |
false | true, false |
Any merge request |
활성화하면, MR이 머지에 필요한 모든 승인을 받은 후 새 커밋이 추가되면 새로운 승인이 필요합니다. 이를 통해 취약점을 포함할 수 있는 새 커밋이 승인 없이 들어오지 못하도록 합니다. |
require_password_to_approve |
boolean |
false | true, false |
Any merge request |
활성화하면, 승인자는 승인하기 전에 다시 인증해야 합니다. 승인자는 구성된 인증 방식에 따라 비밀번호나 SAML로 재인증할 수 있습니다. 이는 승인자의 신원을 확인하는 추가 보안 레이어입니다. 자세한 내용은 승인을 위한 사용자 재인증 요구를 참조합니다. |
prevent_pushing_and_force_pushing |
boolean |
false | true, false |
All | 활성화하면, 해당 브랜치가 보안 정책에 포함된 경우 사용자가 보호된 브랜치에 푸시하거나 강제 푸시하지 못하도록 막습니다. 이를 통해 사용자가 머지 리퀘스트 프로세스를 우회하여 취약한 코드를 브랜치에 추가하지 못하도록 합니다. 아직 존재하지 않는 브랜치의 생성은 표준 보호된 브랜치 규칙에 따라 관리되며, 이 설정은 브랜치가 존재하게 된 이후의 푸시 및 강제 푸시에 적용됩니다. |
승인 설정의 적용 범위#
다음 설정은 정책 위반이 있는 머지 리퀘스트에만 적용됩니다.
prevent_approval_by_authorprevent_approval_by_commit_authorremove_approvals_with_new_commitrequire_password_to_approve
머지 리퀘스트에 정책 위반이 없으면 해당 설정은 그 머지 리퀘스트에 영향을 미치지 않습니다.
다음 설정은 정책이 활성화되어 있으면 머지 리퀘스트의 정책 위반 여부와 무관하게 항상 적용됩니다.
block_branch_modificationblock_group_branch_modificationprevent_pushing_and_force_pushing설정
fallback_behavior#
히스토리
fallback_behavior필드:security_scan_result_policies_unblock_fail_open_approval_rules라는 기능 플래그와 함께 GitLab 17.0에서 도입됨. 기본적으로 비활성화됨.- GitLab 17.0에서 GitLab.com, GitLab Self-Managed, GitLab Dedicated에서 활성화됨.
- GitLab 17.1에서 일반적으로 사용 가능해짐. 기능 플래그
security_scan_result_policies_unblock_fail_open_approval_rules제거됨.
| Field | Type | Required | Possible values | Description |
|---|---|---|---|---|
fail |
string |
false | open or closed |
closed(기본값): 정책의 유효하지 않거나 적용할 수 없는 규칙에는 승인이 필요합니다. open: 정책의 유효하지 않거나 적용할 수 없는 규칙에는 승인이 필요하지 않습니다. |
policy_tuning#
unblock_rules_using_execution_policies#
히스토리
- 파이프라인 실행 정책에서 사용할 수 있는 지원이
unblock_rules_using_pipeline_execution_policies라는 기능 플래그와 함께 GitLab 17.10에서 도입됨. 기본적으로 활성화됨. - GitLab 18.3에서 일반적으로 사용 가능해짐. 기능 플래그
unblock_rules_using_pipeline_execution_policies제거됨.
| Field | Type | Required | Possible values | Description |
|---|---|---|---|---|
unblock_rules_using_execution_policies |
boolean |
false | true, false |
활성화하면, 스캔 실행 정책이나 파이프라인 실행 정책이 스캔을 요구하지만 필요한 스캔 아티팩트가 소스 브랜치에 없는 경우에도 승인 규칙이 머지 리퀘스트를 차단하지 않습니다. 이 옵션은 프로젝트나 그룹에 스캐너가 일치하는 스캔 실행 정책 또는 파이프라인 실행 정책이 이미 있을 때만 작동합니다. |
라이선스 결과(finding) 규칙은 새로 탐지된 상태만을 대상으로 하는 경우(license_states가 newly_detected로 설정된 경우)에만 제외할 수 있습니다.
예시#
스캔 실행 정책과 함께 사용하는 policy_tuning 예시#
이 예시는 보안 정책 프로젝트에 저장된
.gitlab/security-policies/policy.yml 파일에서 사용할 수 있습니다.
scan_execution_policy:
- name: Enforce dependency scanning
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: pipeline
branch_type: all
actions:
- scan: dependency_scanning
approval_policy:
- name: Dependency scanning approvals
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: scan_finding
scanners:
- dependency_scanning
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- type: send_bot_message
enabled: true
fallback_behavior:
fail: closed
policy_tuning:
unblock_rules_using_execution_policies: true
파이프라인 실행 정책과 함께 사용하는 policy_tuning 예시#
이 기능은 GitLab 17.10 이전에 생성된 파이프라인 실행 정책에서는 작동하지 않습니다. 이전 파이프라인 실행 정책에서 이 기능을 사용하려면 정책을 복사, 삭제한 후 다시 생성합니다. 자세한 내용은 GitLab 17.10 이전에 생성된 파이프라인 실행 정책 재생성을 참조합니다.
이 예시는 보안 정책 프로젝트에 저장된
.gitlab/security-policies/policy.yml 파일에서 사용할 수 있습니다.
---
pipeline_execution_policy:
- name: Enforce dependency scanning
description: ''
enabled: true
pipeline_config_strategy: inject_policy
content:
include:
- project: my-group/pipeline-execution-ci-project
file: policy-ci.yml
ref: main # optional
연결된 파이프라인 실행 정책 CI/CD 구성은 policy-ci.yml에 있습니다.
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
GitLab 17.10 이전에 생성된 파이프라인 실행 정책 재생성
GitLab 17.10 이전에 생성된 파이프라인 실행 정책에는 policy_tuning 기능을 사용하는 데 필요한
데이터가 없습니다. 이전 파이프라인 실행 정책에서 이 기능을 사용하려면,
기존 정책을 복사하고 삭제한 후 다시 생성합니다.
동영상 설명은 보안 정책: policy_tuning과 함께 사용할 파이프라인 실행 정책 재생성을 참조합니다.
파이프라인 실행 정책을 재생성하려면 다음과 같이 합니다.
- 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
- 왼쪽 사이드바에서 Secure > Policies를 선택합니다.
- 재생성할 파이프라인 실행 정책을 선택합니다.
- 오른쪽 사이드바에서 YAML 탭을 선택하고 전체 정책 파일의 내용을 복사합니다.
- 정책 표 옆에서 세로 줄임표(⋮)를 선택한 후 Delete를 선택합니다.
- 생성된 머지 리퀘스트를 머지합니다.
- Secure > Policies로 돌아가서 New policy를 선택합니다.
- Pipeline execution policy 섹션에서 Select policy를 선택합니다.
- .yaml mode에서 이전 정책의 내용을 붙여넣습니다.
- Update via merge request를 선택하고 생성된 머지 리퀘스트를 머지합니다.
security_report_time_window#
히스토리
approval_policy_time_window라는 기능 플래그와 함께 GitLab 18.5에서 도입됨.- GitLab 18.5에서 일반적으로 사용 가능해짐. 기능 플래그
approval_policy_time_window제거됨.
활발한 프로젝트에서는 가장 최근 파이프라인의 완료된 보안 스캔 결과가 바로 제공되지 않을 수 있으며, 이로 인해 보안 리포트 비교가 차단될 수 있습니다. 이 경우 security_report_time_window 설정을 사용하면 대신 최근 완료된 파이프라인의 보안 리포트를 사용할 수 있습니다. 보안 리포트는 대상 브랜치 파이프라인 생성 이전의 지정된 시간 창(분 단위)보다 오래될 수 없습니다. 선택한 파이프라인에 이미 완료된 보안 리포트가 있으면 이 설정은 적용되지 않습니다.
| Field | Type | Required | Possible values | Description |
|---|---|---|---|---|
security_report_time_window |
integer |
false | 1~10080(7일) | 보안 리포트 비교를 위한 대상 파이프라인을 선택할 때 사용할 시간 창을 분 단위로 지정합니다. |
정책 범위 스키마#
정책 적용을 맞춤화하기 위해, 지정한 프로젝트·그룹·컴플라이언스 프레임워크 레이블을 포함하거나 제외하도록 정책의 범위를 정의할 수 있습니다. 자세한 내용은 범위를 참조합니다.
policy_scope 필드를 빈 컬렉션(예: including: [])으로 설정하면 해당 필드를 생략한 것과
동일하게 처리되며, 해당 범위 차원에서 모든 프로젝트에 정책이 적용됩니다.
정책을 완전히 비활성화하려면 enabled: false를 사용합니다. 자세한 내용은
policy_scope의 빈 컬렉션을 참조합니다.
bypass_settings#
bypass_settings 필드를 사용하면 특정 브랜치, 액세스 토큰 또는 서비스 계정에 대해 정책 예외를 지정할 수 있습니다. 우회 조건이 충족되면 일치하는 머지 리퀘스트나 브랜치에는 정책이 적용되지 않습니다.
| Field | Type | Required | Description |
|---|---|---|---|
branches |
array | false | 정책을 우회하는 소스 및 대상 브랜치 목록입니다(이름 또는 패턴). |
access_tokens |
array | false | 정책을 우회하는 액세스 토큰 ID 목록입니다. |
service_accounts |
array | false | 정책을 우회하는 서비스 계정 ID 목록입니다. |
users |
array | false | 정책을 우회할 수 있는 사용자 ID 목록입니다. |
groups |
array | false | 정책을 우회할 수 있는 그룹 ID 목록입니다. |
roles |
array | false | 정책을 우회할 수 있는 기본 권한 목록입니다. |
custom_roles |
array | false | 정책을 우회할 수 있는 커스텀 권한 ID 목록입니다. |
소스 브랜치 예외#
히스토리
approval_policy_branch_exceptions라는 기능 플래그와 함께 GitLab 18.2에서 도입됨. 기본적으로 활성화됨- GitLab 18.3에서 일반적으로 사용 가능해짐. 기능 플래그
approval_policy_branch_exceptions제거됨.
브랜치 기반 예외를 사용하면, 특정 소스·대상 브랜치 조합에 대해 머지 리퀘스트 승인 정책이 승인 요건을 자동으로 면제하도록 구성할 수 있습니다. 이를 통해 feature-to-main처럼 엄격한 승인 규칙과 보안 거버넌스를 유지해야 하는 유형의 머지는 그대로 두고, release-to-main처럼 더 유연하게 처리해도 되는 유형에는 여지를 둘 수 있습니다. 우회 이벤트는 보안 정책 프로젝트에 감사 이벤트로 기록됩니다.
| Field | Type | Required | Possible values | Description |
|---|---|---|---|---|
source |
object | false | name(string) 또는 pattern(string) |
소스 브랜치 예외입니다. 정확한 이름이나 패턴 중 하나를 지정합니다. |
target |
object | false | name(string) 또는 pattern(string) |
대상 브랜치 예외입니다. 정확한 이름이나 패턴 중 하나를 지정합니다. |
액세스 토큰 및 서비스 계정 예외#
히스토리
security_policies_bypass_options_tokens_accounts라는 기능 플래그와 함께 GitLab 18.2에서 도입됨. 기본적으로 활성화됨- GitLab 18.3에서 일반적으로 사용 가능해짐. 기능 플래그
security_policies_bypass_options_tokens_accounts제거됨.
액세스 토큰 및 서비스 계정 예외를 사용하면, 필요한 경우 머지 리퀘스트 승인 정책이 적용하는 브랜치 보호를 우회할 수 있는 특정 서비스 계정과 액세스 토큰을 지정할 수 있습니다. 이 방식은 신뢰하는 자동화가 수동 승인 없이 동작하도록 허용하면서도, 사람 사용자에게는 제한을 그대로 유지할 수 있게 해줍니다. 예를 들어 신뢰할 수 있는 자동화에는 CI/CD 파이프라인, 리포지터리 미러링, 자동 업데이트 등이 포함될 수 있습니다. 우회 이벤트는 보안 정책 프로젝트에 감사 이벤트로 기록됩니다.
| Field | Type | Required | Description |
|---|---|---|---|
id |
integer | true | 액세스 토큰 또는 서비스 계정의 ID입니다. |
사용자의 보안 정책 우회 허용#
히스토리
security_policies_bypass_options_group_roles라는 기능 플래그와 함께 GitLab 18.5에서 도입됨. 기본적으로 활성화됨.- GitLab 18.6에서 일반적으로 사용 가능해짐. 기능 플래그
security_policies_bypass_options_group_roles제거됨.
긴급 상황에 대비하여 머지 리퀘스트 승인 정책을 우회할 수 있는 특정 사용자, 그룹, 권한, 커스텀 권한을 미리 지정해 둘 수 있습니다. 이 기능은 긴급 대응과 거버넌스 통제 유지에 유연성을 제공합니다. 사용자, 그룹, 권한, 커스텀 권한에 보안 정책 우회 권한을 부여하려면 예외를 지정합니다. 우회 이벤트는 보안 정책 프로젝트에 감사 이벤트로 기록됩니다.
이러한 예외를 가진 사용자는 두 가지 수준에서 우회할 수 있습니다.
- 머지 리퀘스트 승인 요건: 사용자는 머지 리퀘스트 UI에서 사유를 제공하여 승인 요건을 우회할 수 있습니다.
- 브랜치 보호: 사용자는
security_policy.bypass_reasonGit 푸시 옵션에 사유를 제공하여, 머지 리퀘스트 승인 정책의 푸시 보호가 적용된 브랜치에 직접 푸시할 수 있습니다.
security_policy.bypass_reason 푸시 옵션은 approval_settings로 구성된 머지 리퀘스트 승인 정책의 푸시 보호가 적용된 브랜치에서만 작동합니다. 머지 리퀘스트 승인 정책이 적용되지 않는 보호된 브랜치에 대한 푸시는 이 옵션으로 우회할 수 없습니다.
YAML 예시#
bypass_settings:
access_tokens:
- id: 123
- id: 456
service_accounts:
- id: 789
- id: 1011
users:
- id: 123
- id: 456
groups:
- id: 789
- id: 1011
roles:
- maintainer
- developer
custom_roles:
- id: 789
- id: 1011
보안 정책 프로젝트의 policy.yml 예시#
이 예시는 보안 정책 프로젝트에 저장된
.gitlab/security-policies/policy.yml 파일에서 사용할 수 있습니다.
---
approval_policy:
- name: critical vulnerability CS approvals
description: critical severity level only for container scanning
enabled: true
rules:
- type: scan_finding
branches:
- main
scanners:
- container_scanning
vulnerabilities_allowed: 0
severity_levels:
- critical
vulnerability_states: []
vulnerability_attributes:
false_positive: true
fix_available: true
actions:
- type: require_approval
approvals_required: 1
user_approvers:
- adalberto.dare
- name: secondary CS approvals
description: secondary only for container scanning
enabled: true
rules:
- type: scan_finding
branches:
- main
scanners:
- container_scanning
vulnerabilities_allowed: 1
severity_levels:
- low
- unknown
vulnerability_states:
- detected
vulnerability_age:
operator: greater_than
value: 30
interval: day
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
- 1002816 # Example custom role identifier called "AppSec Engineer"
- name: critical vulnerability CS approvals
description: high/critical severity level only for SAST scanning
enabled: true
enforcement_type: warn
rules:
- type: scan_finding
branch_type: default
scanners:
- sast
vulnerabilities_allowed: 0
severity_levels:
- critical
- high
vulnerability_states: []
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- maintainer
이 예시에서:
- 컨테이너 스캐닝으로 식별된 새로운
critical취약점이 포함된 모든 MR은alberto.dare로부터 승인 1건을 받아야 합니다. - 컨테이너 스캐닝으로 식별된, 30일이 넘은 기존
low또는unknown취약점이 두 개 이상 포함된 모든 머지 리퀘스트는 Owner 권한을 가진 프로젝트 멤버 또는 커스텀 권한AppSec Engineer를 가진 사용자로부터 승인 1건을 받아야 합니다. - SAST 스캐닝으로 식별된 새로운
critical또는high심각도 취약점이 포함된 모든 머지 리퀘스트는 경고 모드 정책을 트리거합니다. 경고 모드는 봇 댓글을 생성하고 머지 리퀘스트를 차단합니다. 이후 개발자가 정책 위반을 우회할 수 있습니다. 선택적으로 메인테이너도 머지 리퀘스트를 승인할 수 있습니다.
머지 리퀘스트 승인 정책 편집기 예시#
머지 리퀘스트 승인 정책 편집기의 YAML 모드에서 이 예시를 사용할 수 있습니다. 이전 예시의 단일 오브젝트에 해당합니다.
type: approval_policy
name: critical vulnerability CS approvals
description: critical severity level only for container scanning
enabled: true
rules:
- type: scan_finding
branches:
- main
scanners:
- container_scanning
vulnerabilities_allowed: 1
severity_levels:
- critical
vulnerability_states: []
actions:
- type: require_approval
approvals_required: 1
user_approvers:
- adalberto.dare
머지 리퀘스트 승인 정책 승인 이해#
머지 리퀘스트 승인 정책 비교 범위#
- 머지 리퀘스트에 승인이 필요한 시점을 판단하기 위해, GitLab은 소스 브랜치와 대상 브랜치(예:
feature/main) 각각에 대해 지원되는 각 파이프라인 소스의 완료된 파이프라인을 비교합니다. 이를 통해 스캔 결과를 가장 포괄적으로 평가합니다. - 소스 브랜치의 경우, 비교 파이프라인은 소스 브랜치의 최신 커밋에 대해 지원되는 각 파이프라인 소스의 완료된 모든 파이프라인입니다.
- 머지 리퀘스트 승인 정책이 신규 탐지 상태(
new_needs_triage및new_dismissed)만 조회하는 경우, 소스 브랜치와 대상 브랜치의 공통 조상에 있는 지원되는 모든 파이프라인 소스를 대상으로 비교가 수행됩니다. Merged Results 파이프라인을 사용하는 경우는 예외이며, 이 경우 MR 대상 브랜치의 최신 커밋을 기준으로 비교합니다. - 머지 리퀘스트 승인 정책이 기존 상태(
detected,confirmed,resolved,dismissed)를 조회하는 경우, 비교는 항상 기본 브랜치(예:main)의 최신 커밋을 기준으로 수행됩니다. - 머지 리퀘스트 승인 정책이 신규 취약점 상태와 기존 취약점 상태의 조합을 조회하는 경우, 비교는 소스 브랜치와 대상 브랜치의 공통 조상을 기준으로 수행됩니다.
- 머지 리퀘스트 승인 정책은 머지 리퀘스트에 승인이 필요한지 판단할 때 소스 브랜치와 대상 브랜치 양쪽의 결과를 비교하면서, 지원되는 모든 파이프라인 소스(
CI_PIPELINE_SOURCE변수 기준)를 고려합니다. 소스가webide인 파이프라인은 지원되지 않습니다. - 선택된 각 파이프라인의 하위 파이프라인도 비교 대상에 포함됩니다.
위험 수용 및 이후 머지 리퀘스트에서 취약점 무시#
새로 탐지된 결과(new_needs_triage 또는 new_dismissed 상태)로 범위가 지정된 머지 리퀘스트 승인 정책의 경우, 이 취약점 상태가 의미하는 바를 이해하는 것이 중요합니다. 결과는 머지 리퀘스트의 브랜치에는 존재하지만 대상 브랜치에는 존재하지 않을 때 신규 탐지로 간주됩니다. 신규 탐지 결과가 포함된 브랜치의 머지 리퀘스트가 승인되어 병합되면, 승인자는 해당 취약점의 "위험을 수용"하는 것입니다. 이후 동일한 취약점 중 하나 이상이 다시 탐지되면 상태가 detected가 되며, 이 경우 new_needs_triage 또는 new_dismissed 결과를 고려하도록 구성된 정책에서는 무시됩니다. 예를 들면 다음과 같습니다.
- critical SAST 결과를 차단하는 머지 리퀘스트 승인 정책이 생성됩니다. CVE-1234에 대한 SAST 결과가 승인되면, 이후 동일한 위반이 발생하는 머지 리퀘스트는 해당 프로젝트에서 승인이 필요하지 않습니다.
new_needs_triage와 new_dismissed 취약점 상태를 사용하는 경우, 정책 규칙과 일치하는 결과가 신규이고 아직 트리아지되지 않았다면 기각된 상태라도 정책이 해당 MR을 차단합니다. 머지 리퀘스트 내에서 신규 탐지된 후 기각된 취약점을 무시하려면 new_needs_triage 상태만 사용할 수 있습니다.
라이선스 승인 정책을 사용하는 경우, 프로젝트·컴포넌트(의존성)·라이선스의 조합이 평가에 고려됩니다. 라이선스가 예외로 승인되면, 이후 머지 리퀘스트에서는 동일한 프로젝트·컴포넌트(의존성)·라이선스 조합에 대해 승인이 필요하지 않습니다. 이 경우 컴포넌트의 버전은 고려되지 않습니다. 이전에 승인된 패키지가 새 버전으로 업데이트되어도 승인자가 다시 승인할 필요는 없습니다. 예를 들면 다음과 같습니다.
AGPL-1.0과 일치하는 신규 탐지 라이선스가 포함된 머지 리퀘스트를 차단하는 라이선스 승인 정책이 생성됩니다. 프로젝트demo에서 컴포넌트osframework에 대한 변경이 정책을 위반합니다. 승인 후 병합되면, 이후 프로젝트demo에서osframework에 라이선스AGPL-1.0이 적용된 머지 리퀘스트는 승인이 필요하지 않습니다.
추가 승인#
머지 리퀘스트 승인 정책은 일부 상황에서 추가 승인 단계를 요구합니다. 예를 들면 다음과 같습니다.
-
작업 브랜치의 보안 job 수가 줄어들어 대상 브랜치의 보안 job 수와 더 이상 일치하지 않는 경우입니다. 사용자는 CI/CD 구성에서 스캐닝 job을 제거하는 방식으로 Scanning Result Policies를 건너뛸 수 없습니다. 머지 리퀘스트 승인 정책 규칙에 구성된 보안 스캔만 제거 여부를 검사합니다.
예를 들어 기본 브랜치 파이프라인에
sast,secret_detection,container_scanning,dependency_scanning네 가지 보안 스캔이 있는 경우를 생각해 봅니다. 머지 리퀘스트 승인 정책이container_scanning과dependency_scanning두 스캐너를 적용하는 상황에서, MR이 머지 리퀘스트 승인 정책에 구성된 스캔(예:container_scanning)을 제거하면 추가 승인이 필요합니다. -
누군가 파이프라인의 보안 job을 중지시키면, 사용자는 보안 스캔을 건너뛸 수 없습니다.
-
머지 리퀘스트의 job이 실패하고
allow_failure: false로 구성되어 있으면, 파이프라인이 차단 상태가 됩니다. -
파이프라인 전체가 통과하려면 성공적으로 실행되어야 하는 수동 job이 파이프라인에 있는 경우입니다.
승인 요구 사항 평가에 사용되는 스캔 결과 관리#
머지 리퀘스트 승인 정책은 파이프라인이 완료된 후 파이프라인 내 스캐너가 생성한 아티팩트 보고서를 평가합니다. 머지 리퀘스트 승인 정책은 스캔 결과를 평가하고 스캔 결과 항목을 기준으로 승인을 결정하여 잠재적 위험을 식별하고 머지 리퀘스트를 차단하며 승인을 요구하는 데 초점을 둡니다.
머지 리퀘스트 승인 정책은 이 범위를 넘어서 아티팩트 파일이나 스캐너에 직접 개입하지 않습니다. 대신 GitLab은 아티팩트 보고서의 결과를 신뢰합니다. 이를 통해 팀은 스캔 실행과 공급망을 유연하게 관리할 수 있으며, 필요하다면 아티팩트 보고서에서 생성된 스캔 결과를 커스터마이즈(예: 오탐 필터링)할 수 있습니다.
예를 들어 잠금 파일 변조(lock file tampering)는 보안 정책 관리의 범위를 벗어나지만, 코드 오너나 외부 상태 검사를 사용하면 완화할 수 있습니다. 자세한 내용은 이슈 433029를 참조합니다.

Fix Available 또는 False Positive 속성으로 정책 위반 필터링#
불필요한 승인 요구 사항을 방지하려면, 이러한 추가 필터를 사용해 가장 실행 가능한 결과에 대해서만 MR을 차단하도록 합니다.
YAML에서 fix_available을 false로 설정하거나, 정책 편집기에서 is not과 Fix Available을 설정하면, 해당 결과에 해결 방법이나 수정 방법이 있는 경우 정책 위반으로 간주되지 않습니다. 해결 방법은 취약점 페이지의 Remediation 섹션에 표시됩니다. 수정 방법은 취약점 페이지의 Other actions 드롭다운 목록에 Resolve with scanner suggestion 액션으로 표시됩니다.
Resolve with scanner suggestion 액션은 다음 기준 중 하나가 충족될 때만 표시됩니다.
- GitLab Duo Enterprise가 포함된 Ultimate 티어 프로젝트에서 SAST 취약점이 발견된 경우입니다.
GIT_STRATEGY: fetch가 설정된 job에서, Ultimate 티어 프로젝트의 컨테이너 스캐닝 취약점이 발견된 경우입니다. 또한 해당 취약점에는 컨테이너 이미지가 활성화된 리포지터리에서 사용 가능한 수정 패키지가 있어야 합니다.- yarn으로 관리되는 Node.js 프로젝트에서 의존성 스캐닝 취약점이 발견되었고 수정 사항이 제공되는 경우입니다. 또한 프로젝트가 Ultimate 티어여야 하며 해당 인스턴스에서 FIPS 모드가 비활성화되어 있어야 합니다.
Fix Available은 의존성 스캐닝과 컨테이너 스캐닝에만 적용됩니다.
마찬가지로 False Positive 속성을 사용하면 false_positive를 false로 설정(또는 정책 편집기에서 속성을 Is not과 False Positive로 설정)하여, 정책에 의해 탐지된 결과를 무시할 수 있습니다.
False Positive 속성은 SAST 결과에 대해 Vulnerability Extraction Tool이 탐지한 결과에만 적용됩니다.
정책 평가와 취약점 상태 변경#
사용자가 취약점의 상태를 변경할 때(예: 취약점 세부 정보 페이지에서 취약점을 기각할 때), GitLab은 성능상의 이유로 머지 리퀘스트 승인 정책을 자동으로 재평가하지 않습니다. 취약점 리포트에서 업데이트된 데이터를 가져오려면 머지 리퀘스트를 업데이트하거나 관련 파이프라인을 다시 실행합니다.
이 동작은 최적의 시스템 성능을 보장하고 보안 정책 적용을 유지합니다. 정책 평가는 다음 파이프라인 실행 시점이나 머지 리퀘스트가 업데이트되는 시점에 수행되며, 취약점 상태가 바뀌는 즉시 수행되지는 않습니다.
취약점 상태 변경을 정책에 즉시 반영하려면 파이프라인을 수동으로 실행하거나 머지 리퀘스트에 새 커밋을 푸시합니다.
보안 리포트와 정책 봇의 불일치 이해#
머지 리퀘스트 보안 스캔 리포트에 표시되는 내용과 보안 봇 댓글이 취약점에 대해 나타내는 내용 사이에 불일치가 있을 수 있습니다. 이 두 기능은 보안 결과에 대해 서로 다른 데이터 소스와 비교 방식을 사용하므로, 표시되는 내용에 차이가 생길 수 있습니다.
데이터 소스:
- 머지 리퀘스트 보안 스캔 리포트: 최신 소스 브랜치 파이프라인의 결과와, 데이터베이스에 이전부터 저장된 대상 브랜치의 취약점을 비교합니다.
- 보안 봇(및 승인 정책 로직): 실제 파이프라인 아티팩트를 비교하며, 구체적으로는 최신 성공 대상 브랜치 파이프라인과 최신 성공 소스 브랜치 파이프라인을 비교합니다.
불일치가 발생하는 일반적인 시나리오#
데이터 소스의 차이로 인해 여러 시나리오에서 일관되지 않은 동작이 나타날 수 있습니다.
대상 브랜치의 보안 스캔 누락 또는 실패#
대상 브랜치의 최신 파이프라인이 보안 스캔을 제대로 실행하지 못하면(예: 잘못된 구성이나 job 실패로), 보안 봇은 결과를 효과적으로 비교할 수 없어 예방 조치로 신규 결과를 보고하고 승인을 요구할 수 있습니다. 반면 보안 스캔 리포트는 이전에 저장된 취약점 데이터를 사용하므로 신규 취약점이 없다고 표시할 수 있습니다.
비교 시점 사이 대상 브랜치의 변경#
보안 스캔 리포트가 비교를 수행하는 시점과 봇이 비교를 수행하는 시점 사이에 대상 브랜치의 보안 프로필을 바꾸는 여러 커밋이 있으면, 결과가 달라질 수 있습니다.
일관된 결과를 위한 모범 사례#
이러한 보안 기능을 사용할 때 혼란을 최소화하려면 다음을 따릅니다.
- 완전한 파이프라인 실행을 보장합니다: 소스 브랜치와 대상 브랜치 모두에서 보안 스캔이 성공적으로 완료되는지 확인합니다.
- 일관된 CI/CD 구성을 유지합니다: 파이프라인에서 보안 스캔 구성을 제거하거나 손상시키지 않습니다.
- 신규 프로젝트의 경우: 기준 취약점 데이터를 마련하기 위해 머지 리퀘스트를 생성하기 전에 기본 브랜치에서 보안 스캔을 실행합니다.
- 스캔 실행 정책 사용을 고려합니다: 머지 리퀘스트 승인 정책과 함께 사용하면 필요한 곳에서 보안 스캔이 항상 실행되도록 하는 데 도움이 됩니다.
문제 해결#
머지 리퀘스트 규칙 위젯에 머지 리퀘스트 승인 정책이 유효하지 않거나 중복된다고 표시됨#
GitLab Self-Managed 15.0~16.4에서 가장 흔한 원인은, 프로젝트가 어떤 그룹에서 내보내져 다른 그룹으로 가져와졌고 머지 리퀘스트 승인 정책 규칙을 가지고 있던 경우입니다. 이 규칙은 내보낸 프로젝트와는 별도의 프로젝트에 저장됩니다. 그 결과 가져온 프로젝트에는, 해당 그룹에 존재하지 않는 엔터티를 참조하는 정책 규칙이 남게 됩니다. 그 결과 정책 규칙이 유효하지 않거나 중복되거나, 둘 다인 상태가 됩니다.
GitLab 인스턴스에서 유효하지 않은 머지 리퀘스트 승인 정책 규칙을 모두 제거하려면, 관리자가 Rails 콘솔에서 다음 스크립트를 실행할 수 있습니다.
Project.joins(:approval_rules).where(approval_rules: { report_type: %i[scan_finding license_scanning] }).where.not(approval_rules: { security_orchestration_policy_configuration_id: nil }).find_in_batches.flat_map do |batch|
batch.map do |project|
# Get projects and their configuration_ids for applicable project rules
[project, project.approval_rules.where(report_type: %i[scan_finding license_scanning]).pluck(:security_orchestration_policy_configuration_id).uniq]
end.uniq.map do |project, configuration_ids| # Take only unique combinations of project + configuration_ids
# If you find more configurations than what is available for the project, take records with the extra configurations
[project, configuration_ids - project.all_security_orchestration_policy_configurations.pluck(:id)]
end.select { |_project, configuration_ids| configuration_ids.any? }
end.each do |project, configuration_ids|
# For each found pair project + ghost configuration, remove these rules for a given project
Security::OrchestrationPolicyConfiguration.where(id: configuration_ids).each do |configuration|
configuration.delete_scan_finding_rules_for_project(project.id)
end
# Ensure you sync any potential rules from new group's policy
Security::ScanResultPolicies::SyncProjectWorker.perform_async(project.id)
end
신규 탐지된 CVE#
new_needs_triage와 new_dismissed를 사용하는 경우, 머지 리퀘스트가 직접 도입하지 않은 결과(예: 관련 의존성의 신규 CVE)에도 승인이 필요할 수 있습니다. 이런 결과는 머지 리퀘스트 보안 스캔 리포트에는 나타나지 않지만, 정책 봇 댓글과 파이프라인 리포트에는 강조 표시됩니다.
policy.yml을 수동으로 무효화한 뒤에도 정책이 계속 적용됨#
GitLab 17.2 이하에서는, policy.yml 파일에 정의된 정책이 계속 적용되는 경우가
있습니다. 파일이 수동으로 편집되어 더 이상
정책 스키마를 통과하지 못하는 상태여도 그렇습니다. 이 문제는
정책 동기화 로직의 버그로 발생합니다.
잠재적인 증상은 다음과 같습니다.
approval_settings가 브랜치 보호 제거를 계속 차단하거나, 강제 푸시를 차단하거나, 그 외의 방식으로 열려 있는 머지 리퀘스트에 영향을 미칩니다.any_merge_request정책이 열려 있는 머지 리퀘스트에 여전히 적용됩니다.
이를 해결하려면 다음 중 하나를 수행합니다.
- 정책을 정의하는
policy.yml파일을 수동으로 편집하여 다시 유효한 상태로 만듭니다. policy.yml파일이 저장된 보안 정책 프로젝트의 할당을 해제한 뒤 다시 할당합니다.
보안 스캔 누락#
머지 리퀘스트 승인 정책을 사용하면, 신규 프로젝트를 포함해 특정 보안 스캔이 실행되지 않는 경우 머지 리퀘스트가 차단되는 상황이 발생할 수 있습니다. 이는 시스템에 취약점이 도입될 위험을 줄이기 위한 설계입니다.
시나리오 예시:
-
소스 브랜치에 스캔 누락
소스 브랜치에 보안 스캔이 없으면 GitLab은 해당 머지 리퀘스트가 새 취약점을 도입하는지 효과적으로 평가할 수 없습니다. 이 경우 예방 조치로 승인이 필요합니다.
-
대상 브랜치에 스캔 누락
대상 브랜치에 보안 스캔이 없으면 GitLab은 소스 브랜치에서 탐지된 취약점을 효과적으로 비교할 수 없습니다. 이 경우 탐지된 취약점은 모두 신규로 보고됩니다.
-
스캔할 파일이 없는 프로젝트
선택한 보안 스캔과 관련된 파일이 없는 프로젝트에서도 승인 요구 사항은 계속 적용됩니다. 이를 통해 모든 프로젝트에서 일관된 보안 관행을 유지합니다.
-
첫 번째 머지 리퀘스트
신규 프로젝트의 첫 번째 머지 리퀘스트는, 소스 브랜치에 취약점이 없더라도 기본 브랜치에 보안 스캔이 없으면 차단될 수 있습니다.
이러한 문제를 해결하려면 다음을 수행합니다.
- 소스 브랜치와 대상 브랜치 모두에서 필요한 모든 보안 스캔이 구성되어 성공적으로 실행되는지 확인합니다.
- 신규 프로젝트의 경우, 머지 리퀘스트를 생성하기 전에 기본 브랜치에서 필요한 보안 스캔을 설정하고 실행합니다.
- 모든 브랜치에서 보안 스캔이 일관되게 실행되도록 스캔 실행 정책이나 파이프라인 실행 정책 사용을 고려합니다.
- 정책의 유효하지 않거나 적용 불가능한 규칙이 승인을 요구하지 않도록
fallback_behavior를open으로 사용하는 것을 고려합니다. - 보안 스캔 아티팩트가 누락되고 스캔 실행 정책이 적용되는 상황을 해결하기 위해
policy tuning설정unblock_rules_using_execution_policies사용을 고려합니다. 이 설정을 활성화하면, 스캔 아티팩트가 소스 브랜치에 없고 스캔 실행 정책에 의해 스캔이 요구되는 경우에도 승인 규칙을 선택 사항으로 만듭니다. 이 기능은 스캐너가 일치하는 기존 스캔 실행 정책이 있을 때만 작동합니다. 아티팩트 누락으로 특정 보안 스캔을 수행할 수 없는 경우 머지 리퀘스트 프로세스에 유연성을 제공합니다.
보안 봇 댓글에 나타나는 Target: none#
보안 봇 댓글에서 Target: none이 보이면, GitLab이 대상 브랜치의 보안 리포트를 찾지 못했다는 의미입니다. 이를 해결하려면 다음을 수행합니다.
- 필요한 보안 스캐너가 포함된 파이프라인을 대상 브랜치에서 실행합니다.
- 파이프라인이 성공적으로 완료되어 보안 리포트가 생성되는지 확인합니다.
- 소스 브랜치에서 파이프라인을 다시 실행합니다. 새 커밋을 만들어도 파이프라인이 다시 실행됩니다.
보안 봇 메시지#
대상 브랜치에 보안 스캔이 없는 경우:
- 보안 봇이 소스 브랜치에서 발견된 취약점을 모두 나열할 수 있습니다.
- 그중 일부는 이미 대상 브랜치에 존재할 수 있지만, 대상 브랜치 스캔이 없으면 GitLab은 어느 것이 신규인지 판단할 수 없습니다.
잠재적 해결책:
- 수동 승인: 보안 스캔이 자리 잡을 때까지 신규 프로젝트의 머지 리퀘스트를 임시로 수동 승인합니다.
- 대상 정책: 신규 프로젝트를 위해 승인 요구 사항이 다른 별도의 정책을 만듭니다.
- 폴백 동작: 신규 프로젝트의 정책에
fail: open을 사용하는 것을 고려하되, 스캔이 실패해도 사용자가 취약점을 머지할 수 있게 될 수 있다는 점에 주의합니다.
머지 리퀘스트 승인 정책 디버깅 지원 요청#
GitLab.com 사용자는 "Merge request approval policy debugging"이라는 제목으로 지원 티켓을 제출할 수 있습니다. 다음 정보를 제공합니다.
- 그룹 경로, 프로젝트 경로, 필요하다면 머지 리퀘스트 ID
- 심각도
- 현재 동작
- 예상 동작
GitLab.com#
지원팀은 로그(pubsub-sidekiq-inf-gprd*)를 조사하여 실패 reason을 식별합니다. 아래는 로그의 응답 스니펫 예시입니다. 다음 쿼리로 승인 관련 로그를 찾을 수 있습니다: json.event.keyword: "update_approvals" 및 json.project_path: "group-path/project-path". 선택적으로 json.merge_request_iid로 머지 리퀘스트 식별자를 추가 필터링할 수 있습니다.
"json": {
"project_path": "group-path/project-path",
"merge_request_iid": 2,
"missing_scans": [
"api_fuzzing"
],
"reason": "Scanner removed by MR",
"event": "update_approvals",
}
GitLab Self-Managed#
project-path, api_fuzzing, merge_request 등의 키워드로 검색합니다. 예: grep group-path/project-path, grep merge_request. 상관 관계 ID(correlation ID)를 알고 있다면 그 값으로 검색합니다. 예를 들어 correlation_id 값이 01HWN2NFABCEDFG이면 01HWN2NFABCEDFG로 검색합니다.
다음 파일에서 검색합니다.
/gitlab/gitlab-rails/production_json.log/gitlab/sidekiq/current
일반적인 실패 원인:
- Scanner removed by MR(스캐너가 MR에 의해 제거됨): 머지 리퀘스트 승인 정책은 정책에 정의된 스캐너가 존재하고, 비교용 아티팩트를 성공적으로 생성할 것을 전제로 합니다.
- Security scan did not complete successfully(보안 스캔이 성공적으로 완료되지 않음): 정책이 요구하는 스캐너의 CI job이 아티팩트를 생성한 후 취소되거나 실패했습니다. 봇 메시지는 다음과 같습니다.
Policy <name> could not be evaluated because the following security scans did not complete successfully: <scanners>. Ensure security scan jobs are not canceled or failing.GitLab 18.11에서 머지 리퀘스트 228446으로 도입되었습니다. - Security scan job did not succeed and produced no report(보안 스캔 job이 성공하지 못했고 리포트도 생성되지 않음): 정책이
요구하는 스캐너의 CI job이 아티팩트를 하나도 생성하지 못한 채 실패하거나 취소되어, 보안
리포트가 존재하지 않습니다.
봇 메시지는 다음과 같습니다.
Policy <name> could not be evaluated because the following security scans did not complete successfully: <scanners>. Ensure security scan jobs are not canceled or failing.GitLab 19.3에서 머지 리퀘스트 243540으로 기능 플래그approval_policies_block_on_failed_scan_job아래 도입되었으며, GitLab 19.4부터 기본적으로 활성화되었습니다. Dependency Scanning v2의 제약 사항은 파이프라인 요구 사항을 참조합니다.
머지 리퀘스트 승인 정책의 승인 불일치#
머지 리퀘스트 승인 규칙에서 불일치를 발견하면, 다음 중 한 가지 방법으로 정책을 재동기화할 수 있습니다.
resyncSecurityPoliciesGraphQL 뮤테이션을 사용하여 정책을 재동기화합니다.- 영향받는 그룹이나 프로젝트에서 보안 정책 프로젝트의 할당을 해제한 후 다시 할당합니다.
- 또는 정책을 업데이트하여 영향받는 그룹이나 프로젝트에 대해 해당 정책이 재동기화되도록 트리거합니다.
- 보안 정책 프로젝트의 YAML 파일 구문이 유효한지 확인합니다.
이러한 조치는 머지 리퀘스트 승인 정책이 올바르게 적용되고 모든 머지 리퀘스트에서 일관성을 유지하도록 돕습니다.
이 단계를 수행한 후에도 머지 리퀘스트 승인 정책에서 계속 문제가 발생하면 GitLab 지원팀에 문의합니다.
탐지된 취약점을 수정하는 머지 리퀘스트에 승인이 필요함#
정책 구성에 detected 상태가
포함되어 있으면, 이전에 탐지된 취약점을 수정하는 머지 리퀘스트에도 여전히 승인이 필요합니다. 머지 리퀘스트
승인 정책은 그 머지 리퀘스트의 변경 사항이 적용되기 전에 존재했던 취약점을 기준으로 평가하며,
이는 알려진 취약점에 영향을 미치는 변경 사항에 검토 레이어를 하나 더
추가하는 효과가 있습니다.
취약점을 수정하는 머지 리퀘스트가
탐지된 취약점 때문에 추가 승인 없이 진행되도록 허용하려면,
정책 구성에서 detected 상태를 제거하는 것을 고려합니다.
병합된 결과 파이프라인과 브랜치 파이프라인 간 정책 평가 불일치#
프로젝트에서 병합된 결과 파이프라인이 활성화되어 있고 보안 스캔이 포함된 브랜치 파이프라인도 함께 실행되면, 서로 다른 파이프라인에서 머지 리퀘스트 승인 정책이 평가되는 방식이 일관되지 않을 수 있습니다. 다음 예시를 생각해 봅니다.
- 병합된 결과 파이프라인과 브랜치 파이프라인이 모두 동일한 머지 리퀘스트에 대해 보안 스캔을 실행합니다.
- 브랜치 파이프라인이 병합된 결과 파이프라인보다 나중에 완료됩니다.
- 정책 평가는 병합된 결과 파이프라인 대신 브랜치 파이프라인을 비교 대상으로 선택합니다.
머지 리퀘스트 승인 정책은 최신 커밋에 대해 완료된 파이프라인을 평가하며, 가장 나중에 완료된 파이프라인이 비교 대상으로 선택됩니다. 브랜치 파이프라인이 병합된 결과 파이프라인보다 나중에 완료되면, 정책은 브랜치 파이프라인을 평가에 사용합니다.
이 문제를 피하려면 다음을 수행합니다.
-
병합된 결과 파이프라인에서만 보안 스캔을 실행합니다: 병합된 결과 파이프라인이 활성화된 경우 보안 스캐닝 job이 머지 리퀘스트 파이프라인에서만 실행되도록 구성합니다.
rules를 사용하여 보안 job의 실행 시점을 제어합니다.sast: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" -
중복 파이프라인을 피합니다: 중복 파이프라인 피하기의 안내를 따라 커밋당 하나의 파이프라인 유형에서만 보안 스캔이 실행되도록 합니다.
-
일관된 스캐너 구성을 사용합니다: 소스 브랜치와 대상 브랜치 모두에 대해 동일한 파이프라인 유형으로 동일한 스캐너를 실행합니다.
중복 파이프라인에 대한 자세한 내용은 브랜치에 푸시할 때 파이프라인이 두 개 생성되는 경우를 참고합니다.