v2026.5.3
Previous release
v2026.5.3 — Mini Shai-Hulud, supply-chain hardening complete
Tag: `v2026.5.3` · Released: 2026-05-13 · npm: `npm install -g [email protected]`
This is the first AIWG release published through the fully hardened supply-chain pipeline. Every signed-release control modeled in the Mini Shai-Hulud response plan (#1278) is now live, exercised against a real release cycle, and verifiable end-to-end.
TL;DR
# Install
npm install -g [email protected]
# Verify provenance (optional but recommended)
npm view [email protected] --json | jq .dist.attestations
# Should return a non-empty attestation object or array
# Full verification suite
# See docs/releases/verifying.md for cosign tarball verification + SBOM scan
If you're an AIWG consumer: nothing breaks. Node 20+ still works for the CLI. You now get cryptographic provenance for free; verifying it is optional.
If you're an AIWG contributor: bump your local npm to 11.5+ so the release-age gate fires on your `npm install`/`npm update`. The gate is what prevents a freshly-pushed malicious dep from entering the lockfile.
If you're a downstream package author who wants the same pattern for your own npm package: the new skills described below walk you through it.
Context — why this release exists
In early May 2026, the npm ecosystem absorbed the Mini Shai-Hulud worm campaign — a supply-chain attack chain where compromised maintainer accounts pushed malicious versions of dozens of popular packages. AIWG was not directly affected, but the campaign exposed gaps in our publish pipeline: no provenance attestation on npmjs.org, no signed-tag gate, no registry-independent signature on the tarball, no SBOM.
The response was a 9-wave hardening plan tracked in #1278. Track A — the publish-pipeline controls — landed across this release. Track B — user-facing capabilities for downstream adopters — ships in this release and continues in v2026.5.4+.
What's verifiable now
| Control | What it proves | How to verify | |
|---|---|---|---|
| npmjs.org provenance | Tarball built by `jmagly/aiwg/.github/workflows/npm-publish.yml` at commit X, on a GitHub Actions runner npmjs.org could OIDC-attest to | `npm view [email protected] --json \ | jq .dist.attestations` |
| Signed git tag | Tag created by a holder of the published maintainer key | `git tag -v v2026.5.3` | |
| Cosign tarball signature | Tarball bytes produced by AIWG's GitHub Actions workflow (registry-independent) | `cosign verify-blob --bundle aiwg-2026.5.3.tgz.sigstore ...` | |
| CycloneDX SBOM (signed) | What shipped in the tarball, down to transitive deps | Inspect with `jq` or pipe to Grype/Trivy/Dependency-Track |
The full verification walkthrough and chain-of-trust analysis are at `docs/releases/verifying.md`. The user-side hardening guide is at `docs/security/supply-chain-hardening.md`.
Six signed assets per release
Both the GitHub release and the Gitea release carry:
1. `aiwg-2026.5.3.tgz` — the published tarball 2. `aiwg-2026.5.3.tgz.sigstore` — cosign keyless signature bundle 3. `release-manifest.json` — version, tag SHA, commit SHA, workflow run URL, tarball SHA-256 4. `release-manifest.json.sigstore` — cosign keyless signature bundle for the manifest 5. `aiwg-2026.5.3.cdx.json` — CycloneDX SBOM 6. `aiwg-2026.5.3.cdx.json.sigstore` — cosign keyless signature bundle for the SBOM
Same six on both registries. Verification works identically against either source.
Maintainer signing key
Published in `SECURITY.md` and `.gitea/keys/maintainers.asc`.
- Principal: `AIWG Release Signing <[email protected]>`
- Fingerprint: `FE9272F0BC5781E1DE77FAAA719AB63879E84CE8`
- Algorithm: ed25519
- Created: 2026-05-12
- Expires: 2031-05-11
The key signs annotated release tags only. Commits to `main` are signed with the maintainer's separate personal key (already registered with GitHub against the maintainer's GitHub identity) so the GitHub "Verified" badge appears on commits without exposing the release-only key to a wider surface. CI's `tools/ci/verify-signed-tag.sh` gate (#1299) fails any publish whose tag does not verify against a key in `.gitea/keys/maintainers.asc` or `.gitea/allowed_signers`. Release procedure: explicitly select the release key on tag creation with `git tag -s -u FE9272F0BC5781E1DE77FAAA719AB63879E84CE8 -m "..." vX.Y.Z`.
Adopt the pattern for your own packages
Four focused skills land in the `security-engineering` framework for users who want to apply the same hardening to their own npm packages:
| Skill | What it does |
|---|---|
| `supply-chain-hardening-quickstart` | Orchestrates the user-side hardening pass. Run first. |
| `npm-supply-chain-audit` | Audits lifecycle scripts, Git dependency sources, publish-token exposure, and verifier docs. |
| `npm-release-age-gate` | Configures and reviews 7-day / 10-day release-age policies. |
| `supply-chain-trust` | Covers signed tags, provenance, tarball signatures, SBOMs, pinning, and broader trust-chain design. |
Long-form walkthrough at `docs/security/supply-chain-hardening.md`. Release-publisher requirement: npm trusted publishing requires npm 11.5.1+ and Node 22.14+; AIWG uses Node 24 in the publish workflow.
What changed in CI
For the curious: the publish pipeline now pins every container and action.
- Containers: `node:24@sha256:050bf2b...` (publishing leg) and `node:20@sha256:8f693ea...` (everything else). Manifest in `ci/digests.txt`.
- Actions: 40-char commit SHA pins on `actions/checkout`, `actions/setup-node`, `actions/upload-artifact`, `sigstore/cosign-installer`.
- Tools: `cosign` v2.6.1, `syft` v1.18.0.
The pin manifest is the source of truth. Diff it to audit any bump. The update procedure is documented at the bottom of `ci/digests.txt`.
Requirements summary
| You are | Node | npm | Why |
|---|---|---|---|
| AIWG CLI user | 20+ | Any | CLI runtime baseline |
| AIWG CLI user who verifies releases | 20+ | 11.5+ | `npm audit signatures` + release-age gate |
| AIWG contributor | 20+ | 11.5+ | Release-age gate must fire on every `npm install`/`npm update` |
| Adopting the pattern for your own package | 22.14+ or 24+ | 11.5.1+ | OIDC trusted publishing requires npm 11.5.1+ and Node 22.14+ |
Risk closure
9 of 10 supply-chain risks modeled in the Mini Shai-Hulud planning doc are now fully closed. The remaining one (S9, AI-runtime-boundary attacks) is intentionally out of scope for this campaign and tracked separately in the threat-model backlog.
Full risk-closure table and the corresponding control map are in `.aiwg/security/supply-chain-postmortem-2026-05.md`.
Upgrade
npm install -g [email protected]
aiwg doctor
No breaking changes. If you previously pinned to a `2026.5.3-rc.*` pre-release, switch to the stable version — the pre-releases were internal pipeline checkpoints and one (`rc.0`) shipped without provenance.
References
- #1278 — Mini Shai-Hulud response plan + Track A close-out
- `CHANGELOG.md` — full release detail
- `docs/releases/verifying.md` — verification walkthrough
- `docs/security/supply-chain-hardening.md` — apply the pattern to your own package
- `SECURITY.md` — maintainer key fingerprint, vulnerability disclosure
- `ci/digests.txt` — CI pin manifest