0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CI/CD における falco/cicd-sensor の比較

0
Posted at

少し前に、Takumi Runner が cicd-sensor と連携するよ!という記事があったと思います
https://shisho.dev/docs/ja/r/202608-takumi-runner-cicd-sensor-integration/

これを見た際、cicd-sensor を知らなかったので、軽く見たところ「Falco と同じでは?」と感じました。何が違うのか調べてみたので、ここにまとめておきます。

先に結論(個人的な見解)

  • Falco では syscall/capture から低レベルの行動を広く採取し、後追い解析することが可能。
    調査能力は高いが、privileged container、host mount、artifact と image/action の固定を許容・設計できるチーム向けである。単体ではブロック(process kill)しない。
  • cicd-sensor は、eBPF ランタイムセンサー(cicd-sensor agent)が CI/CD 用ルールを評価し、HTML report と attestation を生成する。ルールに terminate を指定すれば対象 process を止められる。導入面はFalco より単純だが、report の情報量、ルール互換性、terminate 後の証跡欠落を運用で扱う必要がある。
  • どちらも「secret を漏らさない」製品ではない。取得した artifact 自体が新しい情報資産になりうるため、private repository、最小権限、保持期間、外部連携を先に決める。

対象読者

  • CI/CD を利用している方
  • CI/CD 上においてサプライチェーン攻撃に対する防護策の1つとして、ランタイムモニタリングの導入を考えている方

前提条件

下記の記事では:

  • Github Actions を利用しています
    • Github-hosted runner を利用しています
    • でも「上記に該当しないから」と読む価値が無いとは言えない可能性があります
  • Falco と cicd-sensor の比較しかしていません。他の選択肢があれば教えていただけると、検証するかも知れません

また、下記は検証環境 における検証結果を元に書いたレポートです。

Github Actions におけるランタイムモニタリング

GitHub Actions の workflow は YAML で記述された自動処理であり、複数の job からなることが一般的です。
各 job は通常、一時的な Linux 仮想マシン(runner)で実行される。Falco(※1) 及び cicd-sensor は、この runner 上で動く process やファイル操作、通信を観察する security action です。

workflow 開始 → runner 作成 → checkout → security action を起動
                                      ↓
                           以後の build/test/deploy を観測
                                      ↓
                           post step で artifact を保存

この順序が重要で、下記は原則として観測できません。

  • security action を起動するの checkout
  • setup で起きた挙動

また runner は job 終了後に破棄されるため、取得したデータは artifact(Actions に保存するファイル)や S3/GCS、必要なら SIEM などに情報を保存する必要があります。

用語集

下記は以降の内容で出てくる用語集です(LLMに作成させているので、若干読みづらいかもしれません)

  • rule(ルール): 「どの行為を不審とみなすか」を表す条件。例: 特定の workflow ファイルへの書込み、秘密情報らしい値を含む argv、未知の外部通信。
  • event(イベント): rule 判定の材料となる実行記録。Falco/cicd-sensor は OS が
    process 実行・file open・network 接続等を行う際の情報を利用する。こうした OS への低レベル操作を syscall(system call)という。
  • eBPF: Linux kernel の event を比較的低い粒度で取得する仕組み。便利だが、通常の application log より runner の権限・kernel・性能への依存が大きい。
  • post step: Actions の通常 step が終わった後にも action が実行する後処理。report upload はここで行われるため、process を terminate すると後処理が途中で欠ける場合がある。

Falco のモードについて

Falco にはモードが 2 種類あります。EDR とは異なるため、脅威を抑止する機能は無いと思います。

  • live mode: Falco を先に起動し、その後に続く build/test 等をリアルタイムに監視する。
    ルールに一致した event をその場で JSON/log に記録する。runtime を止める機能は持たない。
  • analyze mode: 別 job で syscall の記録(capture)を取り、後続 job でそのファイルを
    replay して解析する。抽出条件を変えて再調査しやすい一方、capture は情報量が大きい。

上記の両方について後ほど検証した結果をまとめます。

cicd-sensor の Rule と Action

cicd-sensor は EDR に近い構想を持ち、Rule に合致した際の Action でプロセスキルが可能です。
プロセスキルを実施しない場合(DETECT) 及び実施する場合(TERMINATED) でそれぞれ何が見えるか?を後述します

Falco/cicd-sensor の比較

どう動き、何を取得するか

Falco cicd-sensor
実行方式 live mode は Falco コンテナを起動して runtime event を記録。analyze mode は syscall capture を別 job で replay agent を起動し、実行中の event を CI/CD ルールで評価。post step が report/attestation を生成
主な設定場所 workflow の action 入力、Falco rule YAML .cicd-sensor/config.yaml.cicd-sensor/rules/*.yaml、workflow の action 入力
主な成果物 Falco event JSON、起動/停止ログ、process、書込み path、DNS、接続先、hash、container、必要なら raw capture.scap HTML report、証跡用 JSON (predicate.json)、rule hit、action/result、CI/CD メタデータ
ブロック action 単体は記録・報告。job を失敗させる gate は workflow 側で明示的に実装する action: terminate で一致した process を停止できる。ネットワーク遮断や runner 全体の隔離を保証するものではない

Falco の実行方式と取得例

下記の流れで動作しています。

  1. GitHub Actions で Falco を使うときは、通常 falco-actions のような action wrapper が Docker で Falco を起動
  2. live mode の action は docker run --privileged で Falco を起動し、/tmp、Docker socket、host の /proc/etc を mount
  3. modern eBPF engine が runtime event を読み、rule に一致した event を JSON に書く
  4. analyze mode は sysdig capture を取り、Falco replay と複数の抽出処理を行う。

ここで --privileged は container に強い host 側の権限を与える指定、mount は runner の path を container から読めるようにする指定です。Falco の観測には必要な場合があるが、通常の build action より高い権限を渡すことになる点に注意が必要です。

live mode での結果

検証環境では、Falco v0.44.1/etc/falco/rules.d/cicd_rules.yaml を実際にロードし、検知イベントとしてSource Code Overwrite を8件記録しました。内訳は下記の通りで、誤検知 があります。

  • 4件は package.json / package-lock.json / 無効化済み workflow への書込みという scenario による有効な検知
  • 4件は GitHub Actions が job を管理するために行う runner 自身の $GITHUB_ENV / step-summary 書込み

具体的には、次のような event が得られました。

{
    "hostname": "51c3032626e5",
    "output": "2026-09-01T01:56:15.524982438+0000: Warning A source code file /home/runner/work/cicd-runtime-testbed/cicd-runtime-testbed/node_modules/.package-lock.json was overwritten by process npm (file=/home/runner/work/cicd-runtime-testbed/cicd-runtime-testbed/node_modules/.package-lock.json gparent=Runner.Worker ggparent=Runner.Listener gggparent=hosted-compute- evt_type=openat user=runner user_uid=1001 user_loginuid=-1 process=npm proc_exepath=/usr/local/bin/node parent=bash command=npm                                                                                 terminal=0 container_id=host container_name=host container_image= container_image_tag=) container_id=host container_name=host container_image_repository= container_image_tag= k8s_pod_name=<NA> k8s_ns_name=<NA>",
    "output_fields": {
        "container.id": "host",
        "container.image.repository": "",
        "container.image.tag": "",
        "container.name": "host",
        "evt.time.iso8601": 1788227775524982500,
        "evt.type": "openat",
        "fd.name": "/home/runner/work/cicd-runtime-testbed/cicd-runtime-testbed/node_modules/.package-lock.json",
        "k8s.ns.name": null,
        "k8s.pod.name": null,
        "proc.aname[2]": "Runner.Worker",
        "proc.aname[3]": "Runner.Listener",
        "proc.aname[4]": "hosted-compute-",
        "proc.cmdline": "npm                                                                                ",
        "proc.exepath": "/usr/local/bin/node",
        "proc.name": "npm",
        "proc.pname": "bash",
        "proc.tty": 0,
        "user.loginuid": -1,
        "user.name": "runner",
        "user.uid": 1001
    },
    "priority": "Warning",
    "rule": "Source Code Overwrite",
    "source": "syscall",
    "tags": [
        "CI/CD"
    ],
    "time": "2026-09-01T01:56:15.524982438Z"
}

このように Falco event は「rule が発火して初めて」詳細が出ます。導入後は、正規の package manager や runner 自身を攻撃と誤認しないよう、除外条件を rule に追加・調整する作業が必要です。

analyze mode の結果

analyze mode では System CAPture ファイル(.scap) を作成し、これを後追い検証します。scap ファイルは必要な際には便利ですが、一方で検索しやすいか...と考えるとそうでも無さそうです。
そのため、scap から必要な情報を抽出していきます。検証時において、元ファイル(.scap)は 1.8MB、抽出加工したデータは 12KB でした。

検証環境では analyze mode で event drop 0・4イベントを確認し、次の加工済み telemetry を GitHub Actions の artifact として受け取りました。実運用で正しいものではなく、あくまで可視性の調査に artifact を利用しています。このような情報が見れると参考にしてください

artifact 内のファイル 何が入るか 実測で見えた例
proc.txt process 名、実行 path、親 process runner が起動した command と executable path
files_written.txt 書込み path、process、親 process package.jsonnpm が書いた記録
outbound.txt / top_connection.txt 接続先 IP/port、process/executable Cloudflare 宛先、Azure resolver/IMDS、通信した process
dns_extract_json.txt DNS 問合せ scenario で問い合わせた domain
hashes.txt executable path と SHA-256 runner 上で実行されたバイナリの hash
containers.txt / udp_extract.txt / topprocs_net.txt container、UDP、通信量上位 空の場合もある。今回の container/UDP は空だった

cicd-sensor の実行方式と取得例

cicd-sensor-action は agent を起動し、呼出元 repository の .cicd-sensor/config.yaml と rules を GitHub Contents API から読みます。

post step は次を artifact として出します。

  • HTML report: 全 rule hit の上位集合。rule ID、detect/terminate 等の action、result、event に由来する argv・path・DNS・URL 等を含み得る
  • attestation predicate: provenance(由来を記録する)用途にも使える predicate.json。detect/terminate hit と project path、commit SHA、actor、runner tracking ID、job/run link、接続先 IP/domain 等を含む
  • 任意の debug bundle: runtime event log、journal、raw result-log、systemd snapshot を含むため、通常は無効にする

検証環境では rule validation が成功し、67 rules・warning 0・http_request の hit を確認しました。HTML report と predicate を回収でき、report には短い argv、DNS、file path、URL path の偽カナリアが確認されました。実際の HTML には、次のように rule と process 情報を組み合わせた JSON が埋め込まれており、描画時には JavaScript がこれを処理、情報を可視化してくれています。

{
  "rule_id": "testbed_canary_argv_carrier",
  "event_type": "process_exec",
  "action": "collect",
  "process": {
    "exec_path": "/usr/bin/curl",
    "argv": ["curl", "--referer", "CNRY..."],
    "ancestors": ["bash", "Runner.Worker"]
  }
}

可視化の例(これいいなと思いました):
スクリーンショット 2026-09-02 022958.png
スクリーンショット 2026-09-02 023017.png
スクリーンショット 2026-09-02 023024.png

ただし、逆に他のところに取り込むことを考えると、デフォルトでは上記の2つのみで、本質的に必要な検知情報は HTML の中に埋まった JSON です。cicd-sensor-result-log.json として保存されているっぽいので、こいつを取り出す必要があるかもしれません。

なお、検証環境で cicd-sensor によるプロセスキルを試みたところ、kill marker を書いた process が exit 130 で止まり、report の testbed_kill_markeraction: terminate / result: terminated だった。これは検知だけでなく、ルールに基づく process 停止が動作した実測となります。

スクリーンショット 2026-09-02 033835.png

まとめ

基本的にはどちらも似たようなソフトウェアです。すごくざっくりですが、下記のような感じです。

  • Falco はプロセスキルはしない方針(のはず)。analyze 使うと scap が取れます
  • cicd-sensor は CI/CD に特化した形で、EDR っぽくプロセスキルが出来ます

私はプライベートに Elastic を使っているので、SIEM に取り込むとどんな感じ?ということは考えてもいいかもしれません。Falco に関しては公式の Integration ありますし...

注釈

※1: Falco は厳密には CI/CD 特化ではないです。
Open Source の Endpoint Detection ソフトウェアであり、例として皆さんの端末上や EC2 でも動きます。
その中で CI/CD に寄せた falco-actions というものがあります。記事
今回はこれを利用しています。なお、メンテされていなかったので fork/自前でパッチを当てました。気が向いたら PR 投げるかも

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?