ストーリー
セキュリティテストピラミッド
セキュリティテストピラミッド:
/\
/ \
/ 手動 \ ← ペネトレーションテスト
/ テスト \ (四半期ごと)
/──────────\
/ DAST \ ← 動的スキャン
/ (ステージング) \ (デプロイ後)
/────────────────\
/ SCA + SBOM \ ← 依存ライブラリ検査
/ (ビルド時/PR時) \ (ビルド時)
/──────────────────────\
/ SAST + シークレットスキャン \ ← 静的解析
/ (PR時・プリコミット) \ (コミット/PR時)
/──────────────────────────────\
/ IDE プラグイン + プリコミットフック \ ← 開発時チェック
/ (コーディング中) \ (リアルタイム)
/──────────────────────────────────────\
速い・安い ←──────────────────→ 遅い・高い
検出範囲:狭い ←──────────────→ 検出範囲:広い
パイプライン設計
フェーズ別のセキュリティチェック
| フェーズ | チェック | ツール例 | 実行時間 | ブロック |
|---|---|---|---|---|
| コーディング中 | IDEリアルタイム解析 | Semgrep LSP, Snyk IDE | リアルタイム | なし(警告のみ) |
| プリコミット | シークレットスキャン、リンター | gitleaks, detect-secrets | 数秒 | コミットブロック |
| PR作成時 | SAST、SCA、ライセンスチェック | Semgrep, Trivy, FOSSA | 2-5分 | マージブロック |
| ビルド時 | コンテナイメージスキャン、SBOM生成 | Trivy, Syft | 3-5分 | ビルドブロック |
| ステージングデプロイ後 | DAST、コンプライアンスチェック | ZAP, OPA | 10-30分 | デプロイブロック |
| 本番デプロイ前 | 最終承認、ポリシーチェック | OPA, 手動承認 | 1-5分 | デプロイブロック |
| 本番運用中 | 継続的モニタリング、WAF | CloudWatch, AWS WAF | 常時 | アラート |
統合パイプラインの全体像
# GitHub Actions: 統合セキュリティパイプライン
name: Security Pipeline
on:
pull_request:
branches: [main, develop]
push:
branches: [main]
jobs:
# Phase 1: PR時の静的チェック(並列実行)
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/typescript
.semgrep/custom-rules/
secret-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Gitleaks Secret Scan
uses: gitleaks/gitleaks-action@v2
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy SCA
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'HIGH,CRITICAL'
exit-code: '1'
license-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- name: License Check
run: npx license-checker --failOn 'GPL-3.0'
# Phase 2: ビルド時のコンテナスキャン
container-scan:
needs: [sast, secret-scan, sca, license-check]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Image
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy Image Scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'HIGH,CRITICAL'
exit-code: '1'
- name: Generate SBOM
run: |
syft myapp:${{ github.sha }} -o cyclonedx-json > sbom.json
- uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
# Phase 3: ステージング環境でのDASTスキャン(mainブランチのみ)
dast:
if: github.ref == 'refs/heads/main'
needs: [container-scan]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: ./scripts/deploy-staging.sh
- name: Wait for Deployment
run: ./scripts/wait-for-healthy.sh staging
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.9.0
with:
target: 'https://staging.example.com'
cmd_options: '-f openapi -O https://staging.example.com/api/openapi.json'
# Phase 4: コンプライアンスチェック
compliance:
if: github.ref == 'refs/heads/main'
needs: [dast]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: OPA Policy Check
run: |
opa eval --data policies/ --input scan-results.json \
"data.compliance.allow"
セキュリティゲートの設計
ゲートポリシーの定義
| ゲート | 条件 | 失敗時のアクション |
|---|---|---|
| PR マージゲート | SAST Critical = 0, SCA Critical = 0, シークレット検出 = 0 | マージブロック |
| ビルドゲート | コンテナ Critical = 0, High 未対応 < 5 | ビルド停止 |
| デプロイゲート | DAST Critical = 0, コンプライアンス準拠 | デプロイ停止 |
| リリースゲート | 全セキュリティチェック通過, SBOM生成完了 | リリース停止 |
例外処理(セキュリティ例外)
# security-exceptions.yaml
# 承認された例外を管理
exceptions:
- id: "EXC-2025-001"
vulnerability: "CVE-2024-12345"
package: "lodash@4.17.20"
reason: "影響を受ける関数を使用していない(確認済み)"
approved_by: "security-team-lead"
approved_date: "2025-01-15"
expiry_date: "2025-04-15"
review_date: "2025-03-15"
jira_ticket: "SEC-456"
「例外は許可するが、有効期限と定期レビューが必須だ。『永久に例外』は存在しない」 — 田中VPoE
セキュリティスキャン結果の統合管理
SARIF(Static Analysis Results Interchange Format)
セキュリティスキャン結果の統合フロー:
[SAST] ──→ SARIF ──┐
[DAST] ──→ SARIF ──├──→ [GitHub Security Tab]
[SCA] ──→ SARIF ──┤ or
[Secret]──→ SARIF ──┘ [DefectDojo]
or
[OWASP Dependency-Track]
利点:
├── 全ツールの結果を統一フォーマットで管理
├── 重複排除(同一脆弱性の複数検出をマージ)
├── ダッシュボードでの一元表示
└── トレンド分析(時系列での改善/悪化の追跡)
まとめ
| ポイント | 内容 |
|---|---|
| テストピラミッド | 軽量・高速(IDE/プリコミット)→ 重量・網羅的(DAST/ペンテスト)の階層 |
| フェーズ配置 | PR時にSAST/SCA、ビルド時にコンテナスキャン、デプロイ後にDAST |
| ゲート設計 | 各フェーズにブロック条件を設定、例外は有効期限付きで管理 |
| 結果の統合 | SARIFフォーマットで統一し、ダッシュボードで一元管理 |
チェックリスト
- セキュリティテストピラミッドの各層を説明できる
- フェーズ別のセキュリティチェック配置を設計できる
- GitHub Actionsでの統合パイプラインの構成を理解した
- セキュリティゲートと例外処理の設計方針を理解した
次のステップへ
次は演習です。実際のCI/CDパイプラインにSAST/DAST/SCAを統合するセキュリティパイプラインを設計しましょう。
推定読了時間: 30分