メインコンテンツへスキップ
APIでは、脆弱性を2つのレベルで扱います。
  • 検出(detection)は、1回のスキャンで報告された脆弱性の1件の発生です。ファイルと行、パッケージとCVE、またはIaCルールなど、そのスキャンが報告した内容そのものを表します。スキャンを実行するたびに、新しいIDを持つ新しい検出が作成されます。Issuesに分類されているエンドポイントが返すのは検出であり、問題(issue)と検出は同じものを指します。
  • ファインディング(finding)は、1つのプロジェクトにおける脆弱性そのものです。その脆弱性を検出したすべてのスキャンにまたがって存在し、スキャン間で変わらない1つのIDを持ちます。ステータス、コメント、担当者、受け入れ済みリスクの有効期限、期限、SLAといったトリアージ情報は、ファインディングに保持されます。
/detectionsは/issuesと同じAPIで、名前だけが新しくなったものです。 Issuesに分類されているすべてのエンドポイントは/detections配下でも提供され、コード、パラメーター、レスポンスはまったく同じです。「issue」という名前はファインディングと混同されやすかったため、/detectionsと呼ぶことにしました。各結果は1回のスキャンにおける脆弱性の検出であり、脆弱性そのものではありません。新しい連携では/detectionsを使用してください。/issuesも引き続きサポートされるため、既存の連携を変更する必要はありません。
3回のスキャンがそれぞれ独自の検出を持ち、トリアージの判断を保持する1つのファインディングを指している図3回のスキャンがそれぞれ独自の検出を持ち、トリアージの判断を保持する1つのファインディングを指している図

2つのレベルを行き来する

各検出の項目には、そのファインディングのfinding_idが含まれます。検出をまとめる際は、必ずこのIDでグループ化してください。first_detection_dateはファインディングの属性であってキーではないため、グループ化には使えません。このフィールドがnullになるのは、ファインディングが導入される前に取り込まれた検出だけです。 各ファインディングにはlatest_detectionが含まれます。これは最新の検出で、検出エンドポイントが受け取るIDと、種別ごとの位置情報(file_pathとline_number、path、packageとversionとcve、またはpath、rule_id、start_lineとend_line)を持ちます。 どちらのレベルで行ったトリアージの変更も、ファインディングに反映され、そのすべての検出にも反映されます。

呼び出すエンドポイントの選び方

検出エンドポイント

/detectionsはIssuesに分類されているエンドポイントの新しい名前であり、別のAPIではありません。いずれも両方のパスで応答します。 どちらのパスも同じコードを実行し、issuesキーやtotal_issuesキーを含めて同じレスポンスを返します。新しい連携では/detectionsを使用してください。/issuesも引き続きサポートされます。

ファインディングエンドポイント

GET /api/v1/findingsは、ファインディングごとに1行を、初めて検出された日時の新しい順に返します。pageとpage_size(最大100)でページネーションでき、total_findingsに件数が含まれます。特に記載がない限り、フィルターにはカンマ区切りのリストを指定できます。 branchフィルターはありません。ファインディングはプロジェクトに属し、ブランチはその検出の属性だからです。トークンには、その種別の検出一覧と同じ表示権限が必要です。表示権限のない種別を指定すると403になります。 GET /api/v1/findings/{finding_id}は、同じ形式でファインディングを1件返します。トリアージ関連のフィールドに加えて、urgency、classification、project、detection_state、first_detection_date、last_detection_date、detections_count、latest_detectionが含まれます。

detection_state

ファインディングは、プロジェクト内に検出が存在する間はactiveです。最後の検出がスキャンまたはプロジェクトとともに削除されるとretiredになります。再スキャンで報告されなくなったファインディングはretiredにはなりません。activeのまま、statusがfixedになります。retiredになったファインディングもトリアージ情報を保持するため、検出が再び現れた場合は同じファインディングIDに紐付けられ、同じ判断が引き継がれます。
アカウントのファインディングインデックスの構築が完了するまで、detection_stateはnullになり、GET /api/v1/findingsは404を返します。検出エンドポイントとGET /api/v1/findings/{finding_id}には影響しません。

ファインディング単位のトリアージ

PATCH /api/v1/triage/findingsはfinding_idsを受け付けます。ファインディングID(GET /api/v1/findingsの結果、または検出項目のfinding_idから取得)のリスト、あるいは検出IDのリストを指定できます。ファインディングIDはそのファインディングの最新の検出を表し、判断はファインディングのすべての検出に反映されます。どこにも一致しないIDはunresolved_idsとして返され、不一致として扱われるため、古いIDが含まれていても残りのIDには適用されます。一括トリアージの対象はSAST、シークレット、ロジック、コード品質、依存関係の各種別です。コンテナまたはIaCのIDはunresolved_idsとして返され、監査行のfinding_typeはsastまたはscaになります。 ruleにはstatusesのスコープを指定できます。たとえば、現在受け入れ済みリスクになっているすべてのファインディングを、1回の呼び出しで誤検知に変更できます。

同期ループの例

チケットのキーにはファインディングIDを使用してください。検出IDはスキャンごとに変わりますが、ファインディングIDは変わりません。 1回の実行で3つの一覧を読み取り、1回の一括更新を行います。一覧はすべてページ分割されるため、page_size=100を指定し、pageがtotal_pagesに達するまでpage=1, 2, …と順に取得してください。実行の開始時刻をUTCの完全なISO 8601形式の日時として保存し、次回の<前回の実行時刻>に指定します。
  1. GET /api/v1/findings?created_since=<前回の実行時刻>:新しいファインディングごとにチケットを作成します。新しいファインディングにはまだトリアージの変更がないため、手順2では返されません。
  2. GET /api/v1/findings?status_changed_since=<前回の実行時刻>&detection_state=all:retiredのファインディングを含め、トリアージの変更を反映します。statusがfixedになったファインディングは、対応するチケットをクローズします。
  3. GET /api/v1/findings?detection_state=retired:retiredのファインディングを照合します。retiredになっても時刻は記録されず、ステータスも変わらないため、どちらのカーソルでも返されません。この一覧全体を未完了のチケットと照合し、一覧に含まれるものをクローズするか、フラグを付けてください。検出が再び現れると、ファインディングは同じIDのままactiveに戻ります。
  4. finding_idsを指定したPATCH /api/v1/triage/findings:チケットシステムで行った判断をCorgeaに書き戻します。200が返った場合でもunresolved_idsを確認してください。そこに含まれるIDは更新されていません。コンテナとIaCのファインディングのIDもすべてここに含まれます。バッチ内のその他のIDは更新されています。
コード品質のファインディングも同期する場合は、各一覧の呼び出しにissue_typeを指定してください。デフォルトでは除外されます。GET /api/v1/findingsが404を返した場合は、同期対象がないのではなく、アカウントのファインディングインデックスの構築が完了していないことを意味します。前回のカーソルを保持したまま、後で再試行してください。