View on GitHub

field-cage

A lightweight eBPF agent that monitors and restricts outbound network connections on GitHub Actions runners.

GitHub Actions

Composite Action でランナー上に field-cage を起動できます。指定バージョンのリリースバイナリを取得し、SHA-256 チェックサムを検証してから、ジョブの残りの期間バックグラウンドでエージェントを実行します。

インライン allowlist

別ファイル不要:

- uses: takihito/field-cage@v0.1.0
  with:
    version: v0.1.0
    mode: block
    allow: |
      github.com
      api.github.com
      objects.githubusercontent.com
      registry.npmjs.org

外部 config ファイル

複雑なポリシーや複数ワークフロー共有の場合:

- uses: takihito/field-cage@v0.1.0
  with:
    version: v0.1.0                          # `uses:` のタグと一致させること
    config: .github/field-cage-policy.yml    # 省略時はポリシー無しの audit
    mode: audit                              # audit(ログのみ)または block

allowconfig は同時に指定できません。両方を指定するとエラーになります。

補足

レポート: 整形されたジョブサマリ

ジョブの末尾に takihito/field-cage/report を追加すると(前段のステップが失敗・DENY してもレポートは実行したいため if: always() を付ける)、ログを GitHub Actions のジョブサマリとして整形表示し、拒否された宛先をアノテーションとして表示できます:

- uses: takihito/field-cage@v0.1.0
  with:
    version: v0.1.0
    mode: audit
    allow: |
      github.com
      api.github.com

# ... 通信を発生させるステップ ...

- uses: takihito/field-cage/report@v0.1.0
  if: always()
  with:
    version: v0.1.0        # 本体ステップの version と一致させる
    fail-on-deny: false    # DENY が1件でもあればジョブを失敗させたい場合は true(主に block モード向け)

$GITHUB_STEP_SUMMARY へ拒否/許可/スキップ宛先の表を書き込み、拒否された宛先ごとにアノテーションを1件発行します(block モードでは warning、audit モードでは実際には遮断していないため notice)。また denied-count / allowed-count / suggested-allowlist(観測された宛先の JSON 配列。ポリシー作成の出発点として使えるが、採用前にレビューすること)/ log-file(実際に解決・レンダリングしたログパス)をステップ出力として公開します。生ログ全文はジョブログへのコピー(既定オフ、dump-log: true で有効化)やアーティファクトへのアップロード(upload-log: true)を明示的に有効化しない限り出力されません — 上記のサマリを優先する設計です。v0.1.0 の次のリリース以降では、レンダリング後にエージェントの停止も行います(stop-agent: false で無効化可、詳細は後述の「エージェントの停止」参照)。この動作を得るには version をそのリリース以降にピン留めしてください。全入力は report/action.yml を参照してください。

エージェントの停止

stop/action.yml および report の既定停止動作は v0.1.0 には含まれていません。version / uses: の参照先は v0.1.0 ではなく、これらを含む最初のリリースタグ(Releases を確認)にピン留めしてください。

takihito/field-cage/report は既定でエージェントを停止するため、通常はこれを直接呼ぶ必要はありません。report を使わないジョブ、または後続ステップでエージェントを動かし続けたいために stop-agent: false を指定した場合は、ジョブの本当の末尾で takihito/field-cage/stopif: always() 付きで呼んでください:

- uses: takihito/field-cage/stop@vX.Y.Z
  if: always()

エージェントに SIGTERM を送り、少し待ってから必要に応じて SIGKILL にエスカレーションします。これが特に重要になるのは block モードです。エージェントは cgroup 全体を対象とする eBPF フックで強制するため、ランナー自身のプロセスも対象に含まれます。ジョブ終了時までエージェントが動き続けていると、ランナー自身のステータス報告用通信までブロックしてしまい、正常な失敗ではなく「ジョブがハングしたように見える」状態になり得ます。

CLI: text、JSON、CSV

同じ集計処理はバイナリの report サブコマンドから直接利用できます。ローカルや他の CI システムでも使えます:

field-cage report --log /tmp/field-cage.log --format text
field-cage report --log /tmp/field-cage.log --format json
field-cage report --log /tmp/field-cage.log --format csv

--format auto(既定)は GitHub Actions ランナー上(GITHUB_ACTIONS=true)では markdown、それ以外では text を選ぶため、上記の Action もローカルで同じバイナリを実行する場合も追加フラグ無しでそれぞれ適切な出力になります。--raw は集計せず1イベント1行で出力します(textjsoncsv のみ)。他ツールへのパイプ処理に便利です。フラグ一覧は field-cage report --help を参照してください。

リリース

バイナリ(linux/amd64linux/arm64)と checksums.txtGoReleaser により GitHub Releases へ公開されます。バージョン管理は tagpr が担い、自動メンテされるリリースPRをマージすると vX.Y.Z タグが push され、リリースビルドが起動します。

各リリースには cosign によるキーレス署名バンドル(checksums.txt.bundle)と SLSA Level 3 来歴証明(checksums.txt.intoto.jsonl)がリリースアセットとして同梱されます。

チェックサムの署名を検証する:

cosign verify-blob \
  --bundle checksums.txt.bundle \
  --certificate-identity "https://github.com/takihito/field-cage/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  checksums.txt

SLSA 来歴証明を検証する:

slsa-verifier verify-artifact \
  --provenance-path checksums.txt.intoto.jsonl \
  --source-uri github.com/takihito/field-cage \
  --source-tag vX.Y.Z \
  field-cage_linux_amd64   # または field-cage_linux_arm64