サプライチェーン保護
自律型コーディングエージェントは絶えずパッケージをインストールします。プロジェクトの雛形を作るだけで、人間が名前どころか変更履歴を読むこともなく、数百もの依存関係が取り込まれます。そのため、パッケージレジストリは敵対的なコードがサンドボックスに侵入する最も広い経路となります。タイポスクワットされた名前、乗っ取られたばかりのリリース、悪意のある postinstall スクリプトは、npm install が完了した瞬間にエージェントの完全な権限で実行されます。Bromure Agentic Coding はすべてのパッケージ取得を信頼できない入力として扱い、1バイトでもVMに到達する前に、ホスト上でマシンごとのポリシーを適用します。
この章では、何が傍受されるか、パイプラインの各チェック、チェックが発動したときに何が起こるか、そしてセキュリティ タイムラインで結果をどう読むかを説明します。サプライチェーンのポリシーはマシンごと(設定エディタではワークスペース)に設定します。このペインの設定をフィールドごとに説明したリファレンスは サプライチェーン設定 にあります。
パッケージのインストールが攻撃対象領域である理由
サンドボックスはすでにエージェントを封じ込めています。エージェントはあなたのMacに触れることはできず、その認証情報はおとりです(認証情報 を参照)。サンドボックスが単独でできないのは、エージェントが取り込むコードの出所を判断することです。サプライチェーン攻撃はまさにそのギャップを突きます。
- 新しいリリースの乗っ取り。 メンテナーのアカウントが侵害され、悪意のあるバージョンが公開されます。これらのバージョンは通常、数時間から数日以内に検出され取り下げられます。だからこそ エイジゲート は、カットオフより新しいバージョンを拒否します。
- 既知の脆弱性を持つバージョン。 エージェントが依存関係を、公開されたアドバイザリのあるバージョンに解決します。OSV チェックがこれらを捕捉します。
- マルウェア、タイポスクワット、不正なインストールスクリプト。 最初から悪意を持って作られたパッケージです。socket.dev および Depi プロバイダーがこれらをフラグ付けまたはフィルタリングし、インストールスクリプトの除去が最も一般的な実行経路を完全に取り除きます。
強制はもともとホスト側で行われます。プロキシはエージェントが見る前にレスポンスにポリシーを適用するため、VM内で動作するもの(完全に侵害されたエージェントを含む)はルールを緩めることができません。VM内の .npmrc と pip.conf は、プロキシがすでに提供したものをさらに制限することしかできず、緩めることは決してできません。評価サービスのAPIキー(socket.dev、Depi)はホスト上でのみ保持され、VMにエクスポートされることは決してありません。
傍受の仕組み
VMが行うすべてのネットワークリクエストは、ホスト側のMITMプロキシを通過します(コンセプト を参照)。プロキシは主要なパッケージレジストリへのリクエストを認識し、それぞれを分類します。
- メタデータ — パッケージのバージョン一覧(npm の packument、PyPI の JSON API または
/simple/インデックス、Cargo のスパースインデックスエントリなど)。エイジゲートはここで、一覧を書き換えることによって動作します。 - アーティファクト — 特定の1バージョンのダウンロード可能なファイル。npm の
.tgz、Python の wheel または sdist、.crate、.gem、.nupkg、Go モジュールの.zipなど。OSV 検索、socket.dev チェック、スクリプト除去、ハードブロックはすべてアーティファクト取得時に行われます。 - パススルー — それらのホスト上のその他すべて(検索、認証)。手を加えません。
すべてのパッケージ取得は、ポリシーに関係なく分類され、セキュリティ タイムラインに記録されます。チェック自体は有効にしたレイヤーについてのみ実行されます。VM 内でインストールや設定をする必要はありません。
メモ: npm や pip のローカルキャッシュにすでに存在するパッケージはネットワークに到達しないため、それらについては何もチェックされず、記録もされません。インストール中にタイムラインが静かなのは、単にすべてがキャッシュから来たことを意味する場合があります。
判定: 許可、書き換え、ブロック、保留
サプライチェーンレイヤーは個別のオン/オフトグルであり、それぞれ固定のアクションを持ちます。このペインにはグローバルなブロック/警告/許可モードはありません。(プロンプトインジェクション で見たことがあるかもしれない3方向のログ/確認/ブロックのラジオボタンや、ガードレール の強制モードは別のシステムです。)すべての取得は次の4つの結果のいずれかで終わります。
| 結果 | 何が起こるか | 表示されるマーカー |
|---|---|---|
| 許可 | レスポンスはそのまま通過します。 | セキュリティ タイムラインの緑の 確認 / ダウンロード 行。 |
| 書き換え | プロキシがレスポンスを変更しました。新しすぎるバージョンをメタデータから削除したか、tarball からインストールスクリプトを除去しました。パッケージマネージャーは通常どおり処理を続けます。 | X-Bromure-Rewritten: supply-chain レスポンスヘッダー。タイムラインの青い行。 |
| ブロック | ダウンロードは HTTP 451(「法的理由により利用不可」)レスポンスで拒否されます。 | X-Bromure-Block: supply-chain ヘッダー。タイムラインの赤い行。 |
| 同意のため保留 | ロックファイルにピン留めされたパススルー、有効な評価ソースが審査できなかったパッケージ、そして OSV または socket.dev がフラグを立てたパッケージ(ブロックされたパッケージを信頼する を参照)について、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 | Depi | スクリプト除去 |
|---|---|---|---|---|---|---|
| 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 と Depi
パッケージフィルタリング グループは、相互排他的なラジオボタンで評価プロバイダーを選択します。None、socket.dev、または Depi です。2つのプロバイダーは根本的に異なる方法で動作します。socket.dev はプロキシが取得を通す前に参照する事前検索であり、Depi は 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 チェックを組み合わせています。
Depi
Depi は Lupin & Holmes(landh.tech)によるドロップイン式のセキュアな npm レジストリで、事前審査済みのパッケージを提供します。パッケージを検索する代わりに、Bromure はすべての npm レジストリリクエスト(メタデータ、tarball、audit、registry.npmjs.org または *.npmjs.org 宛てのあらゆるもの)を、depi-npm-proxy.landh.tech:443 にある Depi の npm 互換フィルタリングレジストリに再ルーティングし、あなたのキーを Authorization: Bearer ヘッダーとして付加し、ゲストが送信した Authorization ヘッダーを取り除きます。Depi は packument 内の tarball URL を自身を指すように書き換えるため、それらの後続の取得もホスト側でキーが注入されます。
有効にするには、ラジオボタンで Depi を選択し、API キー: のセキュアフィールドにキーを貼り付けます(API キーを取得 で landh.tech が開きます)。フィールドが空の間は、オレンジ色の警告に API キーを入力してください — キーがないと Depi はオフのままです。 と表示されます。リダイレクトされた各リクエストはアプリのログに書き込まれます。
[depi] GET registry.npmjs.org/… → https://depi-npm-proxy.landh.tech
エラー処理は静かではなく明示的です。
- 401(キー拒否)。 Bromure は npm が表示する明確なプレーンテキストエラー(「Bromure: the Depi registry rejected the configured API key…」、ヘッダー
X-Bromure-Block: depi-auth付き)に置き換え、それをログに記録し、ワークスペースとキーの組み合わせごとに一度きりの GUI アラート「Depi rejected your API key」を表示します。ヘッドレスの SSH/TUI セッションでは GUI アラートは表示されず、ログ行と書き換えられた npm エラーに依存します。 - 403(Depi によりパッケージがブロックされた、またはキーがそれに対して認可されていない)。 ログに記録され、変更されずに通過するため、npm は Depi 自身の拒否テキストを報告します。
Depi は npm のみに影響します。他の7つのエコシステムはそれによって手を加えられません。Depi はラジオボタンで socket.dev を置き換えるものであり、あなたのローカルポリシーを置き換えるものではありません。エイジゲート、OSV チェック、スクリプト除去は Depi が提供するものに対してなお実行されます。
インストールスクリプトの除去
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)、そのフックが維持されます。
メモ: このプロキシレイヤーは、VM 内の npm 自身のインストールスクリプトポリシーとは別物です。最近の npm は
allow-scriptsリストにあるパッケージについてのみインストールスクリプトを実行するため、Bromure が各マシンで管理する~/.npmrcは、同梱するエージェント CLI —@anthropic-ai/claude-code、@openai/codex、@moonshot-ai/kimi-code、@oh-my-pi/pi-coding-agent— に限ってそれを許可しています。これにより、npm install -gで自身を更新するエージェントがネイティブバイナリを取得できます。それ以外のパッケージは npm のデフォルトに従います。ここでスクリプト除去をオンにする場合は、これらのパッケージも インストールスクリプトを許可 に追加してください。そうしないと、エージェントの自己更新でインストール手順が失われます。
このトグルはデフォルトでオフで、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 アーティファクトは決して変更されないためです。)
ブロックされたパッケージを信頼する
評判の判定が常にあなたにとって正しいとは限りません。socket.dev は workerd をインストールスクリプトのためにフラグ付けしますが、これは Cloudflare のランタイムで、あなたのプロジェクトに必要なことがあります。OSV または socket.dev がパッケージのダウンロードをブロックすると、黙って 451 を返す代わりにダウンロードを保留し、理由を示したうえで サプライチェーンの警告がありますが、ワークスペース「…」から … をインストールしますか? と尋ねます。選択肢は次のとおりです。
| 選択肢 | 効果 |
|---|---|
| このセッションでは … を許可 | アプリを終了するまで、そのパッケージとその他のバージョンをインストールします。 |
| このワークスペースで … を常に許可 | インストールし、ワークスペースの 信頼するパッケージ リストに追加します。リストに載っている間、以後のダウンロードではそのパッケージの OSV と socket.dev のチェックをスキップします。 |
| … を許可せず、このセッションではもう確認しない | 451 のままにします。アプリを終了するまで、同じインストールは再確認なしにブロックされたままです。 |
| 今はしない | ひとまず 451 のままにします。1 分後に再度尋ねます。応答がない場合はこれになります。 |
socket.dev の マルウェア 判定(マルウェア、既知のマルウェア、GPT が検出したマルウェア、荒らしパッケージ、侵害された SSH キー)は、上書きの選択肢が示されることもリストの対象になることもありません。これらのダウンロードは常にブロックされます。エイジゲートには独自の 除外パッケージ リストが、インストールスクリプトの除去には インストールスクリプトを許可 リストがあり、ここでパッケージを信頼しても、どちらからも除外されません。
後からパッケージを追加することもできます。セキュリティ タイムラインのブロックされた行には 許可… → このワークスペースで … を常に許可 があり、リスト自体は サプライチェーン ペインの 信頼するパッケージ にあります(形式 npm:workerd)。変更は実行中のマシンにすぐ反映されます。
同意プロンプトと付与
すべてのサプライチェーンのユーザー確認経路(ロックファイルのパススルーと、以下で説明する未検証パッケージの保留)は、バースト統合を備えた共有の同意ブローカーを経由します。同じスコープに対する並行リクエストは、アラートを積み重ねるのではなく、単一のダイアログを待ちます。ロックファイルのパススルーでは次の4つの決定を選べます(未検証パッケージの保留にはパッケージごとの独自の選択肢があります。オフラインおよび機能低下時の動作を参照)。
| 決定 | 効果 |
|---|---|
| 許可しない | 451 でブロックします。60秒間記憶され、即時の再試行を自動的に拒否します。 |
| 一度だけ許可 | この1つのリクエスト(または統合されたバースト)を通します。 |
| 15分間許可 | スコープを15分間付与します。 |
| セッションの残りの間許可 | アプリが終了するまでスコープを付与します。 |
アクティブな付与と拒否は、承認 UI(Window → Credential Approvals… エリア)に、ガードレールの決定とは別に サプライチェーンの決定 として一覧表示され、そこで付与を早期に取り消すことができます。付与はメモリ内のみで、アプリの再起動後は残りません。
リモートの SSH/CLI セッションでは GUI ダイアログはありません。同じ質問がマシンの tmux 内の選択肢として表示されます。応答がない場合は拒否となります。リモートアクセス を参照してください。
ポリシーの設定
サプライチェーンのポリシーはマシンごとに、マシンの設定の セキュリティ にある サプライチェーン ペインで設定します。フィールドごとの完全なリファレンスは サプライチェーン設定 にあります。デフォルトの概要は次のとおりです。
| 設定 | デフォルト |
|---|---|
| カットオフより新しいパッケージを拒否(エイジゲート) | オン、最低経過日数: 2日、除外なし |
| api.osv.dev でパッケージを検索する(無料、キー不要) | オフ、ブロックする深刻度: 高以上 |
| パッケージフィルタリング | None(socket.dev または Depi キーなし) |
| 侵害されたパッケージをブロック / 既知の 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はキーが入力されているがどちらのブロックも有効になっていないことを意味し、depi=selected-but-no-keyは Depi が選択されているがキーがないためオフであることを意味します。 -
保存場所。 ポリシーはワークスペースの
profile.json(~/Library/Application Support/BromureAC/profiles/<id>/の下)に存在します(デフォルト以外のフィールドのみが書き込まれます)。socket.dev と Depi の API キーもそこに保存されます。ホスト側のみで、UI ではセキュアフィールドとして表示され、VM にコピーされることは決してありません。サプライチェーン固有の環境変数や起動引数はありません。 -
リモート設定。 SSH/TUI リモートメニューは、同じフィールドを持つ同じ サプライチェーン ペインを公開するため、ヘッドレスインスタンスを GUI なしで設定できます。リモートアクセス を参照してください。
セキュリティ タイムラインでインストールを確認する
サプライチェーンパイプラインが判断したことはすべて セキュリティ タイムライン で確認できます。ウインドウ → セキュリティ… を開くか、⌘K で検索します。概要 タブの 確認したパッケージ タイルは過去 24 時間のパッケージ取得を数えます。これをクリックするか、タイムライン タブのエンジンフィルタで サプライチェーン を選ぶと、1 行ずつ表示されます。
各行は 内容 列でパッケージを示し(npm · [email protected])、判定 列で何が起きたかを色分けして示します。
| 判定 | 色 | 意味 |
|---|---|---|
| 確認 | 緑 | パッケージのバージョン一覧が取得され、通過しました。 |
| ダウンロード | 緑 | パッケージのアーティファクトが取得され、通過しました。 |
| 確認 — 待機期間より新しいバージョンを非表示 | 青 | エイジゲートがバージョン一覧を書き換えました。これはゲートが通常の仕事をしているだけで、ブロックではありません。 |
| インストールスクリプトを除去 | 青 | npm tarball からインストールフックが除去されました。 |
| ブロック — … | 赤 | 取得は 451 で拒否されました。理由はダッシュの後に続きます(例: ブロック — 既知のマルウェア)。上書きできるブロックには、行末に 許可… ボタンがあります。 |
| ダウンロード済み — 次の警告がありますが、あなたが許可しました: … | 青 | OSV または socket.dev がフラグを立てたが、あなたが許可したため(プロンプト、または 信頼するパッケージ)インストールされたパッケージ。 |
パッケージ取得は、サプライチェーンのレイヤーがオンかどうかにかかわらず 常に 記録されます。強制はポリシーに従いますが、記録は従いません。apt のインストールも記録されます。Ubuntu または Debian のアーカイブプールから取得された .deb はそれぞれ apt 行として表示されます。これらは観測されるだけで、この章のチェックはどれも適用されません。
実際に動作を確認するには、タイムラインを開き、セッション内で任意のインストール(npm install、pip install、cargo add、gem install、apt install など)を実行して、行が届くのを見てください。イベントはディスク上に 90 日間保存され、アプリを再起動しても残ります。クリア はウィンドウから現在の行を隠すだけです。書き出す… はタブに表示されている内容を CSV ファイルとして保存します。
メモ: タイムラインが記録するのは判定であり、すべての手順ではありません。パイプラインの詳細な行 — 各外向き検索、「policy engaged」の要約、Depi のリダイレクト、API エラー — は
~/Library/Logs/BromureAC/bromure-ac.logのアプリのログに出力されます(ターミナルから起動した場合はアプリの stderr にも出力されます)。
オフラインおよび機能低下時の動作
パイプラインの評価チェックは、あなたの Mac からの外向きの呼び出し(VM からではない)に依存します。OSV には api.osv.dev、socket.dev には api.socket.dev、PyPI 公開時刻バックストップには pypi.org、Depi には depi-npm-proxy.landh.tech です。有効なソースが判定を出せない場合(再試行後のネットワークダウン、HTTP エラー、レート制限、認証失敗、サポートされていないエコシステム)、Bromure は静かに許可するのではなく fail closed します。
ダウンロードは一時停止し、未検証パッケージの保留 が ワークスペース「…」の パッケージ バージョン を評判チェックなしでインストールしますか? というタイトルのパネルで尋ねます。パネルには判定がない理由が示されます。socket.dev が応答しなかった、API キーを拒否した(ワークスペースの サプライチェーン 設定で確認してください)、キーのレートを制限している、そのバージョンの解析をまだ終えていない、あるいはそのバージョンを認識していない(公開されたばかりの可能性があります)のいずれかです。あわせて、インストールすると、設定された評価ソースに対してチェックされていないパッケージを受け入れることになる、と説明されます。選択肢は次のとおりです。
- パッケージ バージョン を許可 — このバージョンがインストールされ、セッションの残りの間は再び尋ねられません。
- 未検証のパッケージを 15 分間すべて許可 — このパッケージに加え、今後 15 分間に判定が得られないワークスペースの他のすべてのパッケージ。
- このセッションの間は未検証のパッケージを許可しない — このパッケージとそれ以降のすべてが、尋ねられることなく拒否されます。
- パッケージ バージョン を許可しない — 拒否されます(451 で)。カウントダウンが終わるまで回答がない場合、Esc、パネルを閉じた場合も同じ扱いです。
画面に出る質問はワークスペースごとに一度に 1 つです。uv sync や npm install が複数の未検証パッケージに当たると、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など)、認証情報の名前、発行対象のホスト、送信先として観測されたホストです。
アラートには4つの対応が用意されています。
- シャットダウン(デフォルト)— VM を停止し、マシンを侵害済みとしてマークします。
- ブロック — このリクエストだけを止めて VM を再開します。エージェントが再試行すると検出器が再び発動します。
- 許可 — このセッションの残りの間、観測されたホストを信頼します。認証情報が差し替えられてそこへ送信され、そのホストへのリクエストはフラグ付けされなくなります。見覚えのある送信先にのみ使用してください。
- 調査用に保存 — フォルダを選ぶと、Bromure は
disk.img(VM システムディスクのコピー)、home.tar.gz(マシンのホームディレクトリ)、各共有フォルダのshares/<name>.tar.gzをエクスポートし、その後シャットダウンしてマシンを侵害済みとしてマークします。RAM の状態は破棄されます。
Return キーに反応するのは シャットダウン だけで、他の3つは明示的なクリックが必要です。マシンをミラーしているリモートクライアントには シャットダウン、ブロック、許可 が表示されます。許可 の背後にあるセッションごとの許可リストを含む詳しい説明は、認証情報 にあります。
侵害済みとしてマークされたマシンは、明示的にワイプするまで再起動を拒否します。ワイプのフローでは、共有フォルダはワイプ されない ことが警告されます。共有フォルダには汚染されたファイルが残っている可能性があるため、手作業で確認してください。
ホストスコープを宣言している認証情報については、検出は常にオンです。ホストが固定されていない手動の認証情報(「任意のホスト」)が検出を発動させることはなく、Claude/Codex のトークンは同じ登録ドメインでの緩和された照合を使用します(api.anthropic.com 向けに発行されたトークンが別の anthropic.com ホストで見られてもアラームにはなりません)。一度に表示されるアラートは1つだけで、表示中に繰り返し発生したイベントは破棄されます。マシンは、ガードレールペインの 認証情報の流出時に警告しない でアラートと一時停止を抑制できます。その場合でも漏洩はブロックされ、セキュリティ タイムラインには赤い 資格情報ブローカー 行として表示されます(回避策 を参照)。
エンタープライズの可視性
bromure.io に登録された Mac 上のマシンでは、すべてのメタデータおよびアーティファクトの取得が、エンタープライズイベントストリームに supply_chain.fetch イベントも発行します。これにはエコシステム、パッケージ、バージョン、リクエスト種別、結果(allowed、rewritten、blocked、または stripped)、理由種別(age_gate、osv、socket_compromised、socket_cve、verify_unavailable、lockfile_denied、scripts_stripped)が含まれます。登録するだけで、管理者は組織全体のパッケージダウンロードの可視性(すべてのエージェントがインストールしたすべてのもののインベントリ)を得られます。これはすべての強制レイヤーがオフになっているマシンでもです。
登録の仕組みと、管理者が反対側で何を見るかは、エンタープライズ で説明します。