スキャン結果ポリシー

GitLab 15.6で導入されたグループレベルのスキャン結果ポリシー。

スキャン結果ポリシーを使用すると、スキャン結果に基づいてアクションを実行できます。例えば、スキャン結果ポリシーの1つのタイプは、1つ以上のセキュリティスキャンジョブの調査結果に基づいて承認者を要求できるようにするセキュリティ承認ポリシーです。スキャン結果ポリシーは、CI スキャン ジョブが完全に実行された後に評価されます。

note
スキャン結果ポリシーは、保護対象のブランチにのみ適用されます。
note
保護対象のブランチが作成または削除されると、ポリシーの承認ルールが 1 分遅延で同期されます。

次のビデオでは、GitLabスキャン結果ポリシーの概要を説明します:

ビデオをご覧ください:GitLabスキャン結果ポリシーの概要。

複数のパイプラインでのマージリクエスト

フラグ: セルフマネージドGitLabでは、デフォルトでこの機能が利用可能です。この機能を隠すには、管理者がmulti_pipeline_scan_result_policiesという機能フラグを無効にします。GitLab.comでは、この機能は利用可能です。

プロジェクトには複数のパイプラインタイプを設定することができます。一つのコミットで複数のパイプラインを開始することができ、それぞれのパイプラインにセキュリティスキャンを含めることができます。

  • GitLab 16.3 以降では、MR のソースブランチとターゲットブランチの最新のコミットに対して完了したすべてのパイプラインの結果が評価され、スキャン結果のポリシーを適用するために使用されます。親子パイプラインやオンデマンド DAST パイプラインは考慮されません。
  • GitLab 16.2以前では、スキャン結果ポリシーを適用する際に、最新の完了したパイプラインの結果のみが評価されました。

スキャン結果ポリシーエディタ

note
プロジェクトオーナーだけがセキュリティポリシープロジェクトを選択する権限を持っています。

ポリシーが完成したら、エディタの下部にあるマージリクエストで設定を選択して保存します。これで、プロジェクトの設定済みセキュリティポリシープロジェクトのマージリクエストにリダイレクトされます。セキュリティポリシープロジェクトがあなたのプロジェクトにリンクしていない場合は、GitLab がそのようなプロジェクトを作成します。既存のポリシーは、エディターの一番下にあるDelete policyを選択することで、エディターインターフェイスから削除することもできます。

ほとんどのポリシー変更は、マージリクエストがマージされるとすぐに有効になります。マージリクエストを経由せず、デフォルトブランチに直接コミットされた変更は、ポリシーの変更が有効になるまで最大 10 分かかる場合があります。

ポリシーエディタはYAML モードとルールモードをサポートします。

note
プロジェクト数の多いグループに作成されたスキャン結果ポリシーの伝播には時間がかかります。

スキャン結果ポリシーのスキーマ

スキャン結果ポリシーの YAML ファイルは、scan_result_policy キーの scan_result_policy下にネストされたスキャン結果ポリシー スキーマに一致するオブジェクトの配列で構成されます。キーのscan_result_policy 下に最大 5 つのポリシーを設定 scan_result_policyできます。

新しいポリシーを保存すると、GitLabはその内容をこのJSONスキーマに対して検証します。JSONスキーマの読み方に慣れていない場合は、以下のセクションと表で代替案を提供します。

項目種類必須可能な値説明
scan_result_policy array スキャン結果ポリシーtrue スキャン結果ポリシーのリスト (最大 5 つ)。

スキャン結果ポリシースキーマ

approval_settings フィールドは GitLab 16.4 でscan_result_policy_settingsというフラグと共に 導入されました。デフォルトでは無効です。

フラグ: セルフマネジメントのGitLabでは、デフォルトではこの機能は利用できません。利用可能にするには、scan_result_policy_settingsという機能フラグを有効にするよう管理者に依頼してください。GitLab.comでは、この機能は利用できません。

項目種類必須可能な値説明
namestringtrue ポリシーの名前。最大255文字です。
description (オプション)stringtrue ポリシーの説明
enabledbooleantrue true,false ポリシーを有効 (true) または無効 (false) にするフラグです。
rules array ルールのtrue ポリシーが適用されるルールのリスト。
actions array アクションのtrue ポリシーが強制するアクションのリスト。
approval_settingsobjectfalse{prevent_approval_by_author: boolean, prevent_approval_by_commit_author: boolean, remove_approvals_with_new_commit: boolean, require_password_to_approve: boolean}ポリシーがオーバーライドするプロジェクト設定。

scan_finding ルールタイプ

  • スキャン結果ポリシーフィールドvulnerability_attributes は、GitLab 16.2 でenforce_vulnerability_attributes_rulesというフラグとともに 導入されました。デフォルトでは無効です。
  • GitLab.comでは有効、GitLab 16.3では自己管理
  • スキャン結果ポリシーフィールドvulnerability_age は GitLab 16.2 で導入されました。

フラグ: セルフマネジメントのGitLabでは、デフォルトでvulnerability_attributes フィールドが利用可能です。この機能を隠すには、管理者がenforce_vulnerability_attributes_rulesという機能フラグを無効にします。GitLab.comでは、この機能は利用可能です。このルールは、セキュリティスキャンの結果に基づいて定義されたアクションを実行します。

項目種類必須可能な値説明
typestringtruescan_findingルールのタイプ。
branches arraystring branch_type フィールドが存在しない場合は真。 [] またはブランチ名保護されたターゲットブランチのみに適用されます。空の配列[]を指定すると、すべての保護対象ブランチにルールが適用されます。branch_type フィールドとは併用できません。
branch_typestring branches フィールドが存在しない場合は真。 default またはprotected 指定されたポリシーが適用されるブランチの種類。branches フィールドと一緒に使用することはできません。
scanners arraystring true sast,secret_detection,dependency_scanning,container_scanning,dast,coverage_fuzzingapi_fuzzing sast には、SAST と SAST IaC スキャナの両方の結果が含まれています。
vulnerabilities_allowedintegertrueゼロ以上このルールが考慮される前に許容される脆弱性の数。
severity_levels arraystring true info unknown,low,medium,highcritical このルールで考慮すべき重大度レベル。
vulnerability_states arraystring true newly_detected,detected,confirmed,resolved,dismissed,new_needs_triagenew_dismissed すべての脆弱性は、次の 2 つのカテゴリに分類されます:

新たに検出された脆弱性- このnewly_detected ポリシーオプションは、マージリクエストブランチ自体で特定された脆弱性であって、デフォルトブランチには現在存在しない脆弱性を対象として newly_detectedいます。newly_detected このポリシーオプションでは、ルールが評価される前にパイプラインが完了する必要があるため、脆弱性が新たに検出されたかどうかを知ることができます。マージリクエストは、パイプラインと必要なセキュリティスキャンが完了するまでブロックされます。この newly_detectedオプションでは、次の両方のステータスが考慮されます:

- 検出された
- 却下された

new_needs_triage オプションはステータスを考慮します

- 検出された

new_dismissed オプションはステータスを考慮します

- 却下された

既存の脆弱性- これらのポリシーオプションは直ちに評価され、デフォルトブランチで以前に検出された脆弱性の みを考慮するため、パイプラインの完了を必要としません。

-Detected - ポリシーは検出された状態の脆弱性を探します。
-Confirmed - ポリシーは確認された状態の脆弱性を探します。
-Dismissed - ポリシーは却下された状態の脆弱性を探します。
-Resolved - ポリシーは解決された状態の脆弱性を探します。
vulnerability_attributesobjectfalse{false_positive: boolean, fix_available: boolean}デフォルトではすべての脆弱性所見が考慮されます。しかし、脆弱性の発見のみを考慮するように属性にフィルタを適用することができます:

- 修正プログラムがある場合 (fix_available: true)

- 修正プログラムがない場合 (fix_available: false)
- 偽陽性である場合 (false_positive: true)
- 偽陽性でない場合 (false_positive: false)
- あるいは両方の組み合わせ。例えば (fix_available: true, false_positive: false)
vulnerability_ageobjectfalse該当なし既存の脆弱性の発見を年齢でフィルタリングします。脆弱性の年齢は、プロジェクトで検出されてからの時間として計算されます。基準は、operatorvalue、およびintervalです。
-operator 基準は、使用される年齢比較が (greater_than) より古いか (less_than) より若いかを指定します。
-value 基準は、脆弱性の年齢を表す数値を指定します。
-interval 基準は、脆弱性の年齢の測定単位を指定します:dayweekmonth、またはyear

例:operator: greater_thanvalue: 30,interval: day.

license_finding ルールタイプ

このルールはライセンスの発見に基づいて定義されたアクションを実行します。

項目種類必須可能な値説明
typestringtruelicense_findingルールのタイプ。
branches arraystring branch_type フィールドが存在しない場合は真。 [] またはブランチ名保護されたターゲットブランチのみに適用されます。空の配列[]を指定すると、すべての保護対象ブランチにルールが適用されます。branch_type フィールドとは併用できません。
branch_typestring branches フィールドが存在しない場合は真。 default またはprotected 指定されたポリシーが適用されるブランチの種類。branches フィールドと一緒に使用することはできません。
match_on_inclusionbooleantrue true,false license_types に記載されているライセンスの包含または除外に一致するルールかどうか。
license_types arraystring trueライセンスタイプ一致させるSPDX ライセンス名(例:Affero General Public License v1.0 またはMIT License) 。
license_states arraystring true newly_detected,detected 新しく検出されたライセンスおよび/または以前に検出されたライセンスと一致させるかどうか。newly_detected の状態は、新しいパッケージが導入されたとき、または既存のパッケージの新しいライセンスが検出されたときに承認者をトリガーします。

any_merge_request ルールタイプ

GitLab 16.4で導入されました

このルールは、コミット署名に基づくマージリクエストに対して定義されたアクションを強制します。

項目種類必須可能な値説明
typestringtrueany_merge_requestルールのタイプ。
branches arraystring branch_type フィールドが存在しない場合は真。 [] またはブランチ名保護されたターゲットブランチのみに適用されます。空の配列[]を指定すると、すべての保護対象ブランチにルールが適用されます。branch_type フィールドとは併用できません。
branch_typestring branches フィールドが存在しない場合は真。 default またはprotected 指定されたポリシーが適用されるブランチの種類。branches フィールドと一緒に使用することはできません。
commitsstringtrue any,unsigned ルールがすべてのコミットにマッチするか、マージリクエストで署名なしコミットが検出された場合にのみマッチするかを指定します。

require_approval アクションタイプ

このアクションは、定義されたポリシー内の少なくとも 1 つのルールの条件が満たされた場合に、承認者が必要となる承認ルールを設定します。

項目種類必須可能な値説明
typestringtruerequire_approvalアクションのタイプ。
approvals_requiredintegertrueゼロ以上必要なMR承認者の数。
user_approvers arraystring false複数のユーザーのユーザー名承認者として考慮するユーザー。ユーザーはプロジェクトにアクセスできなければ承認者として認められません。
user_approvers_ids arrayinteger false複数のユーザーのID承認者として考慮するユーザーのID。承認者となるには、ユーザーがプロジェクトにアクセスできる必要があります。
group_approvers arraystring false複数のグループのパス承認者として考慮するグループ。グループに直接所属するユーザーが承認者となります。
group_approvers_ids arrayinteger false複数のグループのID承認者として考慮するグループのID。グループに直接所属するユーザーが承認者となります。
role_approvers arraystring false1つ以上のロール(例:owner,maintainer)承認する資格のある承認者とみなすロール。

要件と制限:

  • それぞれのセキュリティ スキャン ツールを追加する必要があります。そうしないと、スキャン結果のポリシーは有効になりません。
  • ポリシーの最大数は 5 です。
  • 各ポリシーには最大 5 つのルールを設定できます。
  • 設定されたすべてのスキャナーがマージリクエストの最新のパイプラインに存在する必要があります。そうでない場合、脆弱性の基準が満たされていなくても承認者が必要です。

セキュリティスキャン結果ポリシープロジェクトの例

この例は、セキュリティポリシープロジェクトに格納されている.gitlab/security-policies/policy.yml ファイルで使用できます:

---
scan_result_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:
    - newly_detected
    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

この例では:

  • コンテナスキャンによって特定された新しい脆弱性(critical )を含む MR には、alberto.dare からの承認者が 1 人必要です。
  • コンテナスキャンによって特定された 30 日以上前のlow またはunknown の脆弱性を 1 つ以上含む MR はすべて、オーナーのロールを持つプロジェクトメンバからの承認が 1 つ必要です。

スキャン結果ポリシーエディタの例

この例はスキャン結果ポリシーエディタのYAMLモードで使用できます。前の例の1つのオブジェクトに対応しています:

- 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:
    - newly_detected
  actions:
  - type: require_approval
    approvals_required: 1
    user_approvers:
    - adalberto.dare

スキャン結果ポリシーが追加承認を必要とする状況例

スキャン結果ポリシーが追加の承認者を必要とする状況がいくつかあります。たとえば、次のような場合です:

  • 作業ブランチのセキュリティジョブ数が減少し、ターゲットブランチのセキュリティジョブ数と一致しなくなった場合。ユーザーは、CI/CD 設定からスキャンジョブを削除することによって、スキャン結果ポリシーをスキップすることはできません。スキャン結果ポリシールールで設定されたセキュリティスキャンのみが、削除のためにチェックされます。

    例えば、デフォルトのブランチパイプラインに 4 つのセキュリティスキャンがある状況を考えてみましょう:sast secret_detectioncontainer_scanningdependency_scanning。スキャン結果ポリシーは、container_scanningdependency_scanningの 2 つのスキャナを強制します。MR がスキャン結果ポリシーで設定されているスキャン、例えばcontainer_scanning を削除する場合、追加の承認者が必要になります。

  • 誰かがパイプラインのセキュリティジョブを停止すると、ユーザーはセキュリティスキャンをスキップできなくなります。
  • マージリクエストのジョブが失敗し、allow_failure: false で設定されます。その結果、パイプラインはブロックされた状態になります。
  • パイプラインには、パイプライン全体を通過させるために正常に実行する必要がある手動ジョブがあります。