コンテンツにスキップ

Trivyの基礎とスキャン結果の読み方

公開日:2026年9月10日

はじめに

コンテナイメージの脆弱性を確認するツールとして、Trivyがあります。スキャン結果を利用するには、検出件数や深刻度に加えて、何を検査した結果なのか、各項目が何を表しているのかを確認する必要があります。

この記事では、Trivyの基本、スキャン対象、JSON出力を使った結果の読み方、脆弱性管理で利用する際の注意点について記載します。

Trivyとは

Trivyは、Aqua Securityが開発するオープンソースのセキュリティスキャナーです。既知の脆弱性だけでなく、設定ミスや、ファイルに含まれる認証情報などの検出にも対応しています。

機能 調べる内容
脆弱性スキャン OSパッケージや依存ライブラリに関する既知の脆弱性
設定ミスの検査 Dockerfile、Kubernetes、Terraformなどの設定上の問題
シークレット検出 APIキーなどの機密情報らしき記述
ライセンス確認 パッケージのライセンス情報
SBOM生成 検出したソフトウェア構成の一覧

すべての機能が、すべての対象に対して常に有効になるわけではありません。対象とスキャナーの組み合わせ、オプションによって検査範囲が変わります。1

脆弱性検出の基本は、対象に含まれるソフトウェアとバージョンを特定し、対応する脆弱性情報と照合することです。アプリケーションに攻撃を送って、実際に悪用できるかを試験する仕組みではありません。

そのため、「脆弱性が検出された」と「この環境で攻撃が成立する」は区別して考える必要があります。

Trivyのスキャン対象

代表的なスキャン対象とコマンドは次のとおりです。

対象 コマンド例 主に確認するもの
コンテナイメージ trivy image nginx:1.20 イメージ内のOSパッケージ、ライブラリ、ファイルなど
ローカルディレクトリ trivy fs ./my-project 指定範囲内の依存関係ファイルや設定ファイルなど
Gitリポジトリ trivy repo https://github.com/owner/repo リポジトリ内の依存関係ファイルや設定ファイルなど

最後のURLは説明用です。実行時には調べたいリポジトリのURLに置き換えます。

trivy fsは単一のファイルも指定できます。例えば、対応するロックファイルを直接指定して依存パッケージの脆弱性を調べられます。2

trivy repoはソースリポジトリ向けの検査です。公式説明では、ロックファイルなどを対象とし、JARやバイナリなどのビルド成果物は対象にしないとされています。3

ファイルとイメージで結果が異なる理由

例えば、Node.jsアプリのリポジトリに、package-lock.jsonとDockerfileがある場合を考えます。

  • リポジトリ側では、ロックファイルなどに記録された依存パッケージを調べる。
  • イメージ側では、ビルド後のイメージに実際に含まれるOSパッケージやライブラリを調べる。
  • DockerfileのFROMにベースイメージ名が書いてあっても、リポジトリのスキャンだけで、そのベースイメージ内部まで自動的に検査するわけではない。

つまり、「開発用のファイル」と「配布・実行する成果物」では、読み取れる情報が違います。どちらの検出件数が多いかは一概には決まりません。

開発用依存関係についても、ロックファイルに存在するだけで必ず検出対象になるとは限りません。言語ごとの対応や、開発用依存関係を含める設定を確認する必要があります。

共通の出力形式

fs、repo、imageは、表形式やJSON形式などの共通した出力形式を利用できます。

trivy fs --format json ./my-project
trivy image --format json nginx:1.20

JSONの基本構造や脆弱性の主要項目は共通ですが、イメージIDやレイヤー情報など、対象固有の情報もあります。すべての項目が常に存在するわけではありません。4

Trivyのインストール

Trivyのインストール方法は、公式のインストール手順を参照してください。導入後、次のコマンドでバージョンを確認できます。

trivy --version

イメージのスキャンとJSON出力

イメージをスキャンする基本コマンドは次のとおりです。

trivy image nginx:1.20

初回など、必要な場合は脆弱性データベースが自動取得されます。本体のインストールと脆弱性情報の更新は別であり、同じTrivyでも、使用するデータベースによって結果が変わることがあります。5

結果をJSONに保存するには、出力形式とファイル名を指定します。

trivy image --format json --output trivy_nginx.json nginx:1.20

パッケージ一覧も含める意図を明示する場合は、次のように指定できます。

trivy image --format json --list-all-pkgs \
  --output trivy_nginx.json nginx:1.20

同名の出力ファイルがある場合は上書きされるため、過去の結果を残すならファイル名を変えます。4

スキャン結果の読み方

ここでは、2026年9月9日にTrivy 0.71.2で取得したnginx:1.20のスキャン結果を例に、集計値とJSON出力の抜粋を使って説明します。

導入されるTrivyのバージョンや、再実行時の検出結果は、実例と異なる場合があります。

検査対象と件数

項目 記録内容
Trivy 0.71.2
レポート作成日時 2026年9月9日10:45、日本時間
対象 nginx:1.20
検出されたOS Debian 11.3
nginxパッケージのバージョン 1.20.2
パッケージ一覧の件数 142
脆弱性の検出レコード数 866
重複を除いた脆弱性ID数 548

深刻度別の検出レコード数は次のとおりです。

深刻度 検出レコード数
CRITICAL 32
HIGH 217
MEDIUM 348
LOW 238
UNKNOWN 31

866件は「異なるCVEが866個ある」という意味ではありません。同じCVEが複数のパッケージに対応すると、複数の検出レコードになります。また、これらはnginx本体だけの件数ではなく、イメージに含まれるパッケージの検出結果です。

これらの数値は上記の日時に取得したスキャン結果の集計値です。同じコマンドで再実行しても、同じ結果になるとは限りません。

JSON全体の構造

主要な項目に絞ると、JSON出力は次のような構造になります。

{
  "Trivy": {
    "Version": "0.71.2"
  },
  "ArtifactName": "nginx:1.20",
  "ArtifactType": "container_image",
  "Metadata": {
    "OS": {
      "Family": "debian",
      "Name": "11.3"
    }
  },
  "Results": [
    {
      "Target": "nginx:1.20 (debian 11.3)",
      "Class": "os-pkgs",
      "Type": "debian",
      "Packages": [],
      "Vulnerabilities": []
    }
  ]
}

これは全体の構造を示すための例であり、一部の項目を省略しています。PackagesとVulnerabilitiesも説明のため空配列にしていますが、実際のスキャン結果では、検出したパッケージや脆弱性のレコードが入ります。

Metadataにはスキャン対象の情報が入り、Resultsには対象ごとの検査結果が配列として格納されます。上の例ではResultsの要素を1つだけ示しています。その要素の中に、パッケージ一覧のPackagesと脆弱性一覧のVulnerabilitiesがあります。

JSON出力は、主に次の3つに分けて確認できます。

まとまり 内容
レポート情報 使用したTrivy、作成日時、対象名、識別ID
Metadata OS、イメージ、レイヤー、ビルド履歴、起動設定
Results 検出したパッケージと脆弱性

脆弱性を確認したい場合は、まずResults内のVulnerabilitiesを読み、必要に応じてPackagesやMetadataを参照します。

脆弱性レコードの主要項目

脆弱性の検出レコードは、Results配列の各要素にあるVulnerabilities配列(Results[].Vulnerabilities[])に格納されます。このスキャン結果から、PkgNameがaptのレコードの主要項目を抜粋すると、次のようになります。

{
  "VulnerabilityID": "CVE-2011-3374",
  "PkgName": "apt",
  "InstalledVersion": "2.2.4",
  "Status": "affected",
  "Severity": "LOW",
  "SeveritySource": "debian"
}
項目 読み方
VulnerabilityID どの脆弱性か
PkgName どのパッケージに該当するか
InstalledVersion イメージに入っているバージョン
FixedVersion 修正が提供されているバージョン。情報がない場合は省略される
Status 脆弱性情報源が示す対応状況
Severity Trivyが採用した深刻度
SeveritySource その深刻度を採用した情報源

この例では、「apt 2.2.4がCVE-2011-3374に該当し、深刻度にはDebian由来のLOWが使われている」と読めます。ここから、稼働中のアプリがその脆弱性のある処理を呼び出しているかまでは分かりません。

Statusと修正バージョンの関係

同じスキャン結果のResults[].Vulnerabilities[]には、PkgNameがbsdutilsのレコードも含まれています。その主要項目を抜粋すると、次のようになります。

{
  "VulnerabilityID": "CVE-2024-28085",
  "PkgName": "bsdutils",
  "InstalledVersion": "1:2.36.1-8+deb11u1",
  "FixedVersion": "2.36.1-8+deb11u2",
  "Status": "fixed"
}

Status: fixedは、このイメージが修正済みという意味ではなく、修正版が提供されていることを表します。この例では、インストール済みはdeb11u1で、修正版としてdeb11u2が示されています。

このJSONに含まれるステータスと検出レコード数は、次のとおりです。

Status 意味 検出レコード数
fixed 修正版が提供されている 437
affected 影響ありとして登録されている 305
fix_deferred 修正が先送りされている 90
will_not_fix 修正しない方針となっている 34

FixedVersionがないことも、安全や影響なしを意味しません。修正版が未提供の場合や、情報が登録されていない場合があります。6

深刻度の選択とCVSSの関係

Severityは、Trivyが外部の脆弱性情報から採用した深刻度です。Trivyが独自に算出したCVSSスコアではありません。

Trivyは外部の評価を選び、必要に応じて深刻度に分類します。既定の選択では、対象のベンダーの深刻度を優先し、それがなければ提供されたCVSSスコアから分類し、さらに情報がなければNVDなどを参照します。

そのため、同じCVEについてNVDとDebianの評価が異なる場合、NVDで見た深刻度とTrivyのSeverityが一致しないことがあります。ビルド方法や標準設定など、配布形態の違いをベンダーが考慮できるためです。7

先ほどのaptのレコードには、次の評価情報が含まれています。

{
  "Severity": "LOW",
  "SeveritySource": "debian",
  "VendorSeverity": {
    "debian": 1,
    "nvd": 1
  },
  "CVSS": {
    "nvd": {
      "V2Score": 4.3,
      "V3Score": 3.7
    }
  }
}

この抜粋では、CVSSにNVDのスコアがある一方、SeveritySourceはdebianです。つまり、CVSS.nvdが出ているからといって、表示上の深刻度もNVDのスコアだけで決まったとは限りません。

VendorSeverityの数値は、0がUNKNOWN、1がLOW、2がMEDIUM、3がHIGH、4がCRITICALを表す列挙値です。CVSSの点数ではありません。

また、CVSSには情報源ごとに異なるバージョンの評価が入ることがあります。V3Vectorの先頭がCVSS:3.1ならv3.1の評価であり、すべてのCVEにv4.0のスコアがあるわけではありません。

KEV・EPSSとの組み合わせ

このスキャン結果のJSONにはCVSSの評価情報が含まれていますが、KEVへの掲載情報やEPSSスコアの専用項目はありません。

情報 分かること この結果への補い方
CVSS 技術的な深刻さ JSON内のCVSSを参照
KEV CISAが実際の悪用を確認し、カタログに掲載しているか CVE IDをKEVカタログと照合
EPSS 今後30日以内に実環境で悪用される確率の推定 CVE IDを使ってスコアを取得

KEVは、CISAがJSONやCSVで公開しています。未掲載であることは、悪用されていない証明ではありません。8

EPSSはFIRSTがAPIやCSVなどで提供しています。少数のCVEの照会にはAPI、大量のスコア取得には日次CSVなどを使い分けます。EPSSは、特定の自分のサーバーが侵害される確率そのものではありません。910

Trivyの検出結果にこれらを組み合わせる場合は、VulnerabilityIDを共通のキーとして補足情報を付ける形になります。

スキャン結果を利用する際の注意点

脆弱性の報告がなくても、安全とは限らない

今回のスキャンでは、イメージ内にnginxがあることは確認できましたが、nginxの脆弱性は報告されませんでした。

イメージのスキャンが完了しても、中にあるすべてのパッケージが脆弱性の検査対象になるとは限りません。nginxが検査対象から外れていた場合、nginxに脆弱性があっても検出されません。

例えば、Debian上のパッケージを調べるとき、TrivyはDebianが公開する脆弱性情報を使います。しかし、その情報が対象とするのはDebianが配布するパッケージです。nginxの開発元など、別の配布元から入れたパッケージは、検査の対象外になることがあります。11

今回のnginxも、Debian以外の配布元のパッケージとして記録されていました。この結果だけでは検査されたかどうかを確認できないため、「脆弱性の報告がないので安全」とは判断できません。

OSのサポート終了情報を確認する

このスキャン結果のMetadata.OSには、次の値が記録されています。

{
  "Family": "debian",
  "Name": "11.3",
  "EOSL": true
}

これは、そのスキャン時点でTrivyがOSをサポート終了と判定した記録です。現在のサポート契約や、すべての延長サポート制度まで判定した結果とは限らないため、運用判断ではOS提供元の情報も確認します。

同じイメージでも結果は変わる

イメージを変更していなくても、新しい脆弱性の公開や既存情報の訂正によって検出結果は変わります。継続利用するイメージを、ビルド時だけでなく後日再スキャンする意味はここにあります。

比較のためには、イメージのダイジェスト、Trivyのバージョン、実行日時、オプション、使用した脆弱性データベースの情報を記録しておくと、差分の原因を調べやすくなります。

フィルターで除外された脆弱性も存在する

例えば、--ignore-unfixedは修正版がない脆弱性などを結果から除外します。修正可能なものに絞る用途はありますが、全体像の確認とは区別が必要です。

深刻度フィルターや除外設定も同様です。検出件数を比較するときには、検査条件がそろっているかを先に確認します。6

JSON出力の項目一覧

ここでは、本文で扱った項目以外も含め、このスキャン結果のJSON出力に含まれる項目を整理します。Trivyの全スキャン対象に共通する完全なスキーマ一覧ではありません。

まず、各項目の位置関係を示します。MetadataとResultsは、どちらもJSONの最上位の項目です。PackagesとVulnerabilitiesは、Results配列の各要素に属する項目です。

以下は説明用のコメントを付けたJSONC形式の例です。一部の項目を省略し、ハッシュ値は"..."で置き換えています。実際のTrivyのJSON出力にはコメントは含まれません。

{
  "SchemaVersion": 2, // レポート全体のJSON構造のバージョン
  "Trivy": {
    "Version": "0.71.2" // 使用したTrivyのバージョン
  },
  "ArtifactName": "nginx:1.20", // スキャン対象の名前
  "Metadata": { // スキャン対象のイメージ情報
    "OS": {
      "Family": "debian", // イメージ内のOSの種類
      "Name": "11.3" // OSのバージョン
    },
    "Layers": [ // イメージのレイヤー一覧
      {
        "Digest": "..." // このレイヤーのハッシュ
      }
    ],
    "ImageConfig": {
      "architecture": "amd64" // イメージのCPUアーキテクチャ
    }
  },
  "Results": [ // 対象ごとの検査結果
    {
      "Class": "os-pkgs", // この要素はOSパッケージの検査結果
      "Packages": [ // イメージ内で見つかったパッケージの一覧
        {
          "Name": "apt", // パッケージ名
          "Version": "2.2.4" // パッケージのバージョン
        }
      ],
      "Vulnerabilities": [ // 検出した脆弱性の一覧
        {
          "VulnerabilityID": "CVE-2011-3374", // 脆弱性のID
          "PkgName": "apt", // この脆弱性に該当するパッケージ名
          "InstalledVersion": "2.2.4" // そのパッケージのバージョン
        }
      ]
    }
  ]
}

以下の表では、見出しごとに格納位置を示します。.は項目の階層を区切り、[]は配列の各要素を表します。

レポート情報(JSONの最上位)

以下はJSONの最上位の項目です。ただし、Trivy.Versionは、最上位のTrivyに属するVersion項目です。

項目 意味
SchemaVersion JSON構造のバージョン。今回の値は2
Trivy.Version 使用したTrivyのバージョン
ReportID レポートの識別ID
CreatedAt レポート作成日時
ArtifactID Trivyがスキャン対象を識別するID
ArtifactName 対象名
ArtifactType 対象の種類。今回はcontainer_image

Metadata(対象イメージの情報)

以下は、JSONの最上位にあるMetadataに属する項目です。

項目(Metadata内) 意味
Size イメージのレイヤーサイズ合計、バイト単位
OS.Family ディストリビューションの種類
OS.Name 検出したOSバージョン
OS.EOSL Trivyによるサポート終了判定
ImageID イメージの識別ID
Reference 対象イメージの参照文字列
RepoTags タグの一覧
RepoDigests リポジトリ名とダイジェストを組み合わせた参照一覧
DiffIDs 非圧縮レイヤーのハッシュ一覧
Layers レイヤーごとの情報
Layers[].Size 各レイヤーのサイズ、バイト単位
Layers[].Digest 配布されるレイヤーデータのハッシュ
Layers[].DiffID 非圧縮レイヤーデータのハッシュ
ImageConfig イメージの構成情報。内部の項目は次の表で説明

IDやハッシュは用途が異なるため、名前が似ているからといって同じものとして扱わないようにします。1213

ImageConfig(Metadata内の構成情報)

以下は、Metadata.ImageConfigに属する項目です。イメージに記録されている構成情報を表します。

項目(Metadata.ImageConfig内) 意味
architecture CPUアーキテクチャ。今回はamd64
os OSの種類。今回はlinux
created イメージ作成日時
history ビルド履歴
history[].created 各工程の作成日時
history[].created_by 各工程を生成したコマンドなど
history[].empty_layer trueならファイルシステム変更のレイヤーを追加しない工程
rootfs.type ファイルシステムの構成方式。今回はlayers
rootfs.diff_ids 構成レイヤーの非圧縮ハッシュ一覧
config.Entrypoint 起動時に実行するプログラム
config.Cmd デフォルトのコマンド・引数
config.Env 環境変数
config.Labels 管理者情報などの付加情報
config.Labels.maintainer 管理者を表すラベル
config.ExposedPorts 使用を想定するポート。今回は80/tcp
config.StopSignal 停止時に送るシグナル。今回はSIGQUIT

ExposedPortsがあるだけで、ホストへのポート公開が行われるわけではありません。また、Envや起動コマンドは実行時に上書きできるため、この情報は稼働中コンテナの実測結果ではありません。14

Results(対象ごとの検査結果)

以下は、JSONの最上位にあるResults配列の各要素に属する項目です。

項目(Results[]内) 意味
Target この結果の対象名
Class 検査結果の分類。今回はOSパッケージを表すos-pkgs
Type 解析対象の種類。今回はdebian
Packages 検出したパッケージの一覧
Vulnerabilities 脆弱性の検出レコード一覧

Packages(Results内のパッケージ一覧)

以下は、Results[].Packages[]の各要素に属する項目です。

項目(Results[].Packages[]内) 意味
ID パッケージID。例:adduser@3.118
Name パッケージ名
Identifier.PURL 種類・名前・バージョンなどを表す標準形式のPackage URL
Identifier.UID パッケージを区別するための識別子
Version パッケージのバージョン
Release 配布パッケージの改訂番号
Epoch バージョン比較の順序を調整する数値
Arch 対応アーキテクチャ。allはアーキテクチャ非依存
SrcName 元となるソースパッケージ名
SrcVersion/SrcRelease/SrcEpoch ソースパッケージ側のバージョン情報
Licenses ライセンス一覧
Maintainer パッケージ管理者
Repository.Class 配布元の分類。officialはOS公式、third-partyはOS提供元以外の配布元を表す
DependsOn 依存するパッケージのID一覧
Layer.Digest/Layer.DiffID パッケージに対応するレイヤーのハッシュ
InstalledFiles パッケージに属するインストールファイルのパス一覧
AnalyzedBy 解析に使ったアナライザー。今回はdpkg

ライセンス情報やファイル一覧が含まれていても、それ自体が問題の検出を意味するわけではありません。15

Vulnerabilities(Results内の脆弱性一覧)

以下は、Results[].Vulnerabilities[]の各要素に属する項目です。

項目(Results[].Vulnerabilities[]内) 意味
VulnerabilityID CVEなどの脆弱性識別子
PkgID/PkgName 対象パッケージのID/名前
PkgIdentifier.PURL/PkgIdentifier.UID 対象パッケージの識別情報
InstalledVersion インストール済みバージョン
FixedVersion 修正が提供されたバージョン
Status 情報源が示す脆弱性の対応状況
Layer.Digest/Layer.DiffID 対象パッケージのレイヤー情報
Severity 採用された深刻度
SeveritySource 深刻度の採用元
VendorSeverity 情報源ごとの深刻度を表す列挙値
CVSS 情報源ごとのCVSS評価
CVSS.*.V2Score CVSS v2のスコア。*はnvdなどの情報源の名前
CVSS.*.V3Score CVSS v3のスコア
CVSS.*.V40Score CVSS v4.0のスコア
CVSS.*.V2Vector CVSS v2の評価条件を表すベクター文字列
CVSS.*.V3Vector CVSS v3の評価条件を表すベクター文字列
CVSS.*.V40Vector CVSS v4.0の評価条件を表すベクター文字列
CweIDs 弱点の種類を分類するCWE ID
Title/Description 見出し/詳細説明
PrimaryURL 代表的な詳細ページ
References 関連資料のURL一覧
DataSource.ID/DataSource.Name/DataSource.URL 検出に使うアドバイザリの情報源のID/名前/URL
VendorIDs ベンダーのアドバイザリIDなど
Fingerprint 対象・パッケージ・脆弱性などの組み合わせの識別用ハッシュ
PublishedDate 脆弱性情報の公開日時
LastModifiedDate 脆弱性情報の最終更新日時

PublishedDateやLastModifiedDateは、このイメージで初めて脆弱性を検出した日時ではありません。DataSourceとSeveritySourceも、それぞれ検出根拠と深刻度の採用元を表す別の項目です。16

まとめ

Trivyは、コンテナイメージやローカルファイル、Gitリポジトリなどを対象に、既知の脆弱性や設定上の問題を検出するセキュリティスキャナーです。

  • スキャン対象やオプションによって、検査できる範囲が異なる
  • JSON出力では、パッケージ一覧、脆弱性レコード、イメージの構成情報を確認できる
  • 検出レコード数は、重複を除いた脆弱性ID数とは異なる
  • Status: fixedは修正版の提供を表し、対象イメージの修正完了を意味しない
  • Severityと併せて、評価元を示すSeveritySourceやCVSSを確認する必要がある
  • パッケージが検出されていても、脆弱性情報と照合できているとは限らない
  • KEVやEPSSをCVE IDで照合することで、対応の優先順位を判断する材料を補える

スキャン結果を読む際は、どのパッケージが含まれているか、脆弱性情報との照合で何が検出されたか、自分の環境で何を優先して対応するかを分けて考える必要があります。

検出件数や深刻度だけでは、利用環境での影響や対応優先度は決まりません。検査範囲と評価の前提を確認したうえで、修正版の有無、実際の悪用状況、パッケージの利用状況などを組み合わせて判断する必要があります。

参考資料

文書の確認日:2026年9月10日。記事中の集計値とJSON出力の抜粋は、2026年9月9日にTrivy 0.71.2で取得したスキャン結果に基づいています。


KestreLynxは、稼働中のDocker・KubernetesコンテナのイメージをTrivyで定期的にスキャンし、前回からの変化と、深刻度・CISA KEV・EPSSに基づく優先度をSlackやWebhookへ通知するOSSです。Docker・Compose向けの修正計画と修正PR(実験的)で、更新候補の比較からGitHubへのPR作成まで修正を支援します(既定で無効)。マージ・再ビルド・デプロイは利用者が行います。

KestreLynxについて · GitHubでソースコードを見る