サプライチェーン保護
自律型コーディングエージェントは絶えずパッケージをインストールします。プロジェクトの雛形を作るだけで、人間が名前どころか変更履歴を読むこともなく、数百もの依存関係が取り込まれます。そのため、パッケージレジストリは敵対的なコードがサンドボックスに侵入する最も広い経路となります。タイポスクワットされた名前、乗っ取られたばかりのリリース、悪意のある postinstall スクリプトは、npm install が完了した瞬間にエージェントの完全な権限で実行されます。Bromure Agentic Coding はすべてのパッケージ取得を信頼できない入力として扱い、1バイトでもVMに到達する前に、ホスト上でワークスペースごとのポリシーを適用します。
この章では、何が傍受されるか、パイプライン内の各チェック、チェックが発動したときに何が起こるか、そして結果をセキュリティログでどう読むかを説明します。このペインのフィールドごとの設定リファレンスは サプライチェーン設定 にあります。
パッケージのインストールが攻撃対象領域である理由
サンドボックスはすでにエージェントを封じ込めています。エージェントはあなたのMacに触れることはできず、その認証情報はおとりです(認証情報 を参照)。サンドボックスが単独でできないのは、エージェントが取り込むコードの出所を判断することです。サプライチェーン攻撃はまさにそのギャップを突きます。
- 新しいリリースの乗っ取り。 メンテナーのアカウントが侵害され、悪意のあるバージョンが公開されます。これらのバージョンは通常、数時間から数日以内に検出され取り下げられます。だからこそ エイジゲート は、カットオフより新しいバージョンを拒否します。
- 既知の脆弱性を持つバージョン。 エージェントが依存関係を、公開されたアドバイザリのあるバージョンに解決します。OSV チェックがこれらを捕捉します。
- マルウェア、タイポスクワット、不正なインストールスクリプト。 最初から悪意を持って作られたパッケージです。socket.dev および Delpi プロバイダーがこれらをフラグ付けまたはフィルタリングし、インストールスクリプトの除去が最も一般的な実行経路を完全に取り除きます。
強制はもともとホスト側で行われます。プロキシはエージェントが見る前にレスポンスにポリシーを適用するため、VM内で動作するもの(完全に侵害されたエージェントを含む)はルールを緩めることができません。VM内の .npmrc と pip.conf は、プロキシがすでに提供したものをさらに制限することしかできず、緩めることは決してできません。評価サービスのAPIキー(socket.dev、Delpi)はホスト上でのみ保持され、VMにエクスポートされることは決してありません。
傍受の仕組み
VMが行うすべてのネットワークリクエストは、ホスト側のMITMプロキシを通過します(コンセプト を参照)。プロキシは主要なパッケージレジストリへのリクエストを認識し、それぞれを分類します。
- メタデータ — パッケージのバージョン一覧(npm の packument、PyPI の JSON API または
/simple/インデックス、Cargo のスパースインデックスエントリなど)。エイジゲートはここで、一覧を書き換えることによって動作します。 - アーティファクト — 特定の1バージョンのダウンロード可能なファイル。npm の
.tgz、Python の wheel または sdist、.crate、.gem、.nupkg、Go モジュールの.zipなど。OSV 検索、socket.dev チェック、スクリプト除去、ハードブロックはすべてアーティファクト取得時に行われます。 - パススルー — それらのホスト上のその他すべて(検索、認証)。手を加えません。
ワークスペースに対して少なくとも1つのサプライチェーンレイヤーが有効になると(またはワークスペースが bromure.io に登録されると、その場合はすべての強制レイヤーがオフでも取得がテレメトリのために観測されます)、傍受は自動的に行われます。VM内にインストールや設定するものは何もありません。
メモ: npm や pip のローカルキャッシュにすでに存在するパッケージはネットワークに到達しないため、それらについては何もチェックされず、ログにも記録されません。インストール中にセキュリティログが静かなのは、単にすべてがキャッシュから来たことを意味する場合があります。
判定: 許可、書き換え、ブロック、保留
サプライチェーンレイヤーは個別のオン/オフトグルであり、それぞれ固定のアクションを持ちます。このペインにはグローバルなブロック/警告/許可モードはありません。(プロンプトインジェクション で見たことがあるかもしれない3方向のログ/確認/ブロックのラジオボタンや、ガードレール の強制モードは別のシステムです。)すべての取得は次の4つの結果のいずれかで終わります。
| 結果 | 何が起こるか | 表示されるマーカー |
|---|---|---|
| 許可 | レスポンスはそのまま通過します。 | セキュリティログの緑のチェック。「inspecting」の行がプロキシがそれを見たことを確認します。 |
| 書き換え | プロキシがレスポンスを変更しました。新しすぎるバージョンがメタデータから削除されたか、tarball からインストールスクリプトが除去されました。パッケージマネージャーは正常に処理を続けます。 | X-Bromure-Rewritten: supply-chain レスポンスヘッダー。ログのオレンジの「stripped」行。 |
| ブロック | ダウンロードは HTTP 451(「法的理由により利用不可」)レスポンスで拒否されます。 | X-Bromure-Block: supply-chain ヘッダー。ログの赤い行。 |
| 同意のため保留 | ロックファイルにピン留めされたパススルーや、有効な評価ソースが審査できなかったパッケージについて、Bromure があなたに尋ねる間、ダウンロードは一時停止します。拒否すると保留は 451 ブロックに変わります。 | システムの同意アラート。決定がログに記録されます。 |
451 ブロックには、Bromure Supply-Chain Security blocked this request: で始まり、その後に正確な理由が続くプレーンテキストの本文が含まれます。例えば次のとおりです。
Bromure Supply-Chain Security blocked this request: npm package [email protected]
published 4 hours ago — policy requires 2 days minimum
npm、pip、cargo、その他のパッケージマネージャーはその本文をエラー出力にそのまま表示するため、エージェントもあなたもインストールが失敗した理由を正確に確認できます。そしてエージェントはしばしば自力でそれを回避できます(例えば、より古いバージョンをピン留めするなど)。451 ステータスは意図的に選ばれており、サプライチェーンのブロックが ガードレール が使う 403 と一目で区別できるようになっています。
エコシステム別のカバレッジ
プロキシは8つのパッケージエコシステムを傍受します。すべてのチェックがすべてのエコシステムをサポートしているわけではありません。
| エコシステム | 傍受されるホスト | エイジゲート | OSV | socket.dev | Delpi | スクリプト除去 |
|---|---|---|---|---|---|---|
| npm | registry.npmjs.org, *.npmjs.org | あり | あり | あり | あり | あり |
| PyPI | pypi.org, files.pythonhosted.org | あり | あり | あり | — | — |
| Cargo | crates.io, static.crates.io, index.crates.io | あり | あり | なし | — | — |
| RubyGems | rubygems.org | あり | あり | あり | — | — |
| Maven Central | repo1.maven.org, repo.maven.apache.org, search.maven.org | なし | あり | あり | — | — |
| NuGet | api.nuget.org, *.nuget.org | なし | あり | あり | — | — |
| Go モジュール | proxy.golang.org | なし | あり | あり | — | — |
| Packagist | repo.packagist.org, packagist.org | あり | あり | あり | — | — |
知っておくべきギャップが2つあります。
- エイジゲート — Maven、NuGet、Go。 これら3つのエコシステムは、標準のメタデータレスポンスにバージョンごとの公開タイムスタンプを持たないため、メタデータはフィルタリングされずに通過し、アーティファクトのバックストップには処理すべきデータがありません。エイジゲートは今日、これらを事実上ブロックしません。npm、PyPI、Cargo、RubyGems、Packagist は完全にカバーされています。
- socket.dev — Cargo。 socket.dev は Cargo をサポートしていません。socket.dev フィルタリングを有効にすると、すべての
crates.ioアーティファクトは判定を返さず、そのため未検証パッケージの同意プロンプトが発動します(オフラインおよび機能低下時の動作 を参照)。ワークスペースで大量の Rust 作業を行う場合は、プロンプトに答えるか、別のプロバイダーを選択してください。
エイジゲート
エイジゲートは、設定可能な日数より新しいパッケージバージョンを拒否します。これは、公開されたばかりのリリースが乗っ取られたばかりのパッケージである可能性が最も高いという理論に基づいています。悪意のあるバージョンは通常すぐに報告されて取り下げられ、その期間を待つことは通常の開発ではほとんどコストがかかりません。これはデフォルトで有効な唯一のレイヤーで、最低2日に設定されています。
これは2つの連携するメカニズムを通じて動作します。
- メタデータの書き換え。 プロキシはレジストリのバージョン一覧から新しすぎるバージョンを取り除き、
latestやその他の dist-tag を、生き残った最新バージョンに向け直します。したがって浮動参照(pkg@latest、semver 範囲)はハードブロックされることはありません。パッケージマネージャーは、通過するのに十分古い最新バージョンに静かに解決します。エージェントの視点からは、カットオフより新しいバージョンは単にまだ存在しないだけです。 - アーティファクト取得のバックストップ。 プロキシがメタデータで見るバージョンごとの公開時刻はすべてメモリにキャッシュされます(最大50,000エントリ)。エージェントがその後、ピン留めされた新しすぎるバージョンを直接リクエストすると、その取得はパッケージの実際の経過時間と必要な最低日数を示す 451 でブロックされます。pip の場合、デフォルトの PEP 503 HTML インデックスにはタイムスタンプがないため、Bromure は公開時刻を取得するために
https://pypi.org/pypi/<pkg>/<version>/jsonのオンデマンド検索を実行します。
設定するには、ワークスペースの サプライチェーン ペインを開き、エイジゲート グループを使用します。
- カットオフより新しいパッケージを拒否 を切り替えます。
- ステッパーで 最低経過日数: を設定します(0〜90日)。
- 特定のパッケージをすぐにインストール可能にする必要がある場合(例えば、あなた自身のチームがそれを公開している場合)、Add entry ボタンで 除外パッケージ に追加します。エントリは 許可リスト形式 を使用します。
npm:axiosは除外を1つのエコシステムに限定し、単なるaxiosはすべてのエコシステムでそのパッケージ名に一致します。マッチングは大文字小文字を区別しません。
ヒント: npm のメタデータリクエストは、ゲートが公開時刻を見られるように、完全な packument に静かにアップグレードされます。npm の省略メタデータ形式について何もする必要はありません。
OSV 脆弱性チェック
OSV チェックは、ダウンロードされた各アーティファクトのエコシステム、パッケージ、バージョンを api.osv.dev で検索します。これは無料の Open Source Vulnerabilities データベースで、GitHub Advisory Database、PyPI アドバイザリ、Go の脆弱性データベース、RubySec などを集約しています。その正確なバージョンに対するアドバイザリが、あなたが選んだ深刻度以上であれば、ダウンロードは 451 でブロックされます。8つすべてのエコシステムをカバーし、APIキーは不要です。
深刻度は、アドバイザリに GHSA ラベルがある場合はそこから取得されます。それ以外の場合、Bromure はアドバイザリのベクター文字列から CVSS v3 の基本スコアを計算します。
OSV 脆弱性チェック グループでは、次のようにします。
- api.osv.dev でパッケージを検索する(無料、キー不要) を切り替えます。
- ブロックする深刻度: を選択します。低以上、中以上、高以上、または 重大のみ です。
このチェックはデフォルトでオフで、深刻度のしきい値はデフォルトで 高以上 です。ペイン自体が指摘しているように、推移的なサブパッケージの低深刻度の CVE がワークフローを中断させるべきではありません。検索はアーティファクトのダウンロード時のみ実行され(メタデータ取得時ではない)、結果はアプリの実行中メモリにキャッシュされ、最大16件の検索が並行して実行され、一時的なネットワークエラーはバックオフ付きで最大5回再試行されます。OSV にまったく到達できない場合、パッケージは静かに許可されるのではなく、あなたの同意のために保留されます。オフラインおよび機能低下時の動作 を参照してください。
パッケージフィルタリング: socket.dev と Delpi
パッケージフィルタリング グループは、相互排他的なラジオボタンで評価プロバイダーを選択します。None、socket.dev、または Delpi です。2つのプロバイダーは根本的に異なる方法で動作します。socket.dev はプロキシが取得を通す前に参照する事前検索であり、Delpi は npm レジストリを完全に置き換えます。設計上、一度に1つしかアクティブにできず(両方を実行するとすべてのインストールが二重にフィルタリングされます)、None を選択すると、保存されたキーを保持したまま両方を無効にします。どのプロバイダーを選んでも、この章の他のレイヤー(エイジゲート、OSV、スクリプト除去)はその上でなお適用されます。
デフォルトは None です。ラジオボタンが存在する前に作成され、すでに socket.dev キーを持つワークスペースは、自動的に socket.dev と推測されます。
socket.dev
socket.dev は商用のパッケージ評価サービスです。socket.dev を選択して API キーを入力すると、プロキシは各アーティファクトのダウンロードを提供する前に socket.dev の issue API と照合します。npm、PyPI、Go、Maven、RubyGems、NuGet、Packagist をサポートしますが、Cargo はサポートしません(エコシステム別のカバレッジ を参照)。
キーはあなた自身で用意します。API key: フィールドの隣にある Get an API key をクリックし(socket.dev/dashboard/settings/api-tokens が開きます)、トークンを作成して、セキュアフィールドに貼り付けます。両方のブロックトグルはキーが入力されるまで無効のままで、空のキーはトグルに関係なく socket.dev を完全に無効にします。キーはワークスペースの profile.json にホスト側で保存され、VM に入ることは決してありません。すべての検索はあなたの Mac から発信されます。
2つの独立したブロックが利用できます。
- 侵害されたパッケージ(不正なインストールスクリプト、マルウェアとしてフラグ付け、タイポスクワット、疑わしいテレメトリ)をブロック — socket.dev の攻撃的な形状のサプライチェーンリスクの issue で発動します。決定的なマルウェアシグナル(マルウェア、既知のマルウェア、GPT検出マルウェア、トロールパッケージ、侵害された SSH キー)はどの深刻度でもブロックします。よりノイズの多い攻撃的な形状のシグナル(難読化コード、疑わしい文字列、インストールスクリプト、タイポスクワット、シェルアクセス、異常な HTTPS 使用)は、socket.dev が高または重大と評価した場合にのみブロックされ、良性の
postinstallを持つパッケージが引っかからないようにします。純粋な品質および属性シグナル(新しい作者、環境変数の読み取り、ネットワークアクセス、テレメトリ)は意図的に決してブロックしません。 - 既知の CVE を持つパッケージをブロック — socket.dev の脆弱性バケットで、CVE ブロックしきい値: ピッカー(OSV と同じ4段階、デフォルトは 高以上)以上で発動します。
両方のブロックはデフォルトでオフです。結果はアプリの実行中キャッシュされ、最大16件の呼び出しが並行して実行され、一時的な失敗はバックオフ付きで5回再試行されます。認証エラーは HTTP ステータスとレスポンス本文のプレビューとともにセキュリティログに表示されます。
メモ: OSV と socket.dev の CVE ブロックを一緒に有効にすると、両方がすべてのアーティファクトをチェックします。これは許可されており(それらは異なるレイヤーです)、CVE カバレッジとして冗長なだけです。多くのユーザーは代わりに socket.dev の侵害パッケージブロックと無料の OSV チェックを組み合わせています。
Delpi
Delpi は Lupin & Holmes(landh.tech)によるドロップイン式のセキュアな npm レジストリで、事前審査済みのパッケージを提供します。パッケージを検索する代わりに、Bromure はすべての npm レジストリリクエスト(メタデータ、tarball、audit、registry.npmjs.org または *.npmjs.org 宛てのあらゆるもの)を、depi-npm-proxy.landh.tech:443 にある Delpi の npm 互換フィルタリングレジストリに再ルーティングし、あなたのキーを Authorization: Bearer ヘッダーとして付加し、ゲストが送信した Authorization ヘッダーを取り除きます。Delpi は packument 内の tarball URL を自身を指すように書き換えるため、それらの後続の取得もホスト側でキーが注入されます。
有効にするには、ラジオボタンで Delpi を選択し、キーを API key: セキュアフィールドに貼り付けます(Get an API key は landh.tech を開きます)。フィールドが空の間、オレンジの警告に Enter an API key — Delpi stays off without one. と表示されます。再ルーティングされた各リクエストはセキュリティログに記録されます。
[delpi] GET registry.npmjs.org/… → https://depi-npm-proxy.landh.tech
エラー処理は静かではなく明示的です。
- 401(キー拒否)。 Bromure は npm が表示する明確なプレーンテキストエラー(「Bromure: the Delpi registry rejected the configured API key…」、ヘッダー
X-Bromure-Block: delpi-auth付き)に置き換え、それをログに記録し、ワークスペースとキーの組み合わせごとに一度きりの GUI アラート「Delpi rejected your API key」を表示します。ヘッドレスの SSH/TUI セッションでは GUI アラートは表示されず、ログ行と書き換えられた npm エラーに依存します。 - 403(Delpi によりパッケージがブロックされた、またはキーがそれに対して認可されていない)。 ログに記録され、変更されずに通過するため、npm は Delpi 自身の拒否テキストを報告します。
Delpi は npm のみに影響します。他の7つのエコシステムはそれによって手を加えられません。Delpi はラジオボタンで socket.dev を置き換えるものであり、あなたのローカルポリシーを置き換えるものではありません。エイジゲート、OSV チェック、スクリプト除去は Delpi が提供するものに対してなお実行されます。
インストールスクリプトの除去
npm の preinstall、install、postinstall、prepare フックはインストール時に任意のコードを実行し、実世界の npm マルウェアの主力です。(インストールスクリプト グループの)npm tarball から preinstall / install / postinstall / prepare をその場で除去 を有効にすると、プロキシは各 npm tarball をその場で書き換えます。.tgz を gunzip し、トップレベルの package/package.json を見つけ、それら4つのスクリプトキーを削除し、tar ヘッダーのチェックサムを再計算し、再度 gzip します。
tarball のバイトが変わるため、プロキシはパッケージのレジストリメタデータからも dist.integrity と dist.shasum を削除します。これにより npm は除去済みの tarball から自身でハッシュを計算し、ピン留めされていないインストールでもその検証が引き続き通ります。各除去はログに記録され(そのパッケージとバージョンについて「stripped install scripts from」がオレンジで表示されます)、検査されてクリーンと判明した tarball には X-Bromure-Rewritten: supply-chain ヘッダーのみが付けられます。解析に失敗した場合は元の tarball がそのまま通過します。このレイヤーは fail open であり、整形式のインストールを決して壊してはならないためです。
一部のパッケージは正当にインストールスクリプトを必要とします。better-sqlite3 や node-canvas のようなネイティブバインディングのコンパイラなどです。それらを インストールスクリプトを許可 に追加すると(形式は npm:better-sqlite3)、そのフックが維持されます。
このトグルはデフォルトでオフで、2つの制限が適用されます。
- npm のみ。 PyPI の sdist は書き換えられません。
setup.pyは任意のコードなので、そこでの除去は実現不可能です。 - ピン留めされていないインストールのみ。 integrity ハッシュが
package-lock.jsonにピン留めされた tarball は、検証に失敗せずに書き換えることはできません。そのケースは次のレイヤーによって管理されます。
ロックファイルにピン留めされたインストール
ロックファイルにピン留めされたインストール(npm ci)は、すべての tarball の integrity ハッシュをロックファイルにピン留めします。Bromure はハッシュ検証を壊さずにそれらの tarball を書き換えることができないため、選択肢はそれらを変更せずに通過させるか、ブロックするかのどちらかだけです。デフォルトでは静かに通過します。
意見を反映させたい場合は、ロックファイルにピン留めされたインストール グループの ロックファイルにピン留めされた tarball を変更せずに通過させる前に確認(npm ci、pip --require-hashes) を有効にします。すると、バッチ内の最初のロックファイルピン留め取得(npm では npm-command: ci リクエストヘッダーで検出される)が、ワークスペース「…」からの npm ci(ロックファイルにピン留めされたインストール)を通過させますか? というタイトルのホスト同意ダイアログをポップアップします。ボタンは 15分間許可、一度だけ許可、セッションの残りの間許可、許可しない です。並行する取得のバースト全体がその1つのプロンプトに統合され、あなたの決定に従います。拒否すると取得は 451 でブロックされ、拒否は60秒間記憶されるため、再試行で再プロンプトされることはありません。
メモ: UI ラベルには
pip --require-hashesと記載されていますが、検出は現在 npm のnpm-command: ciヘッダーに対してのみ実装されています。pip のハッシュピン留めインストールはプロンプトを発動しません。(それらも決して書き換えられません。PyPI アーティファクトは決して変更されないためです。)
同意プロンプトと付与
すべてのサプライチェーンのユーザー確認経路(ロックファイルのパススルーと、以下で説明する未検証パッケージの保留)は、バースト統合を備えた共有の同意ブローカーを経由します。同じスコープに対する並行リクエストは、アラートを積み重ねるのではなく、単一のダイアログを待ちます。すべてのプロンプトは同じ4つの決定を提供します。
| 決定 | 効果 |
|---|---|
| 許可しない | 451 でブロックします。60秒間記憶され、即時の再試行を自動的に拒否します。 |
| 一度だけ許可 | この1つのリクエスト(または統合されたバースト)を通します。 |
| 15分間許可 | スコープを15分間付与します。 |
| セッションの残りの間許可 | アプリが終了するまでスコープを付与します。 |
アクティブな付与と拒否は、承認 UI(Window → Credential Approvals… エリア)に、ガードレールの決定とは別に サプライチェーンの決定 として一覧表示され、そこで付与を早期に取り消すことができます。付与はメモリ内のみで、アプリの再起動後は残りません。
リモートの SSH/CLI セッションには GUI ダイアログはありません。同じ質問がワークスペースの tmux 内のチューザーとしてレンダリングされます。回答がなければ拒否となります。リモートアクセス を参照してください。
ポリシーの設定
サプライチェーンポリシーはワークスペースごとに、ワークスペースを編集 ウィンドウの サプライチェーン ペイン(サイドバーの黄色い配送箱のアイコン)で設定します。フィールドごとの完全なリファレンスは サプライチェーン設定 にあります。デフォルトを一目で示すと次のとおりです。
| 設定 | デフォルト |
|---|---|
| カットオフより新しいパッケージを拒否(エイジゲート) | オン、最低経過日数: 2日、除外なし |
| api.osv.dev でパッケージを検索する(無料、キー不要) | オフ、ブロックする深刻度: 高以上 |
| パッケージフィルタリング | None(socket.dev または Delpi キーなし) |
| 侵害されたパッケージをブロック / 既知の CVE を持つパッケージをブロック(socket.dev) | オフ、CVE ブロックしきい値: 高以上 |
| npm tarball から preinstall / install / postinstall / prepare をその場で除去 | オフ、空の許可リスト |
| ロックファイルにピン留めされた tarball を変更せずに通過させる前に確認 | オフ(静かなパススルー) |
3つの運用上の詳細があります。
-
編集はライブで適用されます。 ワークスペースを保存すると、新しいポリシーが実行中のセッションに直ちにプッシュされます。プロキシはリクエストごとにそれを読み取るため、VM の再起動は決して必要ありません。新しいまたは変更された各ポリシーは、セキュリティログの1行の要約で確認されます。例えば次のとおりです。
[supply-chain] policy engaged for 1a2b3c4d: age-gate=2d osv=high socket.dev=compromised+cve=high strip-scripts設定ミスはその要約の中で直接指摘されます。
socket.dev=key-set-but-no-toggleはキーが入力されているがどちらのブロックも有効になっていないことを意味し、delpi=selected-but-no-keyは Delpi が選択されているがキーがないためオフであることを意味します。 -
保存場所。 ポリシーはワークスペースの
profile.json(~/Library/Application Support/BromureAC/profiles/<id>/の下)に存在します(デフォルト以外のフィールドのみが書き込まれます)。socket.dev と Delpi の API キーもそこに保存されます。ホスト側のみで、UI ではセキュアフィールドとして表示され、VM にコピーされることは決してありません。サプライチェーン固有の環境変数や起動引数はありません。 -
リモート設定。 SSH/TUI リモートメニューは、同じフィールドを持つ同じ サプライチェーン ペインを公開するため、ヘッドレスインスタンスを GUI なしで設定できます。リモートアクセス を参照してください。
セキュリティログウィンドウ
サプライチェーンパイプラインが行うすべては、セキュリティログで確認できます。Window → Security Log… を開いてください。これはプロキシが発するすべてのセキュリティイベントのライブテールです。サプライチェーンの検索と判定、451 ブロック、スクリプト除去、ポリシー適用の確認、Delpi の再ルーティングに加え、プロンプトインジェクションの検出、Fusion の起動/停止、LLM ルーティングの変更、リモートアクセスイベント、worktree の行が表示されます。1つのウィンドウがアプリ全体を担い、メニュー項目を再度選択すると前面に表示されます。
行は色分けされているため、インストールを一目で読み取ることができます。
| 色 | 意味 | マーカー |
|---|---|---|
| 青 | 外向きの検索(OSV、socket.dev、公開時刻バックストップ) | → |
| 緑 | クリーンな判定 — パッケージが通過した | ✓ |
| 赤 | ブロックまたは失敗(451、エラー) | ✗ |
| オレンジ | tarball からインストールスクリプトが除去された | 「stripped」 |
| アクセント | ポリシー適用/変更 | [supply-chain] |
ウィンドウには、表示を絞り込む Filter… フィールド(パッケージ名、エコシステム、または気になる行のテキストを入力)、Auto-scroll チェックボックス(デフォルトでオン。読んでいる間テールの追従を止めるにはオフにします)、バッファを消去する Clear ボタン、エントリ数を示すフッター(「42 entries」、フィルターがアクティブな間は「7 of 42 entries」)があります。エントリがいつ表示されるかを説明する空状態のメッセージもあります。
実際に動作を見るには、ウィンドウを開き、セッション内で任意のインストール(npm install、pip install、cargo add、gem install など)を実行し、エントリが流れ込むのを見てください。完全にクリーンなインストールでも各アーティファクトについて「inspecting」行が生成されます。これは意図的なもので、静かなパイプラインとバイパスされたパイプラインを区別できるようにするためです。
メモ: バッファは約5,000行に上限が設定されたメモリ内のリングであり、アプリの再起動をまたいで永続化されません。各行はアプリの stderr にもミラーリングされるため、
bromure-cliをターミナルから起動する(またはそのログ出力をキャプチャする)と、永続的なコピーが得られます。ウィンドウは 820×460 で開き、720×360 まで縮小できます。
オフラインおよび機能低下時の動作
パイプラインの評価チェックは、あなたの Mac からの外向きの呼び出し(VM からではない)に依存します。OSV には api.osv.dev、socket.dev には api.socket.dev、PyPI 公開時刻バックストップには pypi.org、Delpi には depi-npm-proxy.landh.tech です。有効なソースが判定を出せない場合(再試行後のネットワークダウン、HTTP エラー、レート制限、認証失敗、サポートされていないエコシステム)、Bromure は静かに許可するのではなく fail closed します。
ダウンロードは一時停止し、未検証パッケージの保留 が、パッケージとバージョンごとに、ワークスペース「…」から未検証のパッケージを通過させますか? というタイトルのシステムアラートであなたに尋ねます。Bromure はパッケージを審査するためにソースに到達できず、それをインストールすることは、設定された評価ソースに対してチェックされなかったパッケージを受け入れることを意味します。4つの標準的な同意決定が適用され、拒否すると(GUI が利用できずリモートプロンプトがタイムアウトした場合を含む)451 でブロックされます。保留は package@version ごとにキー付けされるため、1つの承認が依存関係グラフ全体をまとめて覆うことは決してありません。
これは意図的な保護です。これがなければ、評価サービスにレート制限を誘発できる攻撃者が、チェックされないままパッケージを忍び込ませることができてしまいます。実際的な結果は次のとおりです。
- OSV または socket.dev を有効にして完全にオフラインで作業する ことは、キャッシュされていないパッケージごとにプロンプトが出ることを意味します。オフラインの間はそれらのレイヤーを無効にしてください。エイジゲートは接続なしでもすでにキャッシュされたメタデータから動作し続けます。
- socket.dev と Cargo の組み合わせ は、socket.dev が Cargo をまったく審査できないため、crate ごとにプロンプトが出ることを意味します(付与は package@version ごとなので、セッションの付与はその1つの crate バージョンのみをカバーします)。
- PyPI 公開時刻バックストップは唯一の例外です。 純粋なネットワークエラーの場合、その取得については fail open します(失敗はキャッシュされないため、次回に検索が再試行されます)。エイジゲートのメタデータ書き換えは影響を受けません。
侵害検出
サプライチェーンチェックは敵対的なコードがサンドボックスに侵入する確率を減らします。侵害検出は、実際に侵入した敵対的なコードが行動を起こそうとする瞬間を捕捉します。これはパッケージパイプラインではなく認証情報システムの一部です(おとり認証情報とトークンスワップの全体像は 認証情報 にあります)が、汚染されたパッケージがその最も可能性の高いトリガーであるため、その警報はここで文書化されています。
VM からの各外向きリクエストは、認証情報スワップレイヤーが鋳造したおとり(「偽の」)トークンについて、1回のパスでスキャンされます。1つのホスト(例えば github.com)にスコープされた偽物が、他のいずれかのホスト宛てのリクエストに現れるのは、認証情報の流出のシグネチャです。そうなったとき、次のことが起こります。
- プロキシは 451 でリクエストをブロックします。宛先は1バイトも受信しません。
- VM は即座に一時停止します。セッションがデタッチされていた場合、強制的に再アタッチされて表示されます。凍結されたセッションフレームは赤く色付けされます。
- この環境は侵害された可能性があります というタイトルの重大なアラートが表示され、Bromure が指定されたワークスペースから、鋳造されていないホストへセッション認証情報を漏洩させようとする外向きの試みを検出したこと、そして VM が一時停止されたことを説明します。漏洩ごとの詳細行として、トークンのプレビュー(
sk-a…f9q3のようなもの)、認証情報の名前、それが鋳造されたホスト、そして向かおうとしていたことが観測されたホストが示されます。
アラートは3つの応答を提供します。
- シャットダウン(デフォルト) — VM を停止し、ワークスペースを 侵害済み としてマークします。
- 調査のために保存 — フォルダを選択すると、Bromure は
disk.img(VM システムディスクのコピー)、home.tar.gz(ワークスペースのホームディレクトリ)、共有フォルダごとのshares/<name>.tar.gzをエクスポートし、その後シャットダウンしてワークスペースを侵害済みとしてマークします。RAM の状態は破棄されます。 - 続行 — リスクを受け入れて再開します。再び発生すると検出器は再発動します。Esc と Cmd-. は意図的に 続行 にマップされていません。敵対的である可能性のある VM を再開することは、明示的なクリックでなければなりません。
侵害済みとしてマークされたワークスペースは、明示的にワイプするまで再起動を拒否し、ワイプフローは共有フォルダがワイプされないことを警告します。それらには汚染されたファイルがまだ含まれている可能性があるため、手作業で確認してください。
設定するものは何もありません。検出は、ホストスコープを宣言する認証情報に対して常にオンです。ピン留めされたホストを持たない手動認証情報(「任意のホスト」)は決してそれを発動できず、Claude/Codex トークンは緩やかな同一登録ドメインマッチを使用します(api.anthropic.com 用に鋳造されたトークンが別の anthropic.com ホストで見られても警報は鳴りません)。一度に1つのアラートのみが表示され、それが開いている間の繰り返しイベントは破棄されます。
エンタープライズの可視性
bromure.io に登録されたワークスペースでは、すべてのメタデータおよびアーティファクトの取得が、エンタープライズイベントストリームに supply_chain.fetch イベントも発行します。これにはエコシステム、パッケージ、バージョン、リクエスト種別、結果(allowed、rewritten、blocked、または stripped)、理由種別(age_gate、osv、socket_compromised、socket_cve、verify_unavailable、lockfile_denied、scripts_stripped)が含まれます。登録するだけで、管理者は組織全体のパッケージダウンロードの可視性(すべてのエージェントがインストールしたすべてのもののインベントリ)を得られます。これはすべての強制レイヤーがオフになっているワークスペースでもです。
登録の仕組みと、管理者が反対側で何を見るかは、エンタープライズ で説明します。