Adapt doc

This commit is contained in:
Reinier Criel 2026-03-19 16:07:31 -07:00
parent 2f4268f1af
commit 07e315a382
5 changed files with 18 additions and 8 deletions

View file

@ -113,7 +113,12 @@ The Aikido Safe Chain works by running a lightweight proxy server that intercept
### Minimum package age (npm only)
For npm packages, Safe Chain temporarily suppresses packages published within the last 24 hours (by default) until they have been validated against malware. This provides an additional security layer during the critical period when newly published packages are most vulnerable to containing undetected threats. You can configure this threshold or bypass this protection entirely - see the [Minimum Package Age Configuration](#minimum-package-age) section below.
For npm packages, Safe Chain applies minimum package age checks in two ways:
- During normal package resolution, Safe Chain suppresses versions that are newer than the configured minimum age from the package metadata returned by the registry.
- For direct package download requests that bypass that metadata flow, Safe Chain can block the request itself using a cached list of newly released packages.
By default, the minimum package age is 24 hours. This provides an additional security layer during the critical period when newly published packages are most vulnerable to containing undetected threats. You can configure this threshold or bypass this protection entirely - see the [Minimum Package Age Configuration](#minimum-package-age) section below.
⚠️ This feature **only applies to npm-based package managers** (npm, npx, yarn, pnpm, pnpx, bun, bunx) and does not apply to Python package managers (uv, pip, pip3, poetry, pipx).
@ -185,6 +190,11 @@ You can set the logging level through multiple sources (in order of priority):
You can configure how long packages must exist before Safe Chain allows their installation. By default, packages must be at least 24 hours old before they can be installed through npm-based package managers.
For npm-based package managers, this check currently has two enforcement modes:
- Safe Chain suppresses too-young versions from package metadata during normal dependency resolution.
- Safe Chain blocks direct package download requests when they are matched against the cached newly released packages list.
### Configuration Options
You can set the minimum package age through multiple sources (in order of priority):

View file

@ -85,7 +85,7 @@ export async function main(args) {
ui.writeInformation(
`${chalk.yellow(
"",
)} Safe-chain: Some package versions were suppressed due to minimum age requirement.`,
)} Safe-chain: Some package versions were suppressed during package metadata resolution due to minimum package age.`,
);
ui.writeInformation(
` To disable this check, use: ${chalk.cyan(

View file

@ -232,7 +232,7 @@ function verifyNoMinimumAgeBlockedRequests() {
ui.writeInformation(
`Safe-chain: ${chalk.bold(
`blocked ${state.blockedMinimumAgeRequests.length} package downloads due to minimum age`
`blocked ${state.blockedMinimumAgeRequests.length} direct package download request(s) due to minimum package age`
)}:`
);
@ -248,7 +248,7 @@ function verifyNoMinimumAgeBlockedRequests() {
ui.emptyLine();
ui.writeError(
"Safe-chain: Exiting without installing packages blocked by minimum age."
"Safe-chain: Exiting without installing packages blocked by the direct download minimum package age check."
);
ui.emptyLine();

View file

@ -51,7 +51,7 @@ export async function openNewPackagesDatabase() {
} catch (/** @type {any} */ error) {
if (!hasWarnedAboutUnavailableNewPackagesDatabase) {
ui.writeWarning(
`Failed to load the new packages list. Continuing without tarball minimum age fallback. ${error.message}`
`Failed to load the new packages list used for direct package download request blocking. Continuing with metadata-based minimum age checks only. ${error.message}`
);
hasWarnedAboutUnavailableNewPackagesDatabase = true;
}
@ -112,14 +112,14 @@ async function getNewPackagesList() {
return newPackagesList;
} else {
ui.writeWarning(
"The new packages list was downloaded, but could not be cached due to a missing version."
"The new packages list for direct package download request blocking was downloaded, but could not be cached due to a missing version."
);
return newPackagesList;
}
} catch (/** @type {any} */ error) {
if (cachedList) {
ui.writeWarning(
"Failed to fetch the latest new packages list. Using cached version."
"Failed to fetch the latest new packages list for direct package download request blocking. Using cached version."
);
return cachedList;
}

View file

@ -243,7 +243,7 @@ describe("newPackagesDatabase", async () => {
assert.strictEqual(writeWarningCalls.length, 1);
assert.ok(
writeWarningCalls[0].includes(
"Continuing without tarball minimum age fallback"
"Continuing with metadata-based minimum age checks only"
)
);
});