aqua-installer はなぜ bootstrap するのか
CLI ツールを YAML でバージョン管理できるツール aqua を開発しています。
今回は aqua-installer の内部実装のお話です。
aqua-installer は aqua をインストールする際、指定されたバージョンを直接インストールするのではなく、まず aqua-installer 内でハードコードされたバージョンをインストールし、その後 aqua update-aqua (upa)
コマンドを使って指定されたバージョンをインストールするという、一見無駄なことをしています。
なぜこんなことをしているのか今までちゃんと説明したことはありませんでしたが、 Issue が作られたので説明します。
一言でいうと secure な install を依存を最小限にしつつ簡単に実現するためです。
- secure な install: checksum や署名の検証
- 最小限の依存: Cosign などは不要 (aqua が内部的に自動でインストール) で curl や wget だけで良い
- 簡単に実現: aqua-installer (シェルスクリプト) でそこまで頑張らなくて良い。複雑な処理は aqua (
aqua upa
) に任せる
aqua は Supply Chain Security に力を入れています。
ちなみにツールをインストールするそのへんのシェルスクリプトや action (いわゆる setup-*) の多くは Supply Chain Security について配慮しておらず、安全とは言えません。
checksum の検証をするには、期待される checksum の値を取得する必要があります。
aqua-installer は任意のバージョンを受け取れるので、任意のバージョンの checksum が取得できる必要があります。
checksum file をダウンロードしてきて検証する場合、そのファイルが正しいものかも検証する必要があります。
aqua ではこの検証に Cosign などを用いているので、 aqua をインストールする前に Cosign などを secure にインストールする必要があります。
Cosign を secure にインストールするには Cosign の検証が必要なわけで、ここで bootstrap 問題 が発生します。
この bootstrap 問題を解消するため、 aqua-installer では先述の通り特定の version の aqua の checksum をハードコードしています。
まずはそのバージョンを download して Cosign を使わずに checksum の検証を行っています。
そしてその aqua を用いて aqua upa
を実行し secure に Cosign 及び aqua をインストールします。
Cosign を安全にインストールするため、 aqua 内部では Cosign のバージョンと checksum がハードコードされています。
aqua upa
は安全に Cosign をインストールし、その Cosign を用いて aqua を安全にインストールします。
このため、一見無駄にも見える bootstrap が必要になるのです。
このような仕組みを取らずに安全にインストールしようとすると、事前に以下のいずれかが必要になり、 aqua-installer を簡単に実行できなくなります。
- Cosign: checksum file の検証
- slsa-verifier: SLSA Provenance の検証
- GitHub CLI と GitHub Access Token: GitHub Artifact Attestations の検証
また、 gh attestation コマンドをサポートしてない GitHub CLI だと GitHub Artifact Attestations を検証できないなど、互換性の問題も出てきます。
aqua では Cosign や GitHub CLI など内部的に使うツールのバージョンはハードコードされており、ユーザーの環境に依存しないようになっています。
小難しい処理はシェルスクリプト (aqua-installer) では行わずに aqua upa
で行うことで aqua-installer は比較的シンプルに済んでいます。
もちろん 2 段階でインストールすることになるのでオーバーヘッドはありますが、仕方のないことだと思っています。
Discussion
ドキュメントも更新しました。