スキャン実行ポリシーと、マージリクエスト承認ポリシー
(トップページはこちら) - (アプリケーションのセキュリティを始める)
「全プロジェクトでセキュリティスキャンを統一したいが、各チームが独自のCI/CD設定を持っていて管理が困難」「コンプライアンス要件を満たすために、すべてのマージリクエストに承認プロセスを強制したい」このような課題に直面していませんか。
GitLabのセキュリティポリシー機能は、セキュリティチームとコンプライアンスチームが組織全体にわたって一貫したセキュリティ制御を実装できる仕組みです。開発チームの生産性を損なうことなく、必要なセキュリティスキャンの実行、適切な承認プロセスの確保、脆弱性の自動管理を実現します。
1. セキュリティポリシーの概要
1.1. 解決できる課題
セキュリティチームの課題
- 開発チームのパイプラインに適切な設定でセキュリティスキャナーを強制実行
- スキャンジョブが変更や改変なしに実行されることを保証
- スキャン結果に基づいたマージリクエストの適切な承認プロセスの実施
- 検出されなくなった脆弱性の自動解決による、トリアージ作業の軽減
コンプライアンスチームの課題
- すべてのマージリクエストに対する複数承認者の強制
- マージリクエスト設定やリポジトリ設定など、組織要件に基づいたプロジェクト設定の強制
1.2. ポリシータイプの選択ガイド
GitLabは4つのポリシータイプを提供しています。目的に応じて適切なポリシーを選択してください。
| ポリシータイプ | 主な用途 | 適用場面 |
|---|---|---|
| スキャン実行ポリシー | セキュリティスキャンの強制実行 | パイプライン実行時またはスケジュールでスキャンを実施 |
| マージリクエスト承認ポリシー | 承認プロセスの強制 | スキャン結果に基づいた承認ルールの適用 |
| パイプライン実行ポリシー | カスタムCI/CDジョブの強制 | 高度な設定やサードパーティスキャンの実行 |
| 脆弱性管理ポリシー | 脆弱性の自動解決 | デフォルトブランチで検出されなくなった脆弱性の処理 |
選択のポイント
- 標準的なセキュリティスキャンを素早く導入したい → スキャン実行ポリシー
- 高度なカスタマイズやサードパーティツールを使いたい → パイプライン実行ポリシー
- スキャン結果に基づいて承認を制御したい → マージリクエスト承認ポリシー
本記事では、最も利用頻度の高いスキャン実行ポリシーに焦点を当てて解説します。
2. クイックスタート:最初のポリシーを作成する
まずは最小構成でポリシーを作成し、動作を確認しましょう。
2.1. 基本的なポリシーの例
デフォルトブランチでSecret DetectionとContainer Scanningを実行する最もシンプルな設定です。
scan_execution_policy:
- name: デフォルトブランチでの基本スキャン
description: mainブランチでSecret DetectionとContainer Scanningを実行
enabled: true
rules:
- type: pipeline
branches:
- main
actions:
- scan: secret_detection
- scan: container_scanning
2.2. ポリシー作成の流れ
2.3. 動作確認
ポリシーを適用後、以下を確認してください。
- 対象ブランチにコミットをプッシュ
- パイプラインが自動的に作成されることを確認
- ポリシーで指定したスキャンジョブ(例:
secret-detection-1、container-scanning-1)が実行されることを確認 - スキャン結果がセキュリティダッシュボードに表示されることを確認
3. スキャン実行ポリシーの詳細
3.1. ポリシーの基本構造
スキャン実行ポリシーは、**ルール(いつ実行するか)とアクション(何を実行するか)**の組み合わせで構成されます。
主要フィールド
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
name |
文字列 | ○ | ポリシー名(最大255文字) |
description |
文字列 | - | ポリシーの説明 |
enabled |
真偽値 | ○ | ポリシーの有効/無効 |
rules |
配列 | ○ | ルールのリスト(最大5個) |
actions |
配列 | ○ | アクションのリスト(最大10個、GitLab 18.0以降) |
policy_scope |
オブジェクト | - | ポリシーの適用範囲 |
skip_ci |
オブジェクト | - | skip-ciディレクティブの制御 |
3.2. ルールタイプ
3.2.1. pipelineルール:パイプライン実行時のスキャン
指定されたブランチでパイプラインが実行されるたびに、定義されたアクションを強制実行します。
フィールド一覧
| フィールド | 型 | 必須 | 説明 | 例 |
|---|---|---|---|---|
type |
文字列 | ○ |
pipelineを指定 |
pipeline |
branches |
配列 | △ | ブランチ名(ワイルドカード対応) |
main, release/*
|
branch_type |
文字列 | △ | ブランチタイプ |
default, protected, all
|
branch_exceptions |
配列 | - | 除外するブランチ | experimental-* |
pipeline_sources |
配列 | - | パイプラインソース |
merge_request_event, push
|
注意: branchesとbranch_typeのいずれか一方を指定する必要があります(両方は指定不可)。
設定例
# 例1: 保護されたブランチでのスキャン
rules:
- type: pipeline
branch_type: protected
pipeline_sources:
- push
- merge_request_event
# 例2: リリースブランチでのスキャン(実験ブランチを除外)
rules:
- type: pipeline
branches:
- release/*
branch_exceptions:
- release/experimental-*
# 例3: マージリクエストパイプラインでのみスキャン
rules:
- type: pipeline
branch_type: target_default
pipeline_sources:
- merge_request_event
3.2.2. scheduleルール:スケジュール実行のスキャン
スケジュールに基づいてセキュリティスキャナーを実行します。開発活動とは独立して、定期的なセキュリティチェックを実施できます。
フィールド一覧
| フィールド | 型 | 必須 | 説明 | 例 |
|---|---|---|---|---|
type |
文字列 | ○ |
scheduleを指定 |
schedule |
branches |
配列 | △ | ブランチ名 | main |
branch_type |
文字列 | △ | ブランチタイプ |
default, protected
|
cadence |
文字列 | ○ | cron式 | 0 2 * * * |
timezone |
文字列 | - | タイムゾーン | Asia/Tokyo |
time_window |
オブジェクト | - | 実行時間の分散設定 | 後述 |
cadenceの制約
cron構文を使用しますが、以下の形式のみサポートされます。
-
日次実行:
0 18 * * *(毎日18時に実行) -
週次実行:
0 13 * * 0(毎週日曜日13時に実行)
使用不可: カンマ(,)、ハイフン(-)、ステップ演算子(/)は分と時間には使用できません。
設定例
# 例1: 毎日午前2時にスキャン(日本時間)
rules:
- type: schedule
branches:
- main
cadence: "0 2 * * *"
timezone: "Asia/Tokyo"
# 例2: 毎週月曜日午前9時にスキャン(時間分散あり)
rules:
- type: schedule
branch_type: default
cadence: "0 9 * * 1"
timezone: "Asia/Tokyo"
time_window:
value: 3600 # 1時間のウィンドウ
distribution: random
スケジュール実行の仕組み
重要な特性
- スケジュールされたパイプラインは、ポリシーで定義されたスキャナーのみを実行します
- プロジェクトの
.gitlab-ci.ymlファイルで定義されたジョブは実行されません -
security_policy_botユーザーアカウントで実行されます - GitLab.comでは、最初の10個の
scheduleルールのみが適用されます
3.3. アクションタイプ
3.3.1. scanアクション
指定されたスキャンを追加パラメータとともに実行します。
サポートされるスキャンタイプ
| スキャンタイプ | 説明 | 主な用途 |
|---|---|---|
sast |
静的アプリケーションセキュリティテスト | ソースコードの脆弱性検出 |
sast_iac |
Infrastructure as Codeスキャン | Terraform、CloudFormationなどの設定ミス検出 |
dast |
動的アプリケーションセキュリティテスト | 実行中のアプリケーションの脆弱性検出 |
secret_detection |
シークレット検出 | APIキー、パスワードなどの漏洩検出 |
container_scanning |
コンテナスキャン | コンテナイメージの脆弱性検出 |
dependency_scanning |
依存関係スキャン | ライブラリやパッケージの既知の脆弱性検出 |
フィールド一覧
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
scan |
文字列 | ○ | スキャンタイプ |
site_profile |
文字列 | - | DASTサイトプロファイル名(DASTのみ) |
scanner_profile |
文字列 | - | DASTスキャナープロファイル名(DASTのみ) |
variables |
オブジェクト | - | CI/CD変数のキーと値のペア |
tags |
配列 | - | ランナータグのリスト |
template |
文字列 | - | テンプレートバージョン(defaultまたはlatest) |
scan_settings |
オブジェクト | - | スキャン設定 |
設定例
# 例1: 基本的なSASTスキャン
actions:
- scan: sast
# 例2: 特定のアナライザーを除外したSASTスキャン
actions:
- scan: sast
variables:
SAST_EXCLUDED_ANALYZERS: brakeman,eslint
# 例3: 専用ランナーでのコンテナスキャン
actions:
- scan: container_scanning
tags:
- security-runner
- docker
# 例4: DASTスキャン(プロファイル指定)
actions:
- scan: dast
scanner_profile: "標準スキャナープロファイル"
site_profile: "本番環境サイトプロファイル"
# 例5: 最新テンプレートを使用したSecret Detection
actions:
- scan: secret_detection
template: latest
scan_settings:
ignore_default_before_after_script: true
3.4. ポリシーテンプレート
GitLabは一般的なユースケースに対応する3つのテンプレートを提供しています。
| テンプレート名 | ユースケース | 最適な対象 | パイプラインソース |
|---|---|---|---|
| Merge Request Security Template | MR作成時のみスキャン実行 | インフラコストを削減したいチーム | merge_request_event |
| Scheduled Scanning Template | 定期的な自動スキャン | コンプライアンス要件があるプロジェクト | schedule |
| Merge Release Security Template | リリースブランチでの包括的スキャン | 本番デプロイメント前の検証 | push |
選択のガイドライン
3.5. ポリシースコープの設定
policy_scopeを使用して、ポリシーの適用範囲を細かく制御できます。
フィールド一覧
| フィールド | 説明 | 使用例 |
|---|---|---|
compliance_frameworks |
コンプライアンスフレームワークIDのリスト | PCI-DSS、SOC2対象プロジェクトのみ |
projects.including |
含めるプロジェクトIDのリスト | 特定プロジェクトのみに適用 |
projects.excluding |
除外するプロジェクトIDのリスト | テストプロジェクトを除外 |
groups.including |
含めるグループIDのリスト | 特定グループとその配下すべて |
設定例
# 例1: コンプライアンスフレームワークに基づく適用
policy_scope:
compliance_frameworks:
- id: 2 # PCI-DSS
- id: 11 # SOC2
# 例2: 特定グループのみ(一部プロジェクトを除外)
policy_scope:
groups:
including:
- id: 203 # セキュリティグループ
projects:
excluding:
- id: 64 # テストプロジェクト
- id: 128 # サンドボックスプロジェクト
# 例3: 特定プロジェクトのみに適用
policy_scope:
projects:
including:
- id: 42
- id: 84
- id: 126
3.6. skip_ciディレクティブの制御
GitLab 17.9で導入されたskip_ci設定により、[skip ci]ディレクティブの使用を制御できます。
フィールド一覧
| フィールド | 型 | 説明 |
|---|---|---|
allowed |
真偽値 |
trueで許可、falseで禁止 |
allowlist.users |
配列 | 常に許可するユーザーIDのリスト |
設定例
# 例1: すべてのユーザーに対してskip-ciを禁止
skip_ci:
allowed: false
# 例2: 特定ユーザーのみ許可
skip_ci:
allowed: false
allowlist:
users:
- id: 123 # サービスアカウント
- id: 456 # リリースマネージャー
# 例3: すべてのユーザーに許可
skip_ci:
allowed: true
重要な注意点
scheduleルールタイプを持つスキャン実行ポリシーは、常にskip_ciオプションを無視します。スケジュールされたスキャンは、最後のコミットメッセージに[skip ci]が含まれていても、設定された時刻に実行されます。
4. 実践的な設定例:ユースケース別
4.1. ユースケース1:マージリクエストでのセキュリティスキャン
要件: マージリクエスト作成時にのみスキャンを実行し、インフラコストを削減したい
scan_execution_policy:
- name: MRセキュリティスキャン
description: マージリクエスト作成時にSAST、Secret Detection、Dependency Scanningを実行
enabled: true
rules:
- type: pipeline
branch_type: target_default
pipeline_sources:
- merge_request_event
actions:
- scan: sast
- scan: secret_detection
- scan: dependency_scanning
variables:
DS_EXCLUDED_PATHS: "spec, test, tests, tmp, vendor"
4.2. ユースケース2:リリースブランチでの包括的スキャン
要件: リリースブランチへのプッシュ時に、すべてのセキュリティスキャンを実行したい
scan_execution_policy:
- name: リリースブランチ包括スキャン
description: リリースブランチでSAST、DAST、Container Scanning、Secret Detectionを実行
enabled: true
rules:
- type: pipeline
branches:
- release/*
- production
actions:
- scan: sast
template: latest
- scan: dast
scanner_profile: "本番環境スキャナー"
site_profile: "本番環境サイト"
- scan: container_scanning
tags:
- docker-runner
- scan: secret_detection
policy_scope:
compliance_frameworks:
- id: 2 # PCI-DSS
4.3. ユースケース3:定期的なセキュリティスキャン
要件: 毎日深夜にすべてのセキュリティスキャンを実行し、コンプライアンス要件を満たしたい
scan_execution_policy:
- name: 日次セキュリティスキャン
description: 毎日午前2時にすべてのセキュリティスキャンを実行
enabled: true
rules:
- type: schedule
branch_type: default
cadence: "0 2 * * *"
timezone: "Asia/Tokyo"
time_window:
value: 7200 # 2時間のウィンドウ
distribution: random
actions:
- scan: sast
- scan: secret_detection
- scan: dependency_scanning
- scan: container_scanning
- scan: sast_iac
4.4. ユースケース4:コンプライアンスフレームワーク別のスキャン
要件: PCI-DSS対象プロジェクトには厳格なスキャン、その他には標準スキャンを適用したい
scan_execution_policy:
# PCI-DSS対象プロジェクト用
- name: PCI-DSS厳格スキャン
description: PCI-DSS対象プロジェクトでの厳格なセキュリティスキャン
enabled: true
rules:
- type: pipeline
branch_type: protected
actions:
- scan: sast
template: latest
- scan: dast
scanner_profile: "厳格スキャナー"
site_profile: "本番環境"
- scan: secret_detection
- scan: dependency_scanning
- scan: container_scanning
policy_scope:
compliance_frameworks:
- id: 2 # PCI-DSS
skip_ci:
allowed: false # skip-ciを完全に禁止
# 標準プロジェクト用
- name: 標準セキュリティスキャン
description: 標準プロジェクトでの基本的なセキュリティスキャン
enabled: true
rules:
- type: pipeline
branch_type: default
actions:
- scan: sast
- scan: secret_detection
policy_scope:
projects:
excluding:
- id: 64 # テストプロジェクト
4.5. ユースケース5:段階的なロールアウト
要件: 新しいスキャンポリシーを段階的に導入したい
scan_execution_policy:
# フェーズ1: パイロットグループのみ
- name: セキュリティスキャン(パイロット)
description: パイロットグループでの新スキャンポリシー検証
enabled: true
rules:
- type: pipeline
branch_type: default
actions:
- scan: sast
template: latest
- scan: secret_detection
policy_scope:
groups:
including:
- id: 100 # パイロットグループ
# フェーズ2: 特定のコンプライアンスフレームワーク
# (パイロット成功後に有効化)
- name: セキュリティスキャン(コンプライアンス対象)
description: コンプライアンス対象プロジェクトへの展開
enabled: false # パイロット成功後にtrueに変更
rules:
- type: pipeline
branch_type: default
actions:
- scan: sast
template: latest
- scan: secret_detection
policy_scope:
compliance_frameworks:
- id: 2
- id: 11
5. CI/CD変数とスキャナーの動作
5.1. CI/CD変数の優先順位
スキャン実行ポリシーで定義された変数は、標準のCI/CD変数の優先順位に従います。以下の変数は事前設定された値を持ち、ポリシーで宣言された場合のみ上書き可能です。
事前設定された変数
DS_EXCLUDED_PATHS: spec, test, tests, tmp
SAST_EXCLUDED_PATHS: spec, test, tests, tmp
SECRET_DETECTION_EXCLUDED_PATHS: ''
SECRET_DETECTION_HISTORIC_SCAN: false
SAST_EXCLUDED_ANALYZERS: ''
DEFAULT_SAST_EXCLUDED_PATHS: spec, test, tests, tmp
DS_EXCLUDED_ANALYZERS: ''
SECURE_ENABLE_LOCAL_CONFIGURATION: true
重要: これらの変数はグループまたはプロジェクトのCI/CD変数では上書きできません。ポリシーで明示的に宣言する必要があります。
変数の上書き例
actions:
- scan: sast
variables:
SAST_EXCLUDED_PATHS: "spec, test, vendor, node_modules"
SAST_EXCLUDED_ANALYZERS: "brakeman"
- scan: dependency_scanning
variables:
DS_EXCLUDED_PATHS: "spec, test, vendor"
5.2. スキャナー別の動作特性
各スキャナーには特有の動作があります。理解しておくことで、適切な設定が可能になります。
5.2.1. SAST(静的アプリケーションセキュリティテスト)
- リポジトリにSASTがサポートするファイルが含まれている場合のみ実行されます
- サポート言語: Ruby、Python、Java、JavaScript、Go、C/C++など
5.2.2. Secret Detection(シークレット検出)
デフォルト動作
- デフォルトルールセットのルールのみがサポートされます
- ルールセットをカスタマイズする場合は、
SECRET_DETECTION_RULESET_GIT_REFERENCECI/CD変数を使用
スケジュール実行時の特別な動作
- 最初の実行:
historicモード(SECRET_DETECTION_HISTORIC_SCAN=true)で全履歴をスキャン - 2回目以降: 前回実行と現在のSHA間のコミット範囲のみをスキャン
# カスタムルールセットの使用例
actions:
- scan: secret_detection
variables:
SECRET_DETECTION_RULESET_GIT_REFERENCE: "main@my-group/custom-ruleset"
5.2.3. Container Scanning(コンテナスキャン)
-
pipelineルールタイプ:agentsオブジェクトで定義されたエージェントを無視 -
scheduleルールタイプ:agentsオブジェクトが考慮されます
Kubernetes環境でのスキャン例
rules:
- type: schedule
cadence: '0 10 * * *'
agents:
my-k8s-agent:
namespaces:
- 'default'
- 'production'
actions:
- scan: container_scanning
5.2.4. DAST(動的アプリケーションセキュリティテスト)
必須要件
- すべての対象プロジェクトに、指定されたサイトプロファイルとスキャナープロファイルが存在する必要があります
- プロファイルが存在しない場合、ポリシーは適用されず、エラーメッセージを含むジョブが作成されます
プロファイルの保護
- 有効なスキャン実行ポリシーでDASTプロファイルが指定されている場合、そのプロファイルは変更・削除できません
- プロファイルを編集または削除するには、まずポリシーを無効化する必要があります
6. 大規模運用のベストプラクティス
6.1. 段階的なロールアウト戦略
大規模な組織でポリシーを展開する際は、段階的なアプローチを推奨します。
推奨ステップ
-
パイロットグループの選定(1-2プロジェクト)
- 協力的な開発チーム
- 中規模のプロジェクト
- 代表的な技術スタック
-
部門単位での展開(10-20プロジェクト)
- セキュリティポリシースコープを活用
- フィードバックの収集と調整
-
全社展開
- コンプライアンスフレームワークベースの適用
- 継続的な監視と改善
6.2. 専用ランナーの設定
大規模環境では、セキュリティスキャン専用のランナーを設定することで、他のCI/CDジョブへの影響を最小化できます。
ランナー設定の例
# セキュリティスキャン専用ランナーを使用
actions:
- scan: sast
tags:
- security-runner
- high-memory
- scan: container_scanning
tags:
- security-runner
- docker
- scan: dast
tags:
- security-runner
- network-access
ランナー配置戦略
| ランナータイプ | 用途 | 推奨スペック |
|---|---|---|
security-runner |
一般的なセキュリティスキャン | 4 CPU、8GB RAM |
security-runner-high-memory |
SASTなどメモリ集約型スキャン | 8 CPU、16GB RAM |
security-runner-docker |
Container Scanning | Docker対応、SSD推奨 |
security-runner-network |
DAST | ネットワークアクセス可能 |
6.3. 同時実行制御とtime_window設定
大量のプロジェクトに対してスケジュールスキャンを実行する場合、time_windowを使用してパイプラインの実行を分散させます。
rules:
- type: schedule
branch_type: default
cadence: '0 2 * * *'
timezone: "Asia/Tokyo"
time_window:
value: 7200 # 2時間のウィンドウ
distribution: random
time_window設定のガイドライン
| プロジェクト数 | 推奨time_window | 説明 |
|---|---|---|
| 1-10 | 不要 | 同時実行でも問題なし |
| 10-50 | 3600秒(1時間) | 適度な分散 |
| 50-200 | 7200秒(2時間) | 十分な分散 |
| 200以上 | 14400秒(4時間) | 最大限の分散 |
6.4. 重複スキャンの回避
開発者がプロジェクトの.gitlab-ci.ymlファイルにスキャンジョブを含めている場合、スキャン実行ポリシーによって同じタイプのスキャナーが複数回実行される可能性があります。
回避方法1: プロジェクトのCI/CD設定からスキャンを削除
ポリシーでスキャンを一元管理する場合、プロジェクトの.gitlab-ci.ymlからスキャンジョブを削除します。
回避方法2: 変数でローカルジョブをスキップ
プロジェクトの.gitlab-ci.ymlに以下を追加します。
variables:
SAST_DISABLED: "true"
DAST_DISABLED: "true"
CONTAINER_SCANNING_DISABLED: "true"
SECRET_DETECTION_DISABLED: "true"
DEPENDENCY_SCANNING_DISABLED: "true"
注意: ジョブをスキップしても、スキャン実行ポリシーで定義されたセキュリティジョブの実行は妨げられません。
6.5. ポリシー更新の伝播
ポリシーの更新方法によって、変更が有効になるタイミングが異なります。
| 更新方法 | 有効化タイミング | 推奨用途 |
|---|---|---|
| マージリクエスト | マージ直後 | 本番環境での変更 |
| 直接コミット | 最大10分後 | 緊急時のみ |
推奨事項
- 本番環境では必ずマージリクエストを使用
- レビュープロセスを経てからマージ
- 変更内容を明確に記述
7. GitLab Security Policy Botの理解
7.1. Security Policy Botの役割
GitLab Security Policy Botは、セキュリティポリシーを実行する内部ユーザーです。
7.2. アカウント特性
- セキュリティポリシーが適用されたすべてのプロジェクトで自動的に作成
- プロジェクトでゲストロール権限で実行(特定の追加権限あり)
- 内部ユーザーとしてマークされているため、ライセンス制限にカウントされない
- 各プロジェクトが独自のSecurity Policy Botインスタンスを取得
7.3. 権限とアクセス
| 権限タイプ | 詳細 |
|---|---|
| リポジトリアクセス | ポリシー実行に必要なリポジトリコンテンツへの読み取り専用アクセス |
| パイプライン作成 | ポリシー強制のためのパイプライン作成とトリガー機能 |
| CI/CD変数 | 変数の優先順位ルールに従ってプロジェクトおよびグループ変数にアクセス |
| レジストリアクセス | 適切な認証情報で設定されている場合、コンテナレジストリに認証可能 |
7.4. 制限事項
- 手動で削除できません
- ユーザー設定や権限を手動で変更できません
- 各ボットインスタンスは特定のプロジェクトに紐付けられ、プロジェクト間で共有できません
- ボットの機能は、プロジェクトに設定されたセキュリティポリシーに完全に依存します
8. トラブルシューティング
8.1. スキャン実行ポリシーパイプラインが作成されない
症状: ポリシーを設定したが、パイプラインが作成されない
原因: プロジェクトの.gitlab-ci.ymlファイルのworkflow:rulesがパイプライン作成を妨げている可能性があります。
問題のある設定例
# .gitlab-ci.yml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never
この設定は、すべてのプッシュパイプラインを無効化するため、スキャン実行ポリシーもパイプラインを作成できません。
解決策1: workflow:rulesの修正
workflow:
rules:
# セキュリティポリシーからのパイプラインを許可
- if: $CI_PIPELINE_SOURCE == "security_orchestration_policy"
# その他のプッシュパイプラインは無効化
- if: $CI_PIPELINE_SOURCE == "push"
when: never
解決策2: scheduleルールタイプの使用
type: pipelineルールの代わりにtype: scheduleルールを使用します。スケジュールされたスキャン実行ポリシーはworkflow:rulesの影響を受けません。
# pipelineルールの代わりにscheduleルールを使用
rules:
- type: schedule
branches:
- main
cadence: "0 2 * * *"
解決策3: パイプライン実行ポリシーの使用
より細かい制御が必要な場合は、パイプライン実行ポリシーを使用します。
8.2. Security Policy Botの問題
8.2.1. スケジュールされたパイプラインが実行されない
確認項目
- ボットアカウントが存在し、禁止または削除されていないことを確認
- プロジェクトの「メンバー」ページで
security_policy_botを検索
- プロジェクトの「メンバー」ページで
- セキュリティポリシー設定が有効であることを確認
-
enabled: trueになっているか確認
-
- ボットがプロジェクトで必要な権限を持っていることを確認
解決方法
# ポリシーを再適用してボットを再作成
# 1. ポリシーを一時的に無効化
enabled: false
# 2. マージリクエストをマージ
# 3. ポリシーを再度有効化
enabled: true
# 4. マージリクエストをマージ
8.2.2. ポリシージョブが失敗する
確認項目
- ボットが必要なCI/CD変数にアクセスできることを確認
- 参照されているCI/CD設定ファイルが存在しアクセス可能であることを確認
- パイプラインログで特定のエラーメッセージを確認
よくあるエラーと解決方法
| エラーメッセージ | 原因 | 解決方法 |
|---|---|---|
Site profile not found |
DASTサイトプロファイルが存在しない | プロジェクトにサイトプロファイルを作成 |
Scanner profile not found |
DASTスキャナープロファイルが存在しない | プロジェクトにスキャナープロファイルを作成 |
Variable not defined |
必要なCI/CD変数が設定されていない | プロジェクトまたはグループにCI/CD変数を追加 |
8.2.3. ボットアカウントが存在しない
原因: ボットが誤って禁止または削除された可能性があります。
解決方法
- セキュリティポリシーを再適用または更新してボットアカウントを再作成
- ボットが誤って禁止または削除された場合は、GitLab管理者に連絡
警告: Security Policy Botインスタンスは、不正利用報告システムを通じて禁止または削除される可能性があり、スケジュールされたパイプラインの実行を妨げる可能性があります。管理者は内部ユーザーアカウントの不正利用報告を処理する際に注意が必要です。
8.3. スキャン結果が表示されない
症状: スキャンジョブは成功しているが、セキュリティダッシュボードに結果が表示されない
確認項目
- スキャンジョブがアーティファクトを生成しているか確認
- アーティファクトのパスが正しいか確認
- スキャン結果のフォーマットが正しいか確認
解決方法
パイプラインログで以下を確認します。
# スキャンジョブのログで以下のような出力を確認
Uploading artifacts...
gl-sast-report.json: found 1 matching files
アーティファクトが生成されていない場合は、スキャナーの設定を確認してください。
8.4. ポリシーが特定のプロジェクトに適用されない
症状: ポリシーを設定したが、特定のプロジェクトに適用されない
確認項目
-
policy_scopeの設定を確認 - プロジェクトがスコープに含まれているか確認
- ブランチ名が一致しているか確認
よくある問題
# 問題: ブランチ名が一致しない
rules:
- type: pipeline
branches:
- main # プロジェクトのデフォルトブランチが"master"の場合、適用されない
# 解決: branch_typeを使用
rules:
- type: pipeline
branch_type: default # デフォルトブランチに適用
9. 職務分離とセキュリティ
9.1. 職務分離の原則
ポリシーを成功裏に実装するには、職務分離が不可欠です。
9.2. 役割と責任
セキュリティとコンプライアンスチーム
- ポリシーを定義し、開発チームと協力してポリシーがニーズを満たすことを確認する責任があります
- セキュリティポリシープロジェクトの管理
- ポリシーの監視と改善
開発チーム
- ポリシーを無効化、変更、または回避することはできません
- ポリシーに従った開発
- スキャン結果への対応
9.3. 必要な権限
グループ、サブグループ、またはプロジェクトにセキュリティポリシープロジェクトを適用するには、以下のいずれかが必要です。
| 組織単位 | グループオーナー | サブグループオーナー | プロジェクトオーナー |
|---|---|---|---|
| グループ | ○ | × | × |
| サブグループ | ○ | ○ | × |
| プロジェクト | ○ | ○ | ○ |
または、manage_security_policy_link権限を持つカスタムロールが必要です。
9.4. セキュリティポリシープロジェクトの可視性
セキュリティポリシープロジェクトをリンクする際は、以下の推奨事項に従ってください。
推奨事項
- セキュリティポリシープロジェクトに機密コンテンツを含めない
- プライベートセキュリティポリシープロジェクトをリンクする前に、ターゲットプロジェクトのメンバーリストを確認
- ターゲットプロジェクトの可視性設定を評価
- セキュリティポリシー管理の監査ログを使用してプロジェクトリンクを監視
理由
プライベートセキュリティプロジェクトが別のプロジェクトにリンクされると、リンクされたプロジェクトのセキュリティポリシーページにアクセスできるユーザーは、.gitlab/security-policies/policy.ymlファイルの内容を表示できます。これには、プライベートセキュリティポリシープロジェクトをパブリックプロジェクトにリンクすることも含まれ、パブリックプロジェクトにアクセスできる誰でもポリシーの内容を閲覧できるようになります。
10. ポリシー推奨事項
10.1. ブランチ名の指定
ポリシーでブランチ名を指定する場合は、個別のブランチ名ではなく、デフォルトブランチやすべての保護されたブランチなどの保護されたブランチの一般的なカテゴリを使用します。
推奨しない設定
# 問題: 特定のブランチ名を指定
rules:
- type: pipeline
branches:
- main # 一部のプロジェクトは"master"を使用している可能性
推奨する設定
# 推奨: ブランチタイプを指定
rules:
- type: pipeline
branch_type: default # すべてのプロジェクトのデフォルトブランチに適用
理由: ポリシーは、指定されたブランチがそのプロジェクトに存在する場合にのみ適用されます。例えば、ポリシーがブランチmainにルールを適用するが、スコープ内の一部のプロジェクトがデフォルトブランチとしてproductionを使用している場合、後者にはポリシーが適用されません。
10.2. プッシュルールとの互換性
GitLab 17.3以前では、プッシュルールでブランチ名を検証している場合、update-policy-プレフィックスを持つブランチの作成を許可する必要があります。
GitLab 17.4以降では、セキュリティポリシープロジェクトはブランチ名検証を強制するプッシュルールから除外されます。
10.3. テスト環境での検証
本番環境にポリシーを適用する前に、必ずテスト環境で検証してください。
検証ステップ
- テスト用のセキュリティポリシープロジェクトを作成
- 少数のテストプロジェクトにポリシーを適用
- 各スキャンタイプが正常に実行されることを確認
- パフォーマンスへの影響を測定
- 開発チームからフィードバックを収集
- 必要に応じてポリシーを調整
- 本番環境に展開
11. 制限事項と注意点
11.1. ポリシー数の制限
| 制限項目 | 制限値 | 適用バージョン |
|---|---|---|
| 各ポリシーのルール数 | 最大5個 | すべてのバージョン |
| 各セキュリティポリシープロジェクトのスキャン実行ポリシー数 | 最大5個 | すべてのバージョン |
| 各ポリシーのアクション数 | 最大10個 | GitLab 18.0以降 |
| GitLab.comでのscheduleルール数 | 最初の10個のみ適用 | GitLab.com |
11.2. ローカル設定の優先順位
ローカルプロジェクトのYAMLファイルはスキャン実行ポリシーを上書きできません。これらのポリシーは、プロジェクトのCI/CD設定で同じジョブ名を使用している場合でも、パイプラインに対して定義された設定よりも優先されます。
例
# プロジェクトの.gitlab-ci.yml
sast:
variables:
SAST_EXCLUDED_ANALYZERS: "brakeman" # この設定は無視される
# スキャン実行ポリシー
actions:
- scan: sast
variables:
SAST_EXCLUDED_ANALYZERS: "eslint" # この設定が優先される
11.3. ポリシー更新の伝播
| 更新方法 | 有効化タイミング | 推奨用途 |
|---|---|---|
| マージリクエスト | マージ直後 | 本番環境での変更 |
| 直接コミット | 最大10分後 | 緊急時のみ |
11.4. スケジュールポリシーの動作
-
type: scheduleのポリシーは、設定されたcadenceに従ってのみ実行されます - ポリシーを更新しても、即座にスキャンはトリガーされません
- 次のスケジュールされた時刻まで待つ必要があります
12. まとめ
GitLabのセキュリティポリシー機能は、組織全体にわたって一貫したセキュリティとコンプライアンスの実装を可能にする強力なツールです。
12.1. 主要なポイント
ポリシータイプの選択
- 標準的なセキュリティスキャン → スキャン実行ポリシー
- 高度なカスタマイズ → パイプライン実行ポリシー
- 承認プロセスの制御 → マージリクエスト承認ポリシー
実装のベストプラクティス
- 段階的なロールアウト(パイロット → 部門 → 全社)
- 専用ランナーの設定でパフォーマンス最適化
-
time_windowを使用した同時実行制御 - テスト環境での十分な検証
運用のポイント
- ブランチタイプを使用した柔軟な設定
- ポリシースコープによる適用範囲の制御
- Security Policy Botの理解と適切な管理
- 職務分離の原則に基づいた権限管理
12.2. 次のステップ
- クイックスタートから始めて、基本的なポリシーを作成
- 実践的な設定例を参考に、自組織のユースケースに合わせてカスタマイズ
- 段階的なロールアウトで、パイロットグループから展開
- 継続的な監視と改善で、ポリシーを最適化
GitLabのセキュリティポリシーを活用することで、開発チームの生産性を維持しながら、組織全体のセキュリティレベルを向上させることができます。