日本語

Buildkite での Device Protection

BuildkiteのジョブはLinux上で実行されるため、Device Protectionは他のLinuxマシンと同じ方法でインストールします。Buildkite固有なのはインストール先です。存続し続けるエージェントホストに一度だけインストールするか、ビルドごとに破棄されるエージェントでは各ジョブ内でインストールします。

トークンとパッケージについては、まずInstall Device Protection for Linuxを、以下のジョブレベルのスニペットで使用するコンテナインストールについてはDevice Protection in Containersをお読みください。

存続し続けるエージェント

他のビルドサーバーと同様にホストにエージェントをインストールすれば、パイプラインを一切変更せずに、そのエージェントが実行するすべてのジョブが検査されます。Ansible、cloud-init、または独自にビルドしたイメージを使ってエージェント群に展開するには、Deploying on Linuxを使用してください。

ビルドごとに破棄されるエージェント

エフェメラルエージェント、コンテナ化されたエージェント、Buildkiteホステッドエージェントには準備するホストがないため、ジョブ内でエージェントをインストールし、パッケージのインストールより前に起動します:

.buildkite/pipeline.yml
agents:
  queue: linux-small

steps:
  - label: ":shield: install dependencies"
    command: |
      export AIKIDO_TOKEN=$$(buildkite-agent secret get AIKIDO_TOKEN)

      curl -fsSLO https://github.com/AikidoSec/safechain-internals/releases/latest/download/EndpointProtection-amd64.deb
      AIKIDO_CONTAINER=1 AIKIDO_CI_CD=1 apt-get install -y --no-install-recommends ./EndpointProtection-amd64.deb

      aikido-endpoint-protection-start --wait-for-healthy
      for f in /etc/profile.d/aikido-*.sh; do . "$$f"; done

      npm ci
  • インストール前にトークンをエクスポートしてください。 パッケージはインストール中にAIKIDO_TOKENを読み取ります。
  • インストール自体は標準のコンテナインストールです。 モード変数、起動コマンド、sourceによる読み込みについては、arm64およびRed Hat系エージェントで使用するパッケージとあわせてDevice Protection in Containersで説明しています。

インストールにはroot権限が必要ですが、Dockerベースのエージェントはすでにroot権限を持っています。ジョブがbuildkite-agentユーザーとして実行される場合は、インストールの前にsudoを付けてください。

buildkite-agent secret getにはエージェント3.106.0以降が必要です。このバージョンでは、$$エスケープを省略してBuildkiteに変数を設定させることもできます:

steps:
  - command: .buildkite/install-deps.sh
    secrets:
      AIKIDO_TOKEN: aikido_token

パイプラインを編集せずにすべてのジョブで実行する

このブロックを入れ忘れたステップでは、パッケージが検査されずにインストールされます。代わりに、リポジトリの.buildkite/hooks/pre-commandまたはエージェントのhooksディレクトリにあるpre-commandフックに移動してください:

.buildkite/hooks/pre-command
#!/bin/bash

export AIKIDO_TOKEN="$(buildkite-agent secret get AIKIDO_TOKEN)"

if ! command -v aikidoctl >/dev/null 2>&1; then
  curl -fsSLO https://github.com/AikidoSec/safechain-internals/releases/latest/download/EndpointProtection-amd64.deb
  AIKIDO_CONTAINER=1 AIKIDO_CI_CD=1 apt-get install -y --no-install-recommends ./EndpointProtection-amd64.deb
  rm -f EndpointProtection-amd64.deb
fi

aikido-endpoint-protection-start --wait-for-healthy

for f in /etc/profile.d/aikido-*.sh; do
  [ -e "$f" ] && . "$f"
done

フックはパイプラインYAMLではなくディスク上のスクリプトなので、ここでは$$ではなく$と記述します。Buildkiteはフックをsourceで読み込むため、フックがエクスポートした内容はコマンドに引き継がれます。

コンテナ内で実行されるジョブ

ステップをDockerまたはDocker Composeプラグイン経由で実行する場合は、ステップではなくイメージにエージェントをインストールしてください。Device Protection in Containersを参照してください。

.buildkite/pipeline.yml
steps:
  - label: ":shield: install dependencies"
    command: |
      for f in /etc/profile.d/aikido-*.sh; do . "$$f"; done
      npm ci
    plugins:
      - docker#v5.14.0:
          image: "ghcr.io/your-org/my-app:latest"
          environment:
            - AIKIDO_TOKEN

プラグインはイメージのENTRYPOINTを維持するため、エージェントは自動的に起動します。プラグインのentrypointまたはcommandオプションを設定するとそのエントリポイントは失われるため、コマンドの最初でaikido-endpoint-protection-start --wait-for-healthyを実行してください。Kubernetesスタックはコンテナのコマンドを置き換えるため、同様の対応が必要です。

動作確認

Aikidoがブロックするパッケージをダウンロードするステップを追加します:

.buildkite/pipeline.yml
steps:
  - label: ":shield: verify Device Protection"
    command: |
      aikidoctl version
      curl -sS -o /dev/null -w "%{http_code}\n" --max-time 15 https://registry.npmjs.org/safe-chain-test/-/safe-chain-test-0.0.1-security.tgz

エージェントがすでに実行されているステップで実行してください。curlは403を出力し(エージェントがマルウェアテストパッケージを拒否したことを示します)、エージェントがデバイス一覧に表示されます。その他の確認方法については、How to test if Device Protection is workingを参照してください。

トラブルシューティング

問題解決策
トークンが空で、エージェントが登録されない$がエスケープされていなかったため、Buildkiteがアップロード時に$(buildkite-agent secret get ...)を解決しました。パイプラインYAMLでは$$を、フックスクリプトでは単一の$を使用してください
buildkite-agent: command not found、またはシークレットを読み取れないエージェントが3.106.0より古い、シークレットが別のクラスターにある、またはジョブがエージェントバイナリのないコンテナで実行されています。Dockerプラグインでmount-buildkite-agentを有効にしてください
ジョブ内のダウンロードがまったく検査されないプラグインのentrypointまたはcommandオプションがイメージのエントリポイントを置き換えたため、エージェントが起動しませんでした。コマンドの最初でaikido-endpoint-protection-start --wait-for-healthyを実行してください

npmやuvからの証明書エラーなど、Buildkite固有でない問題については、Device Protection in Containersのトラブルシューティング表を参照してください。