GitLab CIによるDevSecOpsパイプラインの構築 は何をしますか?
概要
GitLabは、セキュリティテストをCI/CDパイプラインに直接組み込む統合DevSecOpsプラットフォームを提供します。GitLabの組み込みセキュリティスキャナー(SAST、DAST、コンテナスキャン、依存関係スキャン、シークレット検出、ライセンスコンプライアンス)を活用することで、チームはセキュリティを左シフトし、デプロイ後ではなく開発中に脆弱性を検出できます。GitLab Duo AIは、SAST脆弱性の誤検知検出を支援し、セキュリティチームが真のインシデントに集中できるようにします。
使用するタイミング
- 環境にDevSecOpsパイプライン構築機能をデプロイまたは設定する場合
- コンプライアンス要件に沿ったセキュリティコントロールを確立する場合
- このドメインのセキュリティアーキテクチャを構築または改善する場合
- この実装を必要とするセキュリティ評価を実施する場合
前提条件
- GitLab Ultimateライセンス(完全なセキュリティスキャナースイートに必要)
- GitLab Runnerの設定(共有またはセルフホスト)
.gitlab-ci.ymlパイプライン設定に関する知識- コンテナビルド用のDocker-in-Docker(DinD)またはKaniko
- DASTスキャン用のステージング環境にデプロイされたアプリケーション
コアセキュリティスキャンステージ
静的アプリケーションセキュリティテスト(SAST)
SASTは、コンパイル前にソースコードを分析して脆弱性を検出します。GitLabは、Semgrep、SpotBugs、Gosec、Bandit、NodeJsScanなどのアナライザーを使用して14以上の言語をサポートしています。最も簡単な導入方法は、GitLabの管理テンプレートを使用することです。
動的アプリケーションセキュリティテスト(DAST)
DASTは、実行中のアプリケーションに対して攻撃ペイロードをシミュレートしてテストします。XSS、SQLi、CSRF、およびその他の静的解析では見つけられない実行時脆弱性を検出します。DASTには、デプロイされアクセス可能なターゲットURLが必要です。
コンテナスキャン
Trivyを使用して、Dockerイメージ内のOSパッケージおよびアプリケーション依存関係の既知のCVEをスキャンします。Dockerビルドステージの後に実行され、イメージがレジストリに到達する前にゲートします。
依存関係スキャン
依存関係マニフェスト(package.json、requirements.txt、pom.xml、Gemfile.lockなど)を検査し、既知の脆弱性のあるバージョンを検出します。ソースコードレベルで動作し、コンテナスキャンを補完します。
シークレット検出
パターンマッチングとエントロピー分析を使用して、誤ってコミットされた資格情報、APIキー、トークン、秘密鍵をコミットごとにスキャンします。すべてのコミットで実行され、シークレットがリポジトリに到達するのを防ぎます。
実装
完全なパイプライン設定
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy-staging
- dast
- deploy-production
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
SECURE_LOG_LEVEL: "info"
# GitLab管理セキュリティテンプレートをインクルード
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Container-Scanning.gitlab-ci.yml
- template: DAST.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml
build:
stage: build
image: docker:24.0
services:
- docker:24.0-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
rules:
- if: $CI_COMMIT_BRANCH
unit-tests:
stage: test
image: $DOCKER_IMAGE
script:
- npm ci
- npm run test:coverage
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
artifacts:
reports:
junit: junit-report.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
# securityステージで実行するようにSASTをオーバーライド
sast:
stage: security
variables:
SAST_EXCLUDED_PATHS: "spec,test,tests,tmp,node_modules"
SEARCH_MAX_DEPTH: 10
# コンテナスキャンをオーバーライド
container_scanning:
stage: security
variables:
CS_IMAGE: $DOCKER_IMAGE
CS_SEVERITY_THRESHOLD: "HIGH"
# 依存関係スキャンをオーバーライド
dependency_scanning:
stage: security
# シークレット検出をオーバーライド
secret_detection:
stage: security
# ライセンスコンプライアンススキャン
license_scanning:
stage: security
deploy-staging:
stage: deploy-staging
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE -n staging
- kubectl rollout status deployment/app -n staging --timeout=300s
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# DASTはデプロイされたステージングに対して実行
dast:
stage: dast
variables:
DAST_WEBSITE: https://staging.example.com
DAST_FULL_SCAN_ENABLED: "true"
DAST_BROWSER_SCAN: "true"
needs:
- deploy-staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
deploy-production:
stage: deploy-production
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE -n production
- kubectl rollout status deployment/app -n production --timeout=300s
environment:
name: production
url: https://app.example.com
when: manual
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
セキュリティ承認ポリシー
必須のセキュリティスキャンを強制するためにスキャン実行ポリシーを設定します:
- Security & Compliance > Policies に移動
- すべてのブランチでSASTとシークレット検出を必須にする「Scan Execution Policy(スキャン実行ポリシー)」を作成
- 重要な脆弱性が検出された場合にセキュリティチームの承認を必要とする「Merge Request Approval Policy(マージリクエスト承認ポリシー)」を作成
カスタムSASTルールセット設定
アナライザーの動作をカスタマイズするには、.gitlab/sast-ruleset.toml を作成します:
[semgrep]
[[semgrep.ruleset]]
dirs = ["src"]
[[semgrep.passthrough]]
type = "url"
target = "/sgrep-rules/custom-rules.yml"
value = "https://semgrep.dev/p/owasp-top-ten"
[[semgrep.passthrough]]
type = "url"
target = "/sgrep-rules/java-rules.yml"
value = "https://semgrep.dev/p/java"
セキュリティダッシュボードと脆弱性管理
脆弱性レポート
GitLabはすべてのスキャナー結果を1つの脆弱性レポートに統合し、Security & Compliance > Vulnerability Report からアクセスできます。各脆弱性には以下が含まれます:
- 重大度評価(Critical、High、Medium、Low、Info)
- スキャナーソース(SAST、DAST、Container、Dependency、Secret)
- ソースコードまたはイメージレイヤー内の場所
- 修復ガイダンスと推奨修正
- ステータス追跡(Detected、Confirmed、Dismissed、Resolved)
マージリクエストセキュリティウィジェット
すべてのマージリクエストには、セキュリティスキャンウィジェットが表示され、以下が示されます:
- MRによって新たに導入された脆弱性
- MRによって修正された脆弱性
- ターゲットブランチのベースラインとの比較
パイプライン最適化
- 並列実行: セキュリティスキャナーはsecurityステージで同時に実行されます
- キャッシング: 依存関係のダウンロードにCIキャッシュを使用してスキャンを高速化
- インクリメンタルスキャン:
SAST_INCREMENTAL: "true"を使用して、変更されたファイルのみをSASTでスキャン可能 - 失敗条件: クリティカルなスキャナーに
allow_failure: falseを設定して品質ゲートを強制
監視とメトリクス
| メトリクス | 説明 | 目標 |
|---|---|---|
| パイプラインセキュリティカバレッジ | すべてのスキャナーが有効なプロジェクトの割合 | > 95% |
| 重要脆弱性の平均修復時間(MTTR) | 重要脆弱性の検出から解決までの時間 | < 48時間 |
| 誤検知率 | 誤検知として却下された検出結果の割合 | < 15% |
| シークレット検出ブロック率 | プッシュルールによってブロックされたシークレットコミットの割合 | > 99% |