DevSecOps 2025 - セキュリティをシフトレフト

2026.01.12

DevSecOpsとは何か

DevSecOpsは、開発(Development)、セキュリティ(Security)、運用(Operations)を統合したアプローチです。従来のウォーターフォール型開発では、セキュリティテストはリリース直前に行われていましたが、DevSecOpsでは開発の初期段階からセキュリティを組み込む「シフトレフト」の考え方を採用します。

2025年現在、DevSecOpsは単なるバズワードから成熟した実践へと進化しました。クラウドネイティブアーキテクチャの普及、サプライチェーン攻撃の増加、規制要件の厳格化により、組織はセキュリティを開発プロセスに深く統合する必要に迫られています。

DevSecOps成熟度モデル

組織のDevSecOps成熟度を評価するためのフレームワークを紹介します。

レベル1: 初期段階(Ad-hoc)

  • セキュリティテストは手動で不定期に実施
  • 開発チームとセキュリティチームの連携が限定的
  • 脆弱性の発見から修正まで数週間〜数ヶ月

レベル2: 基礎段階(Basic)

  • 基本的なSASTツールをCI/CDに導入
  • セキュリティポリシーが文書化されている
  • 定期的なセキュリティレビューを実施

レベル3: 標準化段階(Standardized)

  • 複数のセキュリティツールがパイプラインに統合
  • セキュリティゲートによる自動ブロック機能
  • セキュリティメトリクスの可視化

レベル4: 最適化段階(Optimized)

  • リスクベースの脆弱性優先順位付け
  • 開発者向けセキュリティトレーニングの体系化
  • インシデント対応の自動化

レベル5: 革新段階(Innovative)

  • AIを活用した脆弱性予測と自動修正
  • セキュリティがビジネス価値として認識される
  • 継続的なセキュリティ改善文化の確立

セキュリティツールチェーンの全体像

SAST(Static Application Security Testing)

SASTは、ソースコードを静的に解析して脆弱性を検出します。コードがコミットされた時点で実行され、SQLインジェクション、XSS、バッファオーバーフローなどの脆弱性を早期に発見できます。

# GitHub Actions での SAST 統合例
name: SAST Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: javascript, typescript
          queries: +security-extended

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:javascript"

      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/security-audit
            p/secrets
            p/owasp-top-ten
          generateSarif: true

      - name: Upload SARIF results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: semgrep.sarif

主要なSASTツール:

  • CodeQL: GitHubが提供する強力な静的解析エンジン
  • Semgrep: 軽量で高速、カスタムルールが書きやすい
  • SonarQube: コード品質とセキュリティを統合的に管理
  • Checkmarx: エンタープライズ向けの包括的なSASTソリューション

DAST(Dynamic Application Security Testing)

DASTは、実行中のアプリケーションに対して外部から攻撃をシミュレートします。SASTでは検出できない実行時の脆弱性を発見できます。

# DAST スキャンのCI/CD統合
name: DAST Scan

on:
  deployment:
    types: [completed]

jobs:
  dast:
    runs-on: ubuntu-latest
    if: github.event.deployment.environment == 'staging'
    steps:
      - name: ZAP Full Scan
        uses: zaproxy/action-full-scan@v0.10.0
        with:
          target: "https://staging.example.com"
          rules_file_name: ".zap/rules.tsv"
          cmd_options: "-a -j -l WARN"
          issue_title: "ZAP Scan Report"
          fail_action: true
          allow_issue_writing: true

      - name: Nuclei Scan
        uses: projectdiscovery/nuclei-action@main
        with:
          target: "https://staging.example.com"
          templates: "cves,vulnerabilities,misconfiguration"
          output: "nuclei-report.txt"
          sarif-export: "nuclei.sarif"

      - name: Upload DAST Results
        uses: actions/upload-artifact@v4
        with:
          name: dast-results
          path: |
            nuclei-report.txt
            nuclei.sarif

SCA(Software Composition Analysis)

SCAは、オープンソースコンポーネントとサードパーティライブラリの脆弱性を検出します。2025年現在、サプライチェーン攻撃の増加により、SCAの重要性は飛躍的に高まっています。

# SCA 統合パイプライン
name: Dependency Security Scan

on:
  push:
    paths:
      - "package.json"
      - "package-lock.json"
      - "requirements.txt"
      - "go.mod"
      - "Cargo.toml"
  schedule:
    - cron: "0 6 * * *" # 毎日午前6時に実行

jobs:
  sca:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        continue-on-error: true
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high --sarif-file-output=snyk.sarif

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: "fs"
          scan-ref: "."
          format: "sarif"
          output: "trivy-results.sarif"
          severity: "CRITICAL,HIGH"

      - name: SBOM Generation
        uses: anchore/sbom-action@v0
        with:
          format: spdx-json
          output-file: sbom.spdx.json

      - name: Dependency Review
        uses: actions/dependency-review-action@v4
        with:
          fail-on-severity: high
          deny-licenses: GPL-3.0, AGPL-3.0
          allow-ghsas: false

IAST(Interactive Application Security Testing)

IASTは、アプリケーション内部にエージェントを配置し、実行時の動作を監視します。SASTとDASTの利点を組み合わせた手法です。

# IAST エージェント設定例(Contrast Security)
agent:
  java:
    enable: true
    standalone_app_name: my-application
    server:
      name: production-server
      environment: production

  # ルール設定
  assess:
    enable: true
    rules:
      disabled_rules:
        - reflected-xss  # 特定のルールを無効化

  # 保護モード
  protect:
    enable: true
    rules:
      bot-blocker:
        mode: BLOCK
      sql-injection:
        mode: BLOCK
      cmd-injection:
        mode: BLOCK

  # レポート設定
  reporting:
    period: 3000

  # プロキシ設定
  proxy:
    enable: false

CI/CD統合の実践パターン

パターン1: ゲートキーパーモデル

各ステージにセキュリティゲートを設置し、基準を満たさない場合はパイプラインを停止します。

# GitLab CI/CD でのゲートキーパー実装
stages:
  - build
  - test
  - security-gate-1
  - integration-test
  - security-gate-2
  - deploy-staging
  - security-gate-3
  - deploy-production

variables:
  SEVERITY_THRESHOLD: "HIGH"
  MAX_CRITICAL_VULNS: 0
  MAX_HIGH_VULNS: 5

sast-scan:
  stage: security-gate-1
  image: registry.gitlab.com/security-products/sast:latest
  script:
    - /analyzer run
  artifacts:
    reports:
      sast: gl-sast-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

security-gate-evaluation-1:
  stage: security-gate-1
  needs: [sast-scan]
  script:
    - |
      CRITICAL_COUNT=$(jq '[.vulnerabilities[] | select(.severity=="Critical")] | length' gl-sast-report.json)
      HIGH_COUNT=$(jq '[.vulnerabilities[] | select(.severity=="High")] | length' gl-sast-report.json)

      echo "Critical vulnerabilities: $CRITICAL_COUNT"
      echo "High vulnerabilities: $HIGH_COUNT"

      if [ "$CRITICAL_COUNT" -gt "$MAX_CRITICAL_VULNS" ]; then
        echo "Security gate failed: Too many critical vulnerabilities"
        exit 1
      fi

      if [ "$HIGH_COUNT" -gt "$MAX_HIGH_VULNS" ]; then
        echo "Security gate failed: Too many high vulnerabilities"
        exit 1
      fi

      echo "Security gate passed"

container-scan:
  stage: security-gate-2
  image: aquasec/trivy:latest
  script:
    - trivy image --exit-code 1 --severity CRITICAL,HIGH $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  allow_failure: false

dast-scan:
  stage: security-gate-3
  image: owasp/zap2docker-stable
  script:
    - zap-full-scan.py -t $STAGING_URL -r zap-report.html -x zap-report.xml
  artifacts:
    paths:
      - zap-report.html
      - zap-report.xml
    when: always

パターン2: リスクベースアプローチ

変更の影響範囲とリスクレベルに応じて、スキャンの深度を動的に調整します。

# リスクベースのスキャン設定
name: Risk-Based Security Scan

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  risk-assessment:
    runs-on: ubuntu-latest
    outputs:
      risk_level: ${{ steps.assess.outputs.risk_level }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Assess Risk Level
        id: assess
        run: |
          # 変更されたファイルを取得
          CHANGED_FILES=$(git diff --name-only origin/main...HEAD)

          RISK_LEVEL="low"

          # 認証・認可関連の変更
          if echo "$CHANGED_FILES" | grep -qE "(auth|login|session|token|jwt|oauth)"; then
            RISK_LEVEL="critical"
          # 決済・金融関連の変更
          elif echo "$CHANGED_FILES" | grep -qE "(payment|billing|transaction|stripe|paypal)"; then
            RISK_LEVEL="critical"
          # API・エンドポイントの変更
          elif echo "$CHANGED_FILES" | grep -qE "(api/|routes/|controllers/)"; then
            RISK_LEVEL="high"
          # データベース・モデルの変更
          elif echo "$CHANGED_FILES" | grep -qE "(models/|migrations/|schema)"; then
            RISK_LEVEL="high"
          # 設定ファイルの変更
          elif echo "$CHANGED_FILES" | grep -qE "(config|\.env|secrets)"; then
            RISK_LEVEL="medium"
          fi

          echo "risk_level=$RISK_LEVEL" >> $GITHUB_OUTPUT
          echo "Risk Level: $RISK_LEVEL"

  security-scan:
    needs: risk-assessment
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Basic Scan (All PRs)
        run: |
          # 基本的なシークレット検出
          docker run --rm -v $(pwd):/repo trufflesecurity/trufflehog:latest \
            git file:///repo --only-verified

      - name: Extended Scan (Medium+ Risk)
        if: needs.risk-assessment.outputs.risk_level != 'low'
        run: |
          # SAST スキャン
          semgrep --config=auto --sarif --output=semgrep.sarif .

      - name: Deep Scan (High+ Risk)
        if: needs.risk-assessment.outputs.risk_level == 'high' || needs.risk-assessment.outputs.risk_level == 'critical'
        run: |
          # 依存関係の深度スキャン
          snyk test --all-projects --severity-threshold=medium

          # コンテナイメージスキャン
          trivy image --severity HIGH,CRITICAL ${{ env.IMAGE_NAME }}

      - name: Critical Scan (Critical Risk)
        if: needs.risk-assessment.outputs.risk_level == 'critical'
        run: |
          # 手動レビュー要求
          gh pr edit ${{ github.event.pull_request.number }} \
            --add-label "security-review-required"

          # セキュリティチームへの通知
          curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
            -H "Content-Type: application/json" \
            -d '{"text": "Critical risk PR requires security review: ${{ github.event.pull_request.html_url }}"}'

セキュリティゲート設計のベストプラクティス

ゲート基準の定義

# security-gates.yaml - セキュリティゲート設定ファイル
gates:
  # 開発ブランチへのマージ前ゲート
  pre-merge:
    name: "Pre-Merge Security Gate"
    enabled: true
    blocking: true
    criteria:
      sast:
        critical: 0
        high: 3
        medium: 10
        new_issues_only: true
      secrets:
        any_detected: false
      sca:
        critical: 0
        high: 5
        license_violations: false

  # ステージング環境デプロイ前ゲート
  pre-staging:
    name: "Pre-Staging Security Gate"
    enabled: true
    blocking: true
    criteria:
      sast:
        critical: 0
        high: 0
        medium: 5
      dast:
        critical: 0
        high: 2
      container:
        critical: 0
        high: 3

  # 本番環境デプロイ前ゲート
  pre-production:
    name: "Pre-Production Security Gate"
    enabled: true
    blocking: true
    criteria:
      sast:
        critical: 0
        high: 0
        medium: 0
      dast:
        critical: 0
        high: 0
        medium: 3
      sca:
        critical: 0
        high: 0
        eol_components: false
      container:
        critical: 0
        high: 0
      compliance:
        pci_dss: true
        soc2: true
        gdpr: true

  # 緊急デプロイ用の例外ゲート
  emergency:
    name: "Emergency Deploy Gate"
    enabled: true
    blocking: false
    requires_approval:
      - security-team-lead
      - ciso
    criteria:
      sast:
        critical: 0
      secrets:
        any_detected: false
    audit:
      enabled: true
      retention_days: 365

例外処理とリスク受容

# 脆弱性の例外処理設定
exceptions:
  # 既知の誤検出
  false_positives:
    - id: "CVE-2024-12345"
      reason: "開発環境のみで使用、本番には影響なし"
      approved_by: "security-team"
      expires: "2025-06-30"

  # リスク受容
  risk_accepted:
    - id: "SNYK-JS-LODASH-1018905"
      reason: "影響を受ける関数は使用していない"
      approved_by: "ciso"
      expires: "2025-03-31"
      compensating_controls:
        - "WAFルールで入力値を検証"
        - "該当エンドポイントのレート制限"

  # 一時的な例外(ホットフィックス用)
  temporary:
    - id: "HIGH-VULN-001"
      reason: "緊急のビジネス要件、修正チケット作成済み"
      approved_by: "vp-engineering"
      expires: "2025-01-20"
      jira_ticket: "SEC-1234"

Infrastructure as Code(IaC)セキュリティ

クラウドインフラの設定ミスは、データ漏洩の主要な原因の一つです。IaCスキャンをパイプラインに統合することで、デプロイ前に設定の問題を検出できます。

# IaC セキュリティスキャン
name: IaC Security Scan

on:
  push:
    paths:
      - "terraform/**"
      - "cloudformation/**"
      - "kubernetes/**"
      - "helm/**"

jobs:
  iac-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Checkov Scan
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: terraform/
          framework: terraform
          soft_fail: false
          output_format: sarif
          output_file_path: checkov.sarif

      - name: tfsec Scan
        uses: aquasecurity/tfsec-action@v1.0.3
        with:
          working_directory: terraform/
          soft_fail: false

      - name: Trivy Config Scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: "config"
          scan-ref: "."
          format: "sarif"
          output: "trivy-config.sarif"

      - name: KICS Scan
        uses: Checkmarx/kics-github-action@v1.7.0
        with:
          path: "."
          output_path: "kics-results"
          output_formats: "sarif,json"
          fail_on: high,medium

      - name: Upload Results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: .

Terraformセキュリティポリシーの例

# Sentinel Policy(HashiCorp Sentinel)
import "tfplan/v2" as tfplan

# S3バケットは暗号化必須
s3_bucket_encryption = rule {
  all tfplan.resource_changes as _, rc {
    rc.type is "aws_s3_bucket" and
    rc.change.after.server_side_encryption_configuration is not null
  }
}

# セキュリティグループで0.0.0.0/0へのインバウンドを禁止
no_public_ingress = rule {
  all tfplan.resource_changes as _, rc {
    rc.type is "aws_security_group_rule" and
    rc.change.after.type is "ingress" implies
    rc.change.after.cidr_blocks not contains "0.0.0.0/0"
  }
}

# RDSは暗号化とバックアップ必須
rds_security = rule {
  all tfplan.resource_changes as _, rc {
    rc.type is "aws_db_instance" implies (
      rc.change.after.storage_encrypted is true and
      rc.change.after.backup_retention_period > 0
    )
  }
}

main = rule {
  s3_bucket_encryption and
  no_public_ingress and
  rds_security
}

シークレット管理とスキャン

# シークレット検出の包括的設定
name: Secret Detection

on:
  push:
    branches: ["*"]
  pull_request:
    branches: [main, develop]

jobs:
  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # Git履歴全体をスキャン
      - name: TruffleHog Scan
        uses: trufflesecurity/trufflehog@main
        with:
          path: ./
          base: ${{ github.event.repository.default_branch }}
          head: HEAD
          extra_args: --only-verified

      # GitLeaks でパターンマッチング
      - name: Gitleaks Scan
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

      # AWS認証情報の特化スキャン
      - name: AWS Credential Scan
        run: |
          # AWS キーパターンの検出
          if grep -rE "(AKIA|ABIA|ACCA|ASIA)[0-9A-Z]{16}" --include="*.{js,ts,py,go,java,json,yaml,yml,env}" .; then
            echo "AWS credentials detected!"
            exit 1
          fi

      # Pre-commit hookの設定確認
      - name: Verify Pre-commit Hooks
        run: |
          if [ ! -f ".pre-commit-config.yaml" ]; then
            echo "Warning: pre-commit config not found"
            exit 1
          fi

文化と組織の変革

技術的なツールだけでは、DevSecOpsは成功しません。組織文化の変革が不可欠です。

セキュリティチャンピオンプログラム

各開発チームにセキュリティチャンピオンを配置し、セキュリティ意識を組織全体に浸透させます。

# セキュリティチャンピオン責任マトリクス
security_champions:
  responsibilities:
    - name: "コードレビュー"
      description: "セキュリティ観点からのコードレビュー実施"
      frequency: "全PR"

    - name: "脆弱性トリアージ"
      description: "チーム内の脆弱性優先順位付けと割り当て"
      frequency: "週次"

    - name: "セキュリティトレーニング"
      description: "チームメンバーへのセキュリティ教育"
      frequency: "月次"

    - name: "インシデント対応"
      description: "セキュリティインシデント発生時の初動対応"
      frequency: "発生時"

  training_path:
    - level: "beginner"
      courses:
        - "OWASP Top 10 概要"
        - "セキュアコーディング基礎"
      certification: "Security Champion Bronze"

    - level: "intermediate"
      courses:
        - "脅威モデリング実践"
        - "ペネトレーションテスト基礎"
      certification: "Security Champion Silver"

    - level: "advanced"
      courses:
        - "アプリケーションセキュリティアーキテクチャ"
        - "インシデントレスポンス"
      certification: "Security Champion Gold"

メトリクスとKPI

DevSecOpsの効果を測定するための主要指標を設定します。

# DevSecOps KPI ダッシュボード設定
metrics:
  # 脆弱性関連
  vulnerability:
    - name: "MTTR (Mean Time To Remediate)"
      target:
        critical: "24 hours"
        high: "7 days"
        medium: "30 days"
      current: "$CURRENT_MTTR"

    - name: "Vulnerability Escape Rate"
      description: "本番環境で発見された脆弱性の割合"
      target: "< 5%"
      current: "$ESCAPE_RATE"

    - name: "Security Debt"
      description: "未修正の脆弱性の総数"
      target: "< 50"
      current: "$SECURITY_DEBT"

  # プロセス関連
  process:
    - name: "Security Gate Pass Rate"
      description: "初回でセキュリティゲートを通過したビルドの割合"
      target: "> 85%"
      current: "$PASS_RATE"

    - name: "Developer Security Training Coverage"
      description: "セキュリティトレーニングを完了した開発者の割合"
      target: "100%"
      current: "$TRAINING_COVERAGE"

  # ビジネス関連
  business:
    - name: "Security Incident Count"
      target: "0"
      current: "$INCIDENT_COUNT"

    - name: "Compliance Audit Findings"
      target: "< 3"
      current: "$AUDIT_FINDINGS"

2025年のベストプラクティス

1. AIを活用した脆弱性検出

# AI支援セキュリティスキャン
ai_security:
  vulnerability_prediction:
    enabled: true
    model: "security-ml-v3"
    features:
      - code_complexity
      - historical_vulnerabilities
      - developer_experience
      - component_age
    threshold: 0.75

  auto_remediation:
    enabled: true
    confidence_threshold: 0.95
    supported_fixes:
      - sql_injection_parameterization
      - xss_output_encoding
      - dependency_upgrade
    require_approval: true

  false_positive_reduction:
    enabled: true
    learning_from_feedback: true
    minimum_training_samples: 100

2. サプライチェーンセキュリティ

# SLSA(Supply-chain Levels for Software Artifacts)準拠
slsa:
  level: 3
  requirements:
    source:
      - version_controlled: true
      - verified_history: true
      - two_person_reviewed: true

    build:
      - scripted_build: true
      - build_service: true
      - ephemeral_environment: true
      - isolated: true

    provenance:
      - available: true
      - authenticated: true
      - service_generated: true
      - non_falsifiable: true

  attestation:
    format: "in-toto"
    sign_with: "sigstore/cosign"
    verify_on_deploy: true

3. ゼロトラストセキュリティの統合

# ゼロトラスト原則のCI/CD適用
zero_trust_pipeline:
  # すべてのアクセスを検証
  identity_verification:
    - service_accounts: "workload_identity"
    - human_access: "mfa_required"
    - external_services: "mtls"

  # 最小権限の原則
  least_privilege:
    - pipeline_permissions: "minimal"
    - secret_access: "just_in_time"
    - artifact_access: "signed_required"

  # 継続的な検証
  continuous_verification:
    - artifact_integrity: "every_stage"
    - runtime_protection: "enabled"
    - anomaly_detection: "ml_based"

まとめ

DevSecOpsは2025年において、もはやオプションではなく必須の実践となっています。成功の鍵は、適切なツールの選択、CI/CDへの緊密な統合、そして組織文化の変革にあります。

セキュリティを開発の最初から組み込む「シフトレフト」アプローチにより、脆弱性の修正コストを大幅に削減し、より安全なソフトウェアを迅速にデリバリーすることが可能になります。

継続的な学習と改善を通じて、組織全体でセキュリティ意識を高め、DevSecOpsの成熟度を段階的に向上させていくことが重要です。

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

LINEで無料相談する
← 一覧に戻る