20
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

脆弱性ツールとコードベースからセキュリティ品質の達成状況を教えてくれる 「私のセキュリティ監査人」を作った話

Last updated at Posted at 2025-12-19

0. はじめに

あるプロダクトのリリースに向けて、私は開発チーム側の立場でセキュリティ監査をサポートする役割を担当しました。
監査は GitHub Issue 上で進められ、チェックシートの監査項目ごとに Issue を立て、エビデンスを貼り、監査人と質疑応答を行う形でした。監査項目すべてが満たされると、監査レポートが発行され、監査終了...といった感じです。

その監査には、トータルで半年近くかかってしまいました。いやー長い戦いでした。

振り返ったところ、特に時間を消費していたのは、
• 開発チームがエビデンスを集め、説明用に整理する作業
• エビデンスだけでは意図が伝わらず、Issue 上で何度も発生する質疑応答
でした。
いずれも人手によって非同期で行われるので待ち時間も多く、とても時間がかかってしまいました。

この経験から、
「コードベースやセキュリティツールの結果を横断的に読んで、
セキュリティ観点での達成度を説明してくれる“もう一人の監査人”がいればいいのでは?」
と考えるようになりました。

監査のやり取りはすでに GitHub 上で行われています。
それなら、Issue から AI を呼び出し、コードやツール結果を元に質問へ答える仕組みを作れば、監査対応の負担を減らせるのではないか。
そうして作り始めたのが、「私のセキュリティ監査人」です。

本記事では、このプロトタイプを GitHub Actions と Claude Code、複数のセキュリティツール連携を使って、どのように設計・実装しているかを紹介します。
まずは 開発チームが監査前にセルフチェックできること を目的にしています。

1. このプロダクトは何か

このプロダクトは、GitHub 上で行われているセキュリティ監査・レビューのやり取りに AI を組み込むことを目的としたものです。

使い方はシンプルで、GitHub Issue や PR コメントで
@claude とメンションして質問するだけです。

裏側では GitHub Actions が起動し、
• リポジトリ内のコードや設定ファイル
• 脆弱性スキャンやセキュリティツールの結果

を横断的に読み取り、監査項目に関連する実装情報を収集・整理して回答します。

できること

このプロトタイプで AI が行うのは、判定ではなく情報整理です。
• 監査項目に関連する実装箇所を網羅的に探す
• 要件と実装を対応付けて整理する
• ファイルパスや設定内容、コード片を具体的に提示する
• 該当する実装が見つからない場合は、その事実を示す

「問題ない」「要件を満たしている」といった評価は行わず、
人間の監査人が判断できるだけの材料を揃えることに徹しています。

2. なぜ作ったのか

このプロダクトでは、AI に監査項目の最終的な合否や準拠判断をさせない設計を採用しています。

これは最初から決めていた方針ではありません。
開発を進める中で、セキュリティ部門の担当者にヒアリングを行った際、
「AI を完全に信用して監査判断を任せることには抵抗がある」という意見を聞きました。

そこで役割を分けることにしました。
• AI には、監査項目に関連する実装情報の収集と整理を任せる
• 最終的な判断や責任は、人間の監査人が持つ

AI は、監査項目に関連する実装箇所を探し、要件と実装を対応付けて整理し、ファイルパスやコード片といった事実を提示するところまでを担います。
一方で、「満たしている」「問題ない」といった評価や判定は行いません。

また、用途もいきなり監査人向けにはせず、
開発チームが監査前にセルフチェックするためのツールとして位置づけました。
判断を代替するのではなく、説明や確認の下準備を支援することを狙っています。

この役割分担の考え方が、後述するアーキテクチャやプロンプト設計の前提になっています。

3. アーキテクチャ設計

前章で述べた通り、このプロダクトでは AI に最終的な判断をさせず、
人間が判断できるだけの情報を整理して提示する役割に限定しています。
そのため、既存の開発・監査フローを極力変えずに、AIを差し込むことを重視して設計しました。

業務の導線上になければ、ツール切り替えの手間が生まれ、使いにくくなるからです。
その結果、アーキテクチャの中心には GitHub と GitHub Actions を据えています。

全体像

この図が示している通り、構成自体はシンプルです。
• ユーザーは GitHub Issue / PR コメント上で @claude とメンションする
• GitHub Actions がそれをトリガーに起動する
• Claude(LLM)が
• リポジトリ内のコードや設定
• セキュリティツールの結果
を参照して回答を生成する。
結果はそのまま GitHub にコメントとして投稿されます。

例えば以下のような感じで動きます。
回答が長すぎるので一部抜粋。

監査テスト__SEC-02-05-02-01….png

https___qiita-image-stor….png

4. GitHub Issue から AI を呼び出す仕組み

呼び出し部分は、GitHub Actions の設定ファイルに記載しています。
以下は、今回の仕組みで重要になる部分の抜粋です。

.github/workflows/claude-reply-on-mention.yml
name: Claude Reply on Mention

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

permissions:
  contents: read
  issues: write
  pull-requests: write

jobs:
  reply:
    runs-on: ubuntu-latest
    if: contains(github.event.comment.body, '@claude')

  • Issueコメント / PRレビューコメントの作成をトリガーにします
  • コメント本文に @claude が含まれる場合のみ実行します
  • issues: write などを付与し、結果をコメント投稿できるようにしています

5. プロンプト設計

  1. 監査支援プロンプト設計

GitHub Actions の設定では、Claude に渡すプロンプトを次のように組み立てています。

.github/workflows/claude-reply-on-mention.yml
direct_prompt: |
      SYSTEM CONTEXT: {{file:tools/claude_system_context.txt}}
      AUDIT CONTEXT: {{file:tools/claude_audit_context.txt}}
      THREAD: ${{ github.event.issue.html_url || github.event.pull_request.html_url }}
      USER PROMPT: {{file:prompt.txt}}
    allowed_tools: bash,read,grep,glob,mcp__prismacloud__*,mcp__blackduck__*,mcp__insightappsec__*
    timeout: 900

システムコンテキスト:技術回答の前提を固定する

tools/claude_system_context.txt
あなたはこのGitHubリポジトリの文脈で回答するシニアソフトウェアエンジニアです。

要求:
- 回答前に必要な範囲でリポジトリのソースコードを読み、正確に説明してください。
- 適宜、ファイルパス・シンボル名・行範囲を引用して根拠を示してください。
- 前提や仮定は明示し、不足情報やリスクがあれば指摘してください。
- 簡潔だが技術的に十分な内容にしてください。変更提案が必要な場合は差分または具体的手順を示してください。
- 機密情報(トークン/鍵/認証情報等)は絶対に出力しないでください。
- 出力は日本語で行ってください。

監査コンテキスト:判断をさせず、情報整理に閉じ込める

Claude の役割と制約は、tools/claude_audit_context.txt で明示的に定義しています。
特に重要なのは、次の部分です。(長いので一部抜粋)

あなたの役割は情報収集と整理です。
準拠・非準拠の最終判断は人間の監査人が行います。

❌ 準拠・非準拠の判定
❌ 「問題ない」「十分」といった評価的な表現
❌ 監査人の判断を代替する結論

このプロンプトによって、Claude は
結論を出す存在ではなく、判断に必要な事実を揃える存在として振る舞います。

「何が実装されているか」「どこにあるか」「何が未確認か」までを AI に任せ、
判断そのものは常に人間が行う、という役割分担をプロンプトで担保しています。

6. MCP経由でセキュリティツールから情報を取得する

Claude からセキュリティツールの API を直接呼ばせず、MCP サーバ経由に限定しています。
身近なチームが使用しているツールのMCPサーバを設定しています。

{
  "mcpServers": {
    "prismacloud": {
      "command": "python",
      "args": ["server.py"],
      "cwd": "packages/mcp-server/prismacloud"
    },
    "blackduck": {
      "command": "python",
      "args": ["server.py"],
      "cwd": "packages/mcp-server/blackduck"
    },
    "insightappsec": {
      "command": "python",
      "args": ["server.py"],
      "cwd": "packages/mcp-server/insightappsec"
    }
  }
}

MCP を「使える状態」にするだけでなく、
プロンプト側で「使うべき場面」を明示している点も重要です。

tools/claude_audit_context.txt には、次のような指示を含めています。

## MCPツールの活用

セキュリティ監査では、以下のMCPツールを使用してセキュリティ情報を取得できます:

**Prisma Cloud - クラウドセキュリティ:**
- `mcp__prismacloud__get_critical_alerts`: Criticalアラート取得
- `mcp__prismacloud__get_alerts_by_severity`: 重要度別アラート取得
- `mcp__prismacloud__get_compliance_summary`: コンプライアンス概要取得
- `mcp__prismacloud__get_policy_violations`: ポリシー違反取得
- `mcp__prismacloud__get_cloud_resources`: クラウドリソース一覧取得
- `mcp__prismacloud__get_security_summary`: セキュリティ総合サマリー

**BlackDuck - オープンソースセキュリティ:**
- `mcp__blackduck__get_project_vulnerabilities`: プロジェクトの脆弱性データ取得
- `mcp__blackduck__get_project_licenses`: プロジェクトのライセンス情報取得
- `mcp__blackduck__get_projects_summary`: プロジェクト一覧と概要取得
- `mcp__blackduck__get_security_summary`: セキュリティ総合サマリー
- `mcp__blackduck__get_vulnerability_details`: 全プロジェクトの脆弱性詳細情報取得
- `mcp__blackduck__get_project_uuid`: プロジェクト名からUUID取得
- `mcp__blackduck__get_detailed_data`: 指定エンドポイントの詳細データ取得

**InsightAppSec - Webアプリケーションセキュリティ (DAST):**
- `mcp__insightappsec__get_critical_vulnerabilities`: Critical/High脆弱性取得
- `mcp__insightappsec__get_vulnerabilities_by_severity`: 重要度別脆弱性取得
- `mcp__insightappsec__get_apps_summary`: アプリケーション概要取得
- `mcp__insightappsec__get_scan_status`: スキャン状況取得
- `mcp__insightappsec__get_app_details`: アプリケーション詳細取得
- `mcp__insightappsec__get_security_summary`: セキュリティ総合サマリー

**使用例:**
- クラウドセキュリティ、コンプライアンス、ポリシー違反: Prisma Cloudツールを使用
- オープンソースライセンス、依存関係の脆弱性(CVE): BlackDuckツールを使用
- Webアプリケーションセキュリティ、DAST脆弱性: InsightAppSecツールを使用
- これらのツールで取得したスキャン結果をコードベースの実装と照らし合わせることができます

## 情報収集の手順

### 1. 監査項目の特定と理解
- 質問から該当する監査項目IDを特定
- 監査項目カタログから要件内容を読み込み
- 確認すべきポイントを把握

### 2. 関連情報の網羅的収集

以下の情報源から関連する実装を検索・収集してください:

**アプリケーションコード:**
- ソースコード(Python, JavaScript, Java等)
- 設定ファイル
- テストコード
- ドキュメント

**IaCコード:**
- Terraform設定(`.tf`ファイル)
- CloudFormation
- Kubernetes manifest
- Ansible playbook

**セキュリティスキャン結果(MCPツール経由):**
- Prisma Cloud: アラート・ポリシー違反・コンプライアンス状況・クラウドリソース設定
- BlackDuck: オープンソース脆弱性(CVE)・ライセンス情報・依存関係分析
- InsightAppSec: Webアプリケーション脆弱性(DAST)・スキャン状況・アプリ詳細

**その他:**
- README.md、docs/ディレクトリ
- CI/CDパイプライン設定
- 環境変数定義
- セキュリティポリシー文書

こんな感じでプロンプトを書いておけば、ユーザーが「脆弱性ツールを見てください」と明示的に書かなくても、
Claudeが自律的にMCP経由で必要なセキュリティ情報を取得するようになります。

例ですが、こんな感じのものが出せます。
【テスト】Claude自動返信機能の動作確認_·….png

7. 使ってみてわかったこと・難しかった点

使っていて良さそうだと感じた点は、
不足している観点だけでなく、解決策の例を示してくれたことです。
どれだけやればいいかわからないチームにとってはとても助かるのではないかと考えます。

image.png

image.png

難しい点としては、
Claudeくん(に限らず他のモデルもそうなのかもですが)は放っておくと、どうしても「問題ない」「要件を満たしている」といった結論を出そうとします。
しかし最終判断は人手に任せたい。一方で、(セキュリティ観点で必要な実装が)できていないものは、「できていない(見つからない/未確認)」と事実として明確に言ってほしいので、この塩梅が難しいと感じます。

そのため、
• 役割を明示する(判断はしない/情報を整理する)
• 評価的な表現を具体例で禁止する(「問題ない」「十分」など)
• 「見つかった/見つからなかった/未確認」を必ず明記させる
• 出力フォーマットをある程度固定する(要点→根拠→未確認事項の順)

といった制約を、プロンプト側でかなり強めにかける必要がありました。

また、使っていく中で感じたもう一つの課題は、回答がどんどん長くなってしまうことです。

少し質問しただけでも、背景説明やら周辺知識の補足やらを長々と解説し始めて、目的の答えを見つけるのが大変になりました。
そのためまずは 要点のサマリを述べ、その根拠となる 最小限のエビデンス(ファイルパスや設定)だけを提示し、気になった点は追加質問で深掘りできるような出力に寄せたほうが良いと考えています。

このへんはまだまだ調整が必要です。

8. 今後やりたいこと

  • 導入手順を極力簡単にして、開発チームにバンバン使っていってもらえるようにします
  • なんか最近Skillsが盛り上がって来たので、Skillsで良くね?って感じてきています。試したい
  • 社内規定を読み込ませて会社の規定、ガイドラインに沿った実装をしているかという観点でも見てくれるようにしたいと考えています

9. おわりに

このプロトタイプでやりたかったのは、監査判断をAIに置き換えることではなく、人が判断するための材料を素早く揃えることでした。(ホントは全部AIでできたらいいんですけどねーー!)
GitHub上のやり取りにAIを差し込むことで、エビデンス収集の手間と質疑応答の待ち時間を減らせる手応えがあります。
まだまだ改善の余地は多いですが、まずはチームで使い倒しながら育てていきます。

20
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?