View a markdown version of this page

Pakete auf der Versionsseite anordnen - CodeArtifact

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Pakete auf der Versionsseite anordnen

Wichtig

Die Änderung des Versionsalters schützt nicht vor Sicherheitslücken, die in vorhandenen Versionen entdeckt wurden, die das Quarantänefenster bereits überschritten haben. Verwenden Sie es CodeArtifact zusammen mit Amazon Inspector für das Scannen von Sicherheitslücken etablierter Pakete.

Wenn eine Paketversion in einer öffentlichen Registrierung veröffentlicht wird, zeichnet die Registrierung den Veröffentlichungszeitstempel auf. CodeArtifact behält diese ursprünglichen Upstream-Zeitstempel bei, wenn Pakete von externen Verbindungen zwischengespeichert werden. Sie können diese Zeitstempel in Ihrer CI/CD Pipeline lesen und Versionen ablehnen, die zu kürzlich veröffentlicht wurden.

Die meisten bösartigen Pakete werden innerhalb weniger Stunden nach der Veröffentlichung erkannt und entfernt. Ein Quarantänefenster von 3 bis 7 Tagen verhindert die meisten Angriffe auf die Lieferkette, darunter Verwirrung bei Abhängigkeiten, Übernahme von Benutzerkonten und Typosquatting.

Anmerkung

In den Beispielen in diesem Thema wird die CodeArtifact Repository-URL abgefragt. Dabei handelt es sich um denselben Endpunkt, den Ihr Paketmanager zum Herunterladen von Paketen verwendet. Alle Anfragen erfordern eine Authentifizierung. Übergeben Sie ein gültiges CodeArtifact Autorisierungstoken im Authorization: Bearer Header. Um ein Token abzurufen, führen Sie den Befehl aus aws codeartifact get-authorization-token (den vollständigen Aufruf mit --domain und finden Sie im CI/CD Beispiel weiter unten in diesem Thema--domain-owner).

Verwenden Sie das von zurückgegebene publishedTime Feld nicht aws codeartifact describe-package-version für die Altersfreigabe. Dieses Feld wird zum Zeitpunkt der Aufnahme ausgefüllt. Bei Datensätzen, bei denen der ursprüngliche Upstream-Veröffentlichungszeitpunkt nicht erfasst wurde (einschließlich Paketen, die vor der Erfassung von Zeitstempeln pro Artefakt aufgenommen wurden, und bestimmter Aufnahmepfade), wird automatisch auf den Zeitpunkt der letzten Aktualisierung des Datensatzes zurückgegriffen. Die API-Antwort gibt nicht an, welchen der beiden Werte Sie gerade lesen, sodass Sie sich nicht darauf verlassen können, dass es sich um das Upstream-Veröffentlichungsdatum handelt. Verwenden Sie stattdessen die in diesem Thema beschriebenen formatspezifischen Felder.

Die Angaben pro Format sind unterschiedlich, aber das Gating-Muster ist für jedes Format gleich: Lesen Sie den Upstream-Veröffentlichungszeitstempel für jede aufgelöste Version, vergleichen Sie ihn mit Ihrem Quarantäne-Cutoff (der aktuellen Uhrzeit minus dem von Ihnen ausgewählten Fenster) und schlagen Sie den Build fehl, falls eine Version neuer als der Grenzwert ist. Wenn Sie mehr als ein Paketformat verwenden, wenden Sie dasselbe Muster auf das unten gezeigte formatspezifische Feld an.

NPM

CodeArtifact gibt den ursprünglichen Veröffentlichungszeitstempel von npmjs.org für jede Version im Feld npm-Paket zurück. time Viele Paketmanager und Sicherheitstools lesen dieses Feld nativ. Dazu gehören die npmMinimalAgeGate Option Yarn 4, die minimumReleaseAge Renovate-Einstellung und die minimumReleaseAge pnpm-Einstellung, die alle ohne Änderungen funktionieren. CodeArtifact

Anfrage:

curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/npm/my-repo/axios

Antwort (abgekürzt):

{ "name": "axios", "time": { "1.6.0": "2023-10-26T21:15:55.685Z", "1.6.5": "2024-01-05T19:52:15.051Z", "1.7.0": "2024-05-19T20:25:03.615Z", "1.7.1": "2024-05-20T13:32:52.757Z", "1.7.2": "2024-05-21T16:58:04.163Z" } }

Schlüsselfeld: time["<version>"] — Der Wert ist das ursprüngliche Veröffentlichungsdatum von npmjs.org. Gibt beispielsweise den genauen Zeitstempel time["1.7.2"] zurück2024-05-21T16:58:04.163Z, der von npmjs.org aufgezeichnet wurde, als diese Version veröffentlicht wurde. Um das Alter zu ermitteln, vergleichen Sie diesen Wert mit der aktuellen Uhrzeit abzüglich Ihres Quarantänefensters.

Maven

CodeArtifact Gibt bei Maven-Artefakten den ursprünglichen Veröffentlichungszeitstempel von Maven Central im Last-Modified HTTP-Antwort-Header zurück, wenn Sie eine Datei herunterladen (JAR, POM oder ein anderes Artefakt).

Anfrage:

curl -I -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/maven/my-repo/\ org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.pom

Antwort-Header:

HTTP/2 200 content-type: application/xml Last-Modified: Fri, 26 Feb 2021 20:40:52 GMT content-length: 22672

Schlüsselfeld: Last-Modified Header — Dies ist das ursprüngliche Veröffentlichungsdatum von Maven Central. Vergleichen Sie es mit Ihrem Quarantänegrenzwert, um festzustellen, ob das Artefakt zu neu ist.

Anmerkung

Das darin <lastUpdated> enthaltene Feld maven-metadata.xml gibt an, wann der Cache CodeArtifact zuletzt aktualisiert wurde, nicht das Veröffentlichungsdatum im Upstream. Verwenden Sie keine maven-metadata.xml Zeitstempel für die Altersfreigabe.

NuGet

CodeArtifact Gibt bei NuGet Paketen den ursprünglichen Veröffentlichungszeitstempel von nuget.org in das published Feld der Antwort auf die V3-Registrierung zurück.

Anfrage:

curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/nuget/my-repo/\ v3/registration4/newtonsoft.json/index.json

Antwort (abgekürzt, zeigt eine Version):

{ "items": [{ "items": [{ "catalogEntry": { "id": "Newtonsoft.Json", "version": "13.0.3", "published": "2023-03-08T07:42:54.647+00:00", "listed": true } }] }] }

Schlüsselfeld: catalogEntry.published — Dies ist das ursprüngliche Veröffentlichungsdatum von nuget.org. "2023-03-08T07:42:54.647+00:00"Bedeutet zum Beispiel, dass Newtonsoft.Json 13.0.3 am 8. März 2023 veröffentlicht wurde.

Fracht (Rust)

Für Frachtkisten, die aus crates.io abgerufen wurden, wird der ursprüngliche Veröffentlichungszeitstempel in der crates.io V1-API-Antwort CodeArtifact beibehalten. versions Fragen Sie den V1-API-Endpunkt nach einer Kiste ab, um den Zeitstempel pro Version zu lesen. created_at

Anfrage:

curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/cargo/my-repo/\ api/v1/crates/serde/versions

Schlüsselfeld: Der created_at Zeitstempel pro Version in der versions V1-Antwort ist das ursprüngliche Veröffentlichungsdatum von crates.io.

Anmerkung

Cargo verwendet das Sparse Index Protocol () <prefix>/<crate> für die normale Auflösung von Abhängigkeiten. Der Sparse-Index gibt features für jede Version vers cksumyanked,, und zurück, enthält jedoch keinen Veröffentlichungszeitstempel. Um die Abhängigkeiten von Cargo nach Alter abzugrenzen, fragen Sie die oben gezeigte V1-API in einem separaten Schritt in Ihrer Pipeline ab. Der Standard cargo build und die cargo update Befehle rufen die V1-API nicht auf.

PyPI

CodeArtifact Unterstützt für Python-Pakete PEP 691 (JSON Simple API) und PEP 700, die das upload-time Feld für jede Distributionsdatei enthalten.

Anfrage:

curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ -H "Accept: application/vnd.pypi.simple.v1+json" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/pypi/my-repo/simple/requests/

Antwort (abgekürzt):

{ "files": [{ "filename": "requests-2.31.0-py3-none-any.whl", "upload-time": "2023-05-22T15:12:42.313790Z", "size": 62574, "url": "../../packages/requests/2.31.0/requests-2.31.0-py3-none-any.whl" }] }

Schlüsselfeld: upload-time — Dies ist das ursprüngliche Veröffentlichungsdatum von PyPI. Tools wie uv unterstützen dies nativ:

# Only install versions published before a specific date uv pip install --exclude-newer 2026-05-01T00:00:00Z -r requirements.txt
Anmerkung

Die PEP 691 JSON-API benötigt den Header. Accept: application/vnd.pypi.simple.v1+json Die standardmäßige HTML Simple API enthält keine Zeitstempel.

Bei Distributionsdateien, die vor der Einführung der Erfassung pro Artefakt während des Uploads aufgenommen wurden (ältere Datensätze), fehlt das upload-time Feld möglicherweise in den Einträgen in. files[] Ihre Gating-Logik sollte eine fehlende Version upload-time als eine Version behandeln, die nicht verifiziert werden kann, und entscheiden, ob sie gemäß Ihrer Richtlinie zugelassen oder blockiert werden soll.

Beispiel: Gating von NPM-Paketen in CI/CD

Das folgende Python-Skript liest eine package-lock.json Datei, fragt CodeArtifact den Veröffentlichungszeitstempel jeder Abhängigkeit ab und wird mit einem Status ungleich Null beendet, wenn eine Version innerhalb des Quarantänefensters veröffentlicht wurde.

#!/usr/bin/env python3 """ gate_package_age.py - Block npm packages published too recently. Reads package-lock.json, queries CodeArtifact for each dependency's publish timestamp, and rejects versions newer than QUARANTINE_HOURS. Environment variables: CODEARTIFACT_AUTH_TOKEN - from `aws codeartifact get-authorization-token` CODEARTIFACT_NPM_ENDPOINT - from `aws codeartifact get-repository-endpoint` QUARANTINE_HOURS - minimum version age in hours (default: 72) """ import json, os, sys, urllib.request from datetime import datetime, timezone, timedelta def get_publish_time(endpoint, token, package, version): """Fetch the publish timestamp for a specific version from CodeArtifact.""" url = f"{endpoint.rstrip('/')}/{package}" req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"}) data = json.loads(urllib.request.urlopen(req, timeout=30).read()) time_str = data.get("time", {}).get(version) if not time_str: return None return datetime.fromisoformat(time_str.replace("Z", "+00:00")) token = os.environ["CODEARTIFACT_AUTH_TOKEN"] endpoint = os.environ["CODEARTIFACT_NPM_ENDPOINT"] quarantine_hours = int(os.environ.get("QUARANTINE_HOURS", "72")) cutoff = datetime.now(timezone.utc) - timedelta(hours=quarantine_hours) with open("package-lock.json") as f: lockfile = json.load(f) blocked = [] checked = 0 for path, info in lockfile.get("packages", {}).items(): if not path.startswith("node_modules/"): continue name = path.replace("node_modules/", "", 1) version = info.get("version") if not name or not version: continue checked += 1 pub_time = get_publish_time(endpoint, token, name, version) if pub_time and pub_time > cutoff: age_h = (datetime.now(timezone.utc) - pub_time).total_seconds() / 3600 blocked.append(f" {name}@{version} (age: {age_h:.0f}h, published {pub_time.isoformat()})") if blocked: print(f"BLOCKED: {len(blocked)} package(s) newer than {quarantine_hours} hours:") print("\n".join(blocked)) sys.exit(1) print(f"PASSED: all {checked} packages older than {quarantine_hours} hours.")

CI/CD Integration:

# Step 1: Authenticate export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \ --domain my-domain --domain-owner 111122223333 \ --query authorizationToken --output text) export CODEARTIFACT_NPM_ENDPOINT=$(aws codeartifact get-repository-endpoint \ --domain my-domain --domain-owner 111122223333 \ --repository my-repo --format npm \ --query repositoryEndpoint --output text) # Step 2: Set quarantine window (72 hours = 3 days) export QUARANTINE_HOURS=72 # Step 3: Generate lockfile without installing npm install --package-lock-only # Step 4: Gate on age — fails if any dependency is too new python3 gate_package_age.py # Step 5: If gate passes, install npm ci

Beispielausgabe, wenn ein Paket blockiert ist:

BLOCKED: 1 package(s) newer than 72 hours: evil-package@1.0.0 (age: 2h, published 2026-06-03T08:30:00+00:00)

Beispielausgabe, wenn alle Pakete erfolgreich sind:

PASSED: all 847 packages older than 72 hours.

Angriffe abgemildert

Angriffstyp Funktionsweise Wie Age Gating hilft
Abhängigkeit, Verwirrung Der Angreifer veröffentlicht ein Hochversionspaket mit demselben Namen wie ein internes Paket in einer öffentlichen Registrierung. Die bösartige Version ist brandneu. Durch das Quarantänefenster blockiert.
Kontoübernahme Der Angreifer kompromittiert die Anmeldeinformationen eines Maintainers und veröffentlicht ein bösartiges Update (z. B. Event-Stream). Die neue Version wird gespeichert. Die Community erkennt es und macht es innerhalb der Quarantänezeit rückgängig.
Typosquatting Der Angreifer veröffentlicht ein Paket mit einem Namen, der einem beliebten Paket ähnelt (z. B. lodashs anstelle von). lodash Alle Versionen des Typosquat-Pakets sind neu. Jede Version ist blockiert.
Star-jacking Ein Angreifer injiziert Schadsoftware in eine Patch-Version eines legitimen Pakets, das er kontrolliert. Bei dem bösartigen Patch handelt es sich um eine neu veröffentlichte Version. Blockiert, bis das Quarantänefenster überschritten ist.

Zusammenfassung der unterstützten Formate

Format Wo kann ich den Zeitstempel für die Veröffentlichung lesen Schlüsselfeld Status
NPM Antwort auf das Paket () GET /<package> time["<version>"] Available (Verfügbar)
Maven HTTP-Antwort-Header beim Herunterladen von Artefakten Last-Modified Available (Verfügbar)
NuGet V3-Registrierungsindex catalogEntry.published Available (Verfügbar)
Fracht Antwort auf die V1-API-Versionen created_at Available (Verfügbar)
PyPI PEP 691 JSON Einfache API upload-time Available (Verfügbar)