building-devsecops-pipeline-with-gitlab-ci について
GitLab CI を利用するチーム向けに、CI/CD パイプラインへセキュリティ検査を組み込む方法を解説します。スキャン、ポリシー適用、脆弱性の報告と管理を扱います。
主な機能
- 01SAST、DAST、コンテナスキャンの設定
- 02依存関係の脆弱性と漏えいシークレットの検出
- 03スキャンと承認ポリシーの設定
- 04脆弱性レポートとマージリクエスト結果の確認
- 05並列スキャンと差分スキャンの最適化
活用シーン
- 01プロジェクトの DevSecOps パイプライン構築
- 02デプロイ前のアプリとコンテナのリスク検出
- 03コンプライアンスに沿ったセキュリティ検査の適用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill building-devsecops-pipeline-with-gitlab-ciインストール後、Claude Code で/building-devsecops-pipeline-with-gitlab-ciを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
GitLab CI による DevSecOps パイプラインの構築
概要
GitLab は、セキュリティテストを CI/CD パイプラインに直接組み込んだ、統合型の DevSecOps プラットフォームを提供します。GitLab に組み込まれたセキュリティスキャナー(SAST、DAST、コンテナスキャン、依存関係スキャン、シークレット検出、ライセンスコンプライアンス)を活用することで、チームはセキュリティ対策を開発の早い段階に取り入れ、デプロイ後ではなく開発中に脆弱性を検出できます。GitLab Duo AI は、SAST の脆弱性に対する誤検知の検出を支援し、セキュリティチームが実際の問題に集中できるようにします。
使用するタイミング
- 環境で GitLab CI による 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 は、HTTP エンドポイントに攻撃ペイロードを模擬的に送信して、稼働中のアプリケーションをテストします。静的解析では検出できない 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"
# Include GitLab managed security templates
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
# Override SAST to run in security stage
sast:
stage: security
variables:
SAST_EXCLUDED_PATHS: "spec,test,tests,tmp,node_modules"
SEARCH_MAX_DEPTH: 10
# Override container scanning
container_scanning:
stage: security
variables:
CS_IMAGE: $DOCKER_IMAGE
CS_SEVERITY_THRESHOLD: "HIGH"
# Override dependency scanning
dependency_scanning:
stage: security
# Override secret detection
secret_detection:
stage: security
# License compliance scanning
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 runs against deployed staging
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 は、すべてのスキャナーの検出結果を統合し、Security & Compliance > Vulnerability Report からアクセスできる単一の脆弱性レポートにまとめます。各脆弱性には、次の情報が含まれます。
- 重大度(Critical、High、Medium、Low、Info)
- スキャナーの種類(SAST、DAST、コンテナ、依存関係、シークレット)
- ソースコードまたはイメージレイヤー内の場所
- 修正方法の説明と推奨される修正
- ステータスの追跡(検出済み、確認済み、却下済み、解決済み)
マージリクエストのセキュリティウィジェット
すべてのマージリクエストには、次の情報を表示するセキュリティスキャンウィジェットが表示されます。
- MR によって新たに持ち込まれた脆弱性
- MR によって修正された脆弱性
- ターゲットブランチのベースラインとの比較
パイプラインの最適化
- 並列実行:セキュリティスキャナーはセキュリティステージで並行して実行されます
- キャッシュ:CI キャッシュを使用して依存関係のダウンロードをキャッシュし、スキャンを高速化します
- 増分スキャン:
SAST_INCREMENTAL: "true"を使用すると、SAST で変更されたファイルのみをスキャンできます - 失敗条件:重要なスキャナーに
allow_failure: falseを設定して、品質ゲートを適用します
監視とメトリクス
| メトリクス | 説明 | 目標 |
|---|---|---|
| パイプラインのセキュリティカバレッジ | すべてのスキャナーが有効になっているプロジェクトの割合 | > 95% |
| 重大な脆弱性の MTTR | 重大な検出結果の検出から解決までの時間 | < 48 hours |
| 誤検知率 | 誤検知として却下された検出結果の割合 | < 15% |
| シークレット検出のブロック率 | プッシュルールによってブロックされたシークレットを含むコミットの割合 | > 99% |