Gateway は、7 つの主要なパッケージエコシステムでソフトウェアパッケージのダウンロードを検出し、サプライチェーンのトラフィックをポリシーで制御できます。開発者または CI/CD パイプラインが Gateway 経由でパッケージをダウンロードすると、プロキシはリクエスト URL からレジストリプロトコルを識別し、パッケージのエコシステム、名前、バージョン、名前空間を抽出します。その後、pkg.* セレクターを使った HTTP ポリシーを書き、エコシステム全体のブロックから単一パッケージバージョンの制限まで、必要な粒度でパッケージダウンロードを許可またはブロックできます。
パッケージ検出は、HTTP リクエストの URL 構造だけを使います。Gateway が認識するのは、トラフィックを配信しているホスト名ではなく、対応する各レジストリプロトコルの API 契約です。そのため、公式のパブリックレジストリ、セルフホストのミラー、Artifactory や Nexus などの社内プロキシレジストリ、その他の互換エンドポイントのいずれへ向かうトラフィックでも、検出の動作は同じです。URL パスが既知のレジストリダウンロードの形に一致すれば、Gateway はそれを分類します。
検出はフェイルオープンです。URL をパッケージダウンロードとして分類できない場合、リクエストは通常の非パッケージトラフィックとしてそのまま進みます。分類の失敗が、パッケージインストールをブロックしたり壊したりすることはありません。
Gateway は、次のエコシステムのパッケージダウンロードを検出します。
| Ecosystem | Example artifact pattern | Namespace |
|---|---|---|
| npm | /{package}/-/{package}-{version}.tgz |
スコープ(例: @babel) |
| PyPI | /packages/{hash}/{hash}/{hash}/{package}-{version}.whl |
— |
| RubyGems | /gems/{package}-{version}.gem |
— |
| Cargo | /crates/{package}/{package}-{version}.crate |
— |
| Go | /{module}/@v/{version}.zip |
モジュールパス |
| Maven | /maven2/{group}/{artifact}/{version}/{artifact}-{version}.jar |
Group ID |
| NuGet | /{package}/{version}/{package}.{version}.nupkg |
— |
最初のリリースでは、download 操作だけを検出します。download は、対応するすべてのレジストリで、パッケージ名、バージョン、エコシステムを URL パスから導ける唯一の操作です。resolve(メタデータの参照)や publish など、ほかの操作は、URL パス以外の追加シグナルが必要な、別のエンドポイント、ホスト、HTTP メソッドを使います。
次のセレクターは、Allow および Block アクションの HTTP ポリシー で使えます。
| Selector | UI name | API example | Description |
|---|---|---|---|
pkg.ecosystem |
Package Ecosystem | pkg.ecosystem == "npm" |
リクエスト URL から検出したパッケージエコシステムです。 |
pkg.name |
Package Name | pkg.name == "lodash" |
ダウンロード URL から抽出したパッケージ名です。 |
pkg.version |
Package Version | pkg.version == "4.17.21" |
ダウンロード URL から抽出したパッケージバージョンです。完全一致と、エコシステム固有の比較演算子に対応します。 |
pkg.namespace |
Package Namespace | pkg.namespace == "@babel" |
パッケージの名前空間です。エコシステムが名前空間に対応している場合に使えます。npm ではスコープ、Maven では Group ID、Go ではモジュールパスです。 |
pkg.purl |
Package URL | pkg.purl == "pkg:npm/lodash@4.17.21" |
検出した座標から導いた Package URL(PURL) ↗ です。API でのみ利用できます。 |
ダッシュボードでは、Package Ecosystem が主要なセレクターです。これを選ぶと、パッケージ名、バージョン、名前空間を指定する入れ子フィールドが表示されます。次のルールが適用されます。
- ほかのパッケージフィールドを使う前に、エコシステムを選ぶ必要があります。
- 入れ子フィールドを有効にするには、エコシステムをちょうど 1 つ選ぶ必要があります。
inまたはnot in演算子で複数のエコシステムに一致させると、入れ子のパッケージ名、バージョン、名前空間フィールドは無効になります。 - バージョン制約を追加する前に、パッケージ名を追加する必要があります。
- 名前空間フィールドは、名前空間に対応しているエコシステムだけで使えます。ラベルは選んだエコシステムに応じて変わります。npm では Scope、Maven では Group ID、Go では Module namespace です。
pkg.purl(Package URL)セレクターはダッシュボードでは使えません。PURL で一致させる式は API で書いてください。
API を直接使う場合、これらの制約なしに、wirefilter 式でセレクターを自由に組み合わせられます。
pkg.version セレクターは、完全な文字列一致に加えて、エコシステム固有の比較演算子に対応しています。各エコシステムは、それぞれのネイティブなバージョニング意味論を使います。
| Ecosystem | Versioning standard |
|---|---|
| npm | SemVer |
| Cargo | SemVer |
| PyPI | PEP 440 |
| RubyGems | Gem::Version |
| Go | Go module versions |
| Maven | Maven version ordering |
| NuGet | NuGet normalization and ordering |
次の比較演算子に対応しています。
| Operator | API syntax | Description |
|---|---|---|
| equals | == |
エコシステム固有の同一性ルールを使った正規化後の等価比較です。 |
| not equals | != |
正規化後の等価比較の否定です。 |
| greater than | > |
ネイティブな順序で、指定した値より大きいバージョンです。 |
| greater than or equal | >= |
指定した値以上のバージョンです。 |
| less than | < |
ネイティブな順序で、指定した値より小さいバージョンです。 |
| less than or equal | <= |
指定した値以下のバージョンです。 |
バージョン文字列をエコシステムのバージョニングルールで解析できない場合、または検出したエコシステムが比較のコンテキストと一致しない場合、比較は不一致になります。これには != も含まれます。解析できないバージョンは、何にも一致しません。
組織全体で PyPI パッケージのダウンロードをブロックするには:
| Selector | Operator | Value | Action |
|---|---|---|---|
| Package Ecosystem | is | pypi |
Block |
wirefilter 式:
pkg.ecosystem == "pypi"バージョンに関係なく、既知の悪意のある、または不要な npm パッケージをブロックするには:
| Selector | Operator | Value | Logic | Action |
|---|---|---|---|---|
| Package Ecosystem | is | npm |
And | Block |
| Package Name | is | event-stream |
wirefilter 式:
pkg.ecosystem == "npm" and pkg.name == "event-stream"CVE-2021-23337 を修正したバージョンである 4.17.21 より前の lodash をすべてブロックするには:
| Selector | Operator | Value | Logic | Action |
|---|---|---|---|---|
| Package Ecosystem | is | npm |
And | Block |
| Package Name | is | lodash |
And | |
| Package Version | less than | 4.17.21 |
wirefilter 式:
pkg.ecosystem == "npm" and pkg.name == "lodash" and pkg.version < "4.17.21"社内の Artifactory インスタンス経由の npm パッケージダウンロードだけを許可し、ほかの npm ダウンロードをすべてブロックするには、2 つのポリシーを作成します。
ポリシー 1 - 承認したミラーを許可する(優先度を高くする):
| Selector | Operator | Value | Logic | Action |
|---|---|---|---|---|
| Package Ecosystem | is | npm |
And | Allow |
| Host | is | npm.internal.example.com |
wirefilter 式:
pkg.ecosystem == "npm" and http.request.host == "npm.internal.example.com"ポリシー 2 - その他の npm ダウンロードをすべてブロックする(優先度を低くする):
| Selector | Operator | Value | Action |
|---|---|---|---|
| Package Ecosystem | is | npm |
Block |
wirefilter 式:
pkg.ecosystem == "npm"検出はホスト名ではなくレジストリプロトコルに基づくため、パブリックの registry.npmjs.org と社内ミラーの npm.internal.example.com の両方が npm トラフィックとして検出されます。ポリシー 1(優先度が高い)が承認したミラーを許可し、ポリシー 2 がその他をすべてブロックします。
社内レジストリ経由でのみ機密の内部パッケージのダウンロードを許可し、ほかのすべてのソースからはブロックするには:
ポリシー 1 - 承認したホストからのダウンロードを許可する(優先度を高くする):
| Selector | Operator | Value | Logic | Action |
|---|---|---|---|---|
| Package Ecosystem | is | npm |
And | Allow |
| Package Namespace | is | @acme |
And | |
| Package Name | is | internal-sdk |
And | |
| Host | is | npm.internal.example.com |
wirefilter 式:
pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk" and http.request.host == "npm.internal.example.com"ポリシー 2 - その他のホストからのダウンロードをブロックする(優先度を低くする):
| Selector | Operator | Value | Logic | Action |
|---|---|---|---|---|
| Package Ecosystem | is | npm |
And | Block |
| Package Namespace | is | @acme |
And | |
| Package Name | is | internal-sdk |
wirefilter 式:
pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk"パッケージ検出は、各レジストリのダウンロード API の URL パス構造に基づいてトラフィックを分類します。既知のレジストリホスト名のリストとの照合には依存しません。この設計により、互換性のある URL レイアウトでパッケージを配信するサーバーは、次のいずれであっても同じように検出されます。
- 公式のパブリックレジストリ(例:
registry.npmjs.orgまたはpypi.org) - JFrog Artifactory、Sonatype Nexus、AWS CodeArtifact などの社内プロキシレジストリ
- セルフホストのミラー
- CDN の前段にあるレジストリエンドポイント
特定のレジストリホストを区別する必要があるポリシーでは、これまでどおり http.request.host セレクターを使えます。pkg.* セレクターと http.request.host を組み合わせると、パッケージの取得元に応じて異なるアクションを取るルールを書けます。
Gateway がパッケージダウンロードを検出すると、パッケージのメタデータが Gateway HTTP ログに含まれます。このデータは Gateway アクティビティログ と Logpush で利用できます。
Gateway Activity Log では、次のパッケージフィールドを利用できます。
| Field | Description |
|---|---|
| Package Ecosystem | 検出したレジストリの種類です(例: npm、pypi、cargo)。 |
| Package URL (PURL) | 検出した座標から導いた Package URL 文字列です(例: pkg:npm/lodash@4.17.21)。 |
パッケージのメタデータは、gateway_http Logpush データセットの PackageInfo オブジェクトで利用できます。
| Field | Type | Description |
|---|---|---|
PackageInfo.Ecosystem |
string |
検出したパッケージエコシステムです。 |
PackageInfo.Namespace |
string |
パッケージの名前空間です。該当する場合のみです。 |
PackageInfo.Name |
string |
パッケージ名です。 |
PackageInfo.Version |
string |
パッケージのバージョン文字列です。 |
PackageInfo.Purl |
string |
Package URL 文字列です。 |
- パッケージ検出には TLS 復号 をオンにする必要があります。Do Not Inspect ポリシーや 検査制限の一覧 のアプリケーションにより TLS 検査をバイパスする接続でダウンロードされたパッケージは検出されません。
- 一部の言語ランタイムと HTTP クライアントは、オペレーティングシステムとは別の証明書トラストストアを持っています。検査に使う証明書(Cloudflare 管理証明書など)が OS のトラストストアにだけインストールされている場合、これらのクライアントからのパッケージダウンロードは証明書検証エラーで失敗することがあります。Python、Node.js、Ruby、Rust、Java、Go を含む、アプリケーション固有のトラストストアへの証明書追加手順は、証明書を手動でインストールする を参照してください。
- 検出されるのは download 操作だけです。メタデータの参照(resolve)、パッケージの公開、その他のレジストリ操作は分類されません。
- バージョン比較は、各エコシステムのネイティブな順序ルールを使います。エコシステムをまたぐバージョン比較には対応していません。
- エコシステム固有の範囲構文(npm の
^1.2.3、PyPI の~=1.4、Maven の区間記法など)には対応していません。代わりに個別の比較演算子(>、<、>=、<=)を使ってください。