はじめに

プログラム開発において、セキュリティ対策は煩雑になりがちで、優先順位が低くなる傾向があると言えるでしょう。

対策をやらなければいけないと思いつつも、機能要求への対応が優先され、どうしても後手後手になる作業かなと思います。

この記事では、Trivy / GitHub Actions / Devin を利用して、セキュリティ対策を自動化できないか考えてみます。

今回の検証では、継続的検出と継続的修正を検証します。
このブログでは、継続的検出は開発者のコードが自動的に脆弱性検出されること、継続的修正は開発者のコード内の脆弱性が自動的に修正されることを指します。

主要機能の説明

上の説明で出てきた機能について、説明します。

Trivy

Trivy は、OSS で管理されている脆弱性の検出ツールです。
ファイルシステム、Dockerイメージ、Gitリポジトリをスキャン対象として検出できます。

脆弱性 (Vulnerability) のほか、誤設定 (Misconfiguration)、シークレット (Secret)、ライセンス (License) をスキャンすることが可能です。

Trivy は、GitHub Actions とも連携 しており、Actions として容易に自動化することができます。

今回の検証では、脆弱性のスキャンエンジンとして利用します。

Trivy は OSS で提供されており誰でも簡単に利用できるため、今回のスキャナに利用しました。
企業において、商用プロダクトが利用できる場合には、それらのスキャナを利用することもできると考えます。

GitHub Actions

GitHub Actions は、GitHub 上でワークフローを構築し、処理の自動化を実現する機能です。
CI/CD のほか、コードのテスト、コードレビューなどのアクションを実現できます。

今回の検証では、GitHub の PR を契機として、PR にコメントを追加するアクションを実装します。

これにより、ユーザーが PR を作成した際に継続的にスキャンを実施することができるようになります。

Devin

Devin は、自律型の AI エンジニアです。
課題を渡すことで、GitHub の課題に対して自律的に対応できます。

今回の検証では、脆弱性への対応を Devin に実施させようと思います。

Devin により、簡単なプロンプトにより自律的に修正を実施することが期待できます。

実装

それぞれ、順に実施したいと思います。

Pull Request に対する自動コメント

Pull Request (PR) は GitHub 上の操作で、簡単に言えばプログラムのリリースに近い作業です。
(詳細な説明は、GitHub の説明を読んでください)

PR に対してアクションを実装することで、プログラムのリリースに対して確実に脆弱性スキャンを実施するよう、実装できます。

まずは、この自動スキャンを目的として実装します。

Trivy template

Trivy には出力フォーマットの指定機能がありますが、標準では Markdown 形式に対応していません。

Reporting には、Table、Json、Sarif、SBOM 等の主要なテンプレートには対応していますが、Markdown には対応していないため、簡単に Template ファイルを作成しました。

このテンプレートは、検証のために簡易に作成したものです。
しかし、これによって Markdown 形式で出力が可能となりました。

[.github/markdown.tpl]

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# - Trivy Report -
{{ now }}
 
## Report Summary
 
| Target | Type | Vulnerabilities | Misconfigurations | Secrets |
| :--- | :--- | :--- | :--- | :--- |
{{- range . }}
| {{ .Target }} | {{ .Type }} | {{ len .Vulnerabilities }} | {{ len .Misconfigurations }} | {{ len .Secrets }} |
{{- end }}
 
{{- range $i, $v :=  . }}   
## Target: {{- escapeXML .Target }}
 
| Metadata | Value |
| :--- | :--- |
| Class | {{ .Class }} |
| Type | {{ .Type }} |
 
### Vulnerabilities
    {{- if (eq (len .Vulnerabilities) 0) }}
**No Vulnerabilities found**
    {{- else }}
| Library | Vulnerability | Severity | Status | Installed Version | Fixed Version | Title |
| :-- | :-- | :-- | :-- | :-- | :-- | :-- |
        {{- range .Vulnerabilities }}
| {{ escapeXML .PkgName }} | {{ escapeXML .VulnerabilityID }} | {{ escapeXML .Severity }} | {{ .Status }} | {{ escapeXML .InstalledVersion }} | {{ escapeXML .FixedVersion }} | {{ escapeXML .Title}} <br/> {{- range .Vulnerability.References }} [{{ escapeXML . }}]({{ escapeXML . }})<br/> {{- end }} |
        {{- end }}
    {{- end }}
 
### Misconfigurations
    {{- if (eq (len .Misconfigurations ) 0) }}
**No Misconfigurations found**
    {{- else }}
| Type | Misconf ID | Check | Severity | Message |
| :-- | :-- | :-- | :-- | :-- |
        {{- range .Misconfigurations }}
| {{ escapeXML .Type }} | {{ escapeXML .ID }} | {{ escapeXML .Title }} | {{ escapeXML .Severity }} | {{ escapeXML .Message }} <br/> [{{ escapeXML .PrimaryURL }}]({{ escapeXML .PrimaryURL }}) |
        {{- end }}
    {{- end }}
 
### Secrets
    {{- if (eq (len .Secrets ) 0) }}
**No Secrets found**
    {{- else }}
| Category | Severity | Title | Severity | Message |
| :-- | :-- | :-- | :-- | :-- |
        {{- range .Secrets }}
| {{ .Category }} | {{ escapeXML .Severity }} | {{ escapeXML .Title }} | {{ escapeXML .Severity }} | {{ escapeXML $v.Target }}:{{ .StartLine }}-{{ .EndLine }}  |
        {{- end }}
    {{- end }}
 
{{- end }}

GitHub Actions

次に、GitHub Actions を実装しました。

この定義ファイルでは、Trivy によるスキャンを実施して、その結果を PR コメントとして PR に追記します。

この実装により、PR を上げた際にスキャンが実施され、その結果を確認することができるようになります。

[.github/workflows/main.yml]

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: build
on:
  # Pull Request により起動する
  pull_request:
jobs:
  build:
    name: Build
    runs-on: ubuntu-24.04
    steps:
    - # チェックアウトする
      name: Checkout code
      uses: actions/checkout@v4
    - # Trivy によりスキャンする
      name: Run Trivy vulnerability scanner in fs mode
      uses: aquasecurity/trivy-action@0.28.0
      with:
        scan-type: 'fs'
        scan-ref: '.'
        output: trivy-report.md
        format: template
        template: "@.github/markdown.tpl"
        trivy-config: trivy.yaml
    - # PR コメントを追加する。
      name: Create PR comment
      run:
        gh pr comment ${{ github.event.number }} --body-file trivy-report.md
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

結果

ここまでの実装結果を掲載します。

目的通り、PR を上げた際に自動的にスキャンを実施して、その結果をコメントとして記載することができました。

PR に対する修正の自動化

続いて、PR を Devin に読ませて、自動的に修正させたいと思います。

Devin の実行

Devin は生成 AI であるため、文字列として命令を与えます。

今回は、以下のプロンプトを指定しました。
このプロンプトをチャット欄に入力することにより、自律的に対応されるようになります。

1
2
3
4
5
GitHub Actions により、PR に脆弱性が検知されました。
この PR Comment を確認し、修正のための PR を上げてください。
 
 
{URL}

Devin による自律的な修正

上記のプロンプトにより、Devin が自動的に調査を行い PR をしてくれます。

Devin の動作は、初めて見る人にとって驚くべきものだとおもいます。
私も、初めて Devin の動作を見たときの感動を、今でも覚えています。

簡単なプロンプトから、内容をプログラムの修正だけでなく動作検証、修正の確認、Commit / Push / CI チェックの一通りの編集作業を自律的に実現してくれます。

これにより、GitHub に新しい PR が作成されており、PR コメントも適切に作成してくれます。

内容的にも問題なく、また上述の Trivy によるスキャン結果への対応も実施されており、脆弱性が修正されていることが確認できます。

結果

ここまでの動作により、Trivy / GitHub / Devin を活用して自律的な脆弱性管理が可能となりました。

開発者は、一切手を加えることなく、脆弱性をスキャンして、課題化し、自律的な修正が実現されています。

あくまでも概念実装ですが、脆弱性管理の自動化を実現できました。

まとめ

脆弱性管理を実現する際、常にチェックを実施することが望ましいです。
しかし、どうしても定期的 ( 月次等 ) な実施となっている環境も多いです。

継続的にチェックするためには、GitHub など開発者のツールと連携することが近道だと考えています。

GitHub と連携することで、GitHub Actions を活用して継続的検出を実現することはできますが、修正稼働は変わりません。
そこに対して、Devin などの自律型 AI を組み込むことで、継続的修正も可能となりました。

プログラム開発において、継続的検出と継続的修正で安全性を向上させることができます。