This is the Yarn companion to my previous post on hardening npm. Same threats (compromised maintainer accounts, malicious install scripts, lockfile injection) & same mitigations, but expressed in Yarn’s config language.
If you want the rationale and the list of recent attacks, go read that post first. This one is a short config recipe.
ℹ️ Everything here is for Yarn 4 (Berry). Yarn Classic (1.x) is out of scope.
Tl;dr #
Three lines in .yarnrc.yml:
# .yarnrc.yml
npmMinimalAgeGate: 4320
enableScripts: false
enableHardenedMode: true
And one dependenciesMeta block in package.json (content depends on your project).
The Changes #
1. A 3-day quarantine via npmMinimalAgeGate #
Yarn’s equivalent of npm’s min-release-age. Here the value is in minutes (so 4320 = 3 days):
# .yarnrc.yml
npmMinimalAgeGate: 4320
2. Block install scripts by default #
Yarn ships with the equivalent of ignore-scripts and a per-package allowlist baked in.
Turn scripts off globally in .yarnrc.yml:
# .yarnrc.yml
enableScripts: false
Then allowlist the packages that legitimately need to run postinstall scripts via dependenciesMeta in package.json:
{
"dependenciesMeta": {
"sharp": { "built": true },
"@sentry/cli": { "built": true },
}
}
To find which packages to add to the allowlist, use can-i-ignore-scripts: run npx can-i-ignore-scripts and read the output: you’ll see all packages with a script listed and can decide which ones should be added the the allowlist.
3. Enable Hardened Mode #
# .yarnrc.yml
enableHardenedMode: true
Yarn’s Hardened Mode (added in 4.1) validates that every entry in yarn.lock actually matches the metadata published on the registry, and re-verifies dependency ranges. It covers most of what lockfile-lint and npm audit signatures do for npm, in a single switch.
New Routine #
No changes to your day-to-day workflow here; the new config is always on.
