chore(deps): clear all high-severity npm advisories + enforce 3-day minimum release age - #61
Merged
Merged
Conversation
Closes every open Dependabot alert on the root `yarn.lock` (the semantic-release release-tooling tree — dev-only, installed solely by `.github/workflows/release.yml`). No Kotlin/Java source is touched, so this is deliberately a `chore` commit: release.config.mjs maps `chore` to "no release", and a dependency bump in release tooling must not cut a Maven Central version of the SDK. Three of the four HIGH advisories were reachable through the existing semver ranges and only needed the resolutions floated: ip-address 10.1.0 -> 10.4.0 GHSA-mwp4-54f8-5fhr (high, SSRF) js-yaml 4.1.1 -> 4.3.1 GHSA-52cp-r559-cp3m (high, DoS) brace-expansion 2.1.0 -> 5.0.9 GHSA-3jxr-9vmj-r5cp (high, DoS) The fourth could not be: `sigstore` needed >= 4.1.1 (GHSA-52v5-jr5w-gjxr, high — `certificateOIDs` verification constraints silently dropped), but its dependents pinned it below that major. `pacote@19/20` and `libnpmpublish@10` all declare `sigstore ^3.0.0`, and they arrive via `npm@10.9.8` <- `@semantic-release/npm@12` <- `semantic-release@24.2.9`. Rather than force a major with a `resolutions` override — which would leave the declared range lying about compatibility and rot on the next advisory — bump the range that actually gates the chain: semantic-release ^24.0.0 -> ^25.0.0 (resolves 25.0.9) That pulls @semantic-release/npm@13.1.5 -> npm@11.19.0 -> pacote@21.5.1 + libnpmpublish@11.2.0, both of which declare `sigstore ^4.0.0` -> 4.1.1, entirely within semver. semantic-release 25.0.0's only BREAKING CHANGES are Node minimums (`^22.14.0 || >=24.10.0`). release.yml pins `node-version: lts/*`, which resolves to the Krypton line (24.19.0) and satisfies that, so the workflow needs no change. Every declared plugin stays compatible: @semantic-release/exec@7 declares `semantic-release >=24.1.0`, and commit-analyzer/release-notes-generator/github are hoisted by semantic-release itself. Five MEDIUM advisories close as a side effect of the same resolution pass, with no extra pinning: tar 7.5.13 -> 7.5.22 (GHSA-w8wr-v893-vjvp, GHSA-vmf3-w455-68vh) and @sigstore/core 2.0.0 -> 3.2.1 (GHSA-jfc7-64v2-mr8c) via the chain above, plus the lower-severity duplicates on js-yaml (GHSA-h67p-54hq-rp68) and ip-address (GHSA-v2v4-37r5-5v8g). `.yarnrc.yml` is intentionally byte-identical to main. A Yarn lockfile migration rewrites it with hardening opt-outs — `npmMinimalAgeGate: 0` against a built-in default of 1d — and that would silently disable the minimum-release-age gate. Verified after every install step: no `YN0087: Migrated`, `git diff --exit-code .yarnrc.yml` clean, and `yarn config --json` still reports `npmMinimalAgeGate` effective 1440 from `<default>`. Every version resolved here is at least 8 days old, so the gate admits them all. Ran under the repo's own pinned toolchain (`packageManager: yarn@4.15.0` via corepack), not the ambient yarn. `yarn install --immutable` passes, so CI's frozen install stays in sync. `tools/yarn.lock` is untouched and carries no advisories. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the Convert house supply-chain gate to the repo's `.yarnrc.yml`,
matching what already ships in javascript-sdk and backend tracking:
npmMinimalAgeGate: 4320 # 3 days, in minutes
npmPreapprovedPackages: ["@convertcom/*"]
Yarn refuses to resolve any dependency version published less than three
days ago. That is the window smash-and-grab npm malware lives in — a
compromised publish is typically yanked within hours, so simply not being
first to install it removes most of the exposure. android-sdk pins
`packageManager: yarn@4.15.0`, well past the 4.10 that introduced the
setting, so the gate lands natively with no version bump.
`npmPreapprovedPackages` is NOT dead config here, which is what makes
this repo differ from the php-sdk and python-sdk gates. Those trees hold
zero internal npm packages, so the exemption there would have been
decoration. This repo has TWO Berry projects: the root release tooling
(0 `@convertcom/` hits in yarn.lock) and the nested parity-vector
project under tools/, which depends on `@convertcom/js-sdk-bucketing`.
Yarn resolves rcfiles by walking up from the cwd, so tools/ inherits
this file despite having no `.yarnrc.yml` of its own — verified by
running `yarn config --json` from tools/ and confirming `source` points
back at the repo root. Without the exemption, regenerating the
cross-SDK parity vectors against a freshly published bucketing package
would stall for three days.
Verified, not assumed — four checks:
1. `npmMinimalAgeGate` reports effective 4320 (source `.yarnrc.yml`,
against a built-in default of 1d) from BOTH the repo root AND
tools/, confirming inheritance for the new keys and not just for
the pre-existing `nodeLinker`.
2. `yarn install --immutable` still passes at the root (the exact
command release.yml runs) and in tools/. The only tools/ warnings
are the pre-existing unmet `@convertcom/js-sdk-bucketing` peer
ranges, unrelated to the gate.
3. The gate does not block this tree: a full fresh resolution from no
lockfile at all, with the gate active, resolved 432 packages with
zero quarantine rejections. Every version currently pinned is at
least 8 days old.
4. The gate is not inert. Installing a version published 0.86 days
ago fails with `YN0016: eslint@npm:10.8.1: All versions satisfying
"10.8.1" are quarantined`, and the SAME version installs cleanly
with `--no-time-gate` — so the gate, not a missing version, is
what refused it.
The `@convertcom/*` exemption path itself is not exercised by these
checks: no internal package currently has a release inside the 3-day
window to test against. The setting is confirmed recognized (it reports
as effective config rather than an unknown key), not confirmed to admit
a fresh internal publish end to end.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JosephSamirL
approved these changes
Aug 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits, reviewable independently:
No Kotlin/Java source is touched by either.
1 — Clear the Dependabot alerts
All 9 alerts sit in the root
yarn.lock— the semantic-release release-tooling tree. That tree is dev-only and is installed by exactly one thing: theInstall Node dependenciesstep of.github/workflows/release.yml.ci.ymlis pure Gradle and never installs it. Nothing here reaches the published AAR/JAR, andtools/yarn.lock(parity-vector tooling) is untouched and carries no advisories.One line of
package.json, plus the lockfile it re-resolves.Three of the four highs were already reachable through the existing semver ranges and only needed their resolutions floated (
yarn up -R):ip-addressjs-yamlbrace-expansionThe fourth high needed a range bump, not a pin
sigstorehad to reach ≥ 4.1.1 (GHSA-52v5-jr5w-gjxr — high;certificateOIDsverification constraints are silently dropped and never enforced). Every dependent pinned it below that major:pacote@19.0.2,pacote@20.0.1andlibnpmpublish@10.0.2all declaresigstore ^3.0.0, and they arrive vianpm@10.9.8←@semantic-release/npm@12.0.2←semantic-release@24.2.9.A
resolutionsoverride would have forced the major while leaving the declared range asserting something untrue, and it would rot at the next advisory. Instead this bumps the range that actually gates the chain:which walks entirely within semver to the patched version:
Why the
semantic-releasemajor is safe heresemantic-release@25.0.0's only documentedBREAKING CHANGESare Node minimums —^22.14.0 || >= 24.10.0(v20/v21/v23 dropped). No configuration or plugin-API surface changed.release.ymlpinsnode-version: 'lts/*', which resolves to the current LTS line — Krypton, 24.19.0 — and satisfies that range. The workflow needs no change, and it stays satisfied when Node 26 becomes LTS.@semantic-release/exec@7declaressemantic-release >=24.1.0;commit-analyzer,release-notes-generatorandgithubare hoisted by semantic-release itself (v13/v14/v12 respectively).@semantic-release/github@12also drops its GitHub Search API consumption. That only affected the PR/issue success comments, whichrelease.config.mjsalready disables (successComment: false,releasedLabels: false, …) — so no behavioural change for us.Moderates that close for free
No extra pinning — these are the same resolution pass:
tar7.5.13 → 7.5.22 — GHSA-w8wr-v893-vjvp, GHSA-vmf3-w455-68vh@sigstore/core2.0.0 → 3.2.1 — GHSA-jfc7-64v2-mr8cjs-yaml(GHSA-h67p-54hq-rp68) andip-address(GHSA-v2v4-37r5-5v8g)Why
chore(deps):and notfix:release.config.mjsmapschoreto no release and hides it from the notes. A dev-only release-tooling bump must not cut a Maven Central version of the SDK. Confirmed in the dry-run below: "The commit should not trigger a release."2 — Minimum release age gate
Adds the Convert house gate to
.yarnrc.yml, matching what already ships injavascript-sdkand backend tracking:Yarn refuses to resolve any dependency version published less than three days ago. That is the window smash-and-grab npm malware lives in — a compromised publish is typically yanked within hours, so simply not being first to install it removes most of the exposure. This repo pins
packageManager: yarn@4.15.0, well past the 4.10 that introduced the setting, so the gate lands natively with no Yarn version bump.Why the
@convertcom/*exemption is real here, unlike php-sdk / python-sdkThose trees hold zero internal npm packages, so the exemption there would be decoration. This repo has two Berry projects:
@convertcom/hits inyarn.locktools/parity-vector project — depends on@convertcom/js-sdk-bucketingYarn resolves rcfiles by walking up from the cwd, so
tools/inherits this file even though it has no.yarnrc.ymlof its own. Verified by runningyarn config --jsonfromtools/and confirmingsourcepoints back at the repo root. Without the exemption, regenerating the cross-SDK parity vectors against a freshly published bucketing package would stall for three days.The gate is enforcing, and it doesn't block us — both checked
npmMinimalAgeGatereports effective 4320, source.yarnrc.yml, from the repo root and fromtools/— confirming inheritance for the new keys, not just for the pre-existingnodeLinker.YN0016: eslint@npm:10.8.1: All versions satisfying "10.8.1" are quarantined, and the same version installs cleanly with--no-time-gate— so the gate, not a missing version, is what refused it.One honest gap: the
@convertcom/*exemption path itself is not exercised. No internal package currently has a release inside the 3-day window to test against. The setting is confirmed recognized (it reports as effective config rather than an unknown key), not confirmed to admit a fresh internal publish end to end.Verification
Run under the repo's own pinned toolchain —
packageManager: yarn@4.15.0via corepack, not the ambient yarn.yarn install --immutableon unmodifiedmain: passes, no migration,.yarnrc.ymlclean. Establishes that the starting lock was in sync.yarn install --immutableafter both commits: passes at the root (the exact commandrelease.ymlruns) and intools/→ the frozen install stays in sync. The onlytools/warnings are the pre-existing unmet@convertcom/js-sdk-bucketingpeer ranges, unrelated to either change.yarn.lockand checked against each vulnerable range: 9/9 resolved, 0 still in range.semantic-release@25.0.9— all five configured plugins loaded across all nine lifecycle steps;verifyConditionscompleted for both@semantic-release/execinstances and for@semantic-release/githubagainst the live API; commit analysis ran over real history and concluded "no release".Difference from the real path, stated explicitly: the dry-run used
--no-ci --branches <this branch>becauserelease.config.mjsrestricts releases tomainand semantic-release requires the branch to exist on the remote. Only the branch-name check differs; plugin resolution, GitHub auth and commit analysis all ran for real../gradlew publishAllPublicationsToMavenCentralRepositorycorrectly never executed — dry-run skipsprepare/publish, and no release was warranted anyway.On
.yarnrc.ymlmoving in a dependency PRNormally that file changing inside a dependency bump is a red flag: a Yarn lockfile migration rewrites it with hardening opt-outs, including
npmMinimalAgeGate: 0against a built-in default of1d, which would silently disable the gate. So the two concerns were deliberately split across commits:.yarnrc.ymlbyte-identical tomain— verified withgit diff --exit-code, and no install emittedYN0087: Migrated your project.0.Worth reviewing commit 1's diff on its own to confirm that split.
Note for the reviewer: CI green here does not exercise either change.
ci.ymlnever runsyarn, so the npm tree is only installed byrelease.ymlonmain. That is precisely why the dry-run and gate checks above were run by hand.Supersedes
Dependabot PR #42 (
ip-address10.1.0 → 10.2.0) — that target is still inside GHSA-mwp4-54f8-5fhr's vulnerable range (<= 10.3.0). This PR takesip-addressto 10.4.0 instead.🤖 Generated with Claude Code