Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pgpm/workspace/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ jobs:
- name: Install
run: pnpm install

# Fails when pnpm-workspace.yaml no longer matches pnpm-policy.yaml, or when a
# third-party waiver has passed its expiry date.
- name: Check supply-chain policy
run: pnpm run policy:check

- name: Cache pgpm CLI
id: cache-pgpm
uses: actions/cache@v4
Expand Down
17 changes: 17 additions & 0 deletions pgpm/workspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ cd packages/your-module
pnpm test:watch
```

### Supply-chain policy

A third-party release must be 14 days old before this workspace will install it, which is where most compromised releases are caught. Nothing is exempt by default. `pnpm-policy.yaml` is where you exempt what you publish yourself, approve an install script, or waive the wait for an urgent security release:

```sh
pnpm run policy # regenerate the managed block in pnpm-workspace.yaml
pnpm run policy:check # CI: fail on drift or an expired waiver
```

See [pnpm-policy](https://www.npmjs.com/package/pnpm-policy) for the full configuration.

Nothing is locked yet on the very first install, so it resolves every version from the registry and trips if any of them is newer than the wait. Get past it once, then commit the lockfile it produces — from then on installs replay the lockfile and the wait only applies to versions you are adding:

```sh
pnpm install --config.minimumReleaseAge=0
```

### Prerequisites

- Node.js 20+
Expand Down
3 changes: 3 additions & 0 deletions pgpm/workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"test": "pnpm -r run test",
"lint": "pnpm -r run lint",
"deps": "pnpm up -r -i -L",
"policy": "pnpm-policy generate",
"policy:check": "pnpm-policy check",
"version": "pgpm sync-versions && git add -A"
},
"devDependencies": {
Expand All @@ -36,6 +38,7 @@
"makage": "^0.5.1",
"pgpm": "^5.19.1",
"pgsql-test": "^5.9.7",
"pnpm-policy": "^0.2.2",
"prettier": "^3.7.4",
"ts-jest": "^29.4.6",
"ts-node": "^10.9.2",
Expand Down
60 changes: 60 additions & 0 deletions pgpm/workspace/pnpm-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Supply-chain policy for this workspace, enforced by pnpm itself.
#
# The pnpm settings it produces live in pnpm-workspace.yaml under the
# `Managed by pnpm-policy` marker. Edit this file, then run:
#
# pnpm run policy
#
# `pnpm run policy:check` fails CI when the two drift apart.
#
# https://www.npmjs.com/package/pnpm-policy

# A third-party release must be this old before it can be installed. Most
# malicious releases (compromised maintainer account, typosquat, postinstall
# stealer) are found and yanked well inside two weeks, so the wait costs little
# and catches the attacks that move fastest.
minimumReleaseAge: 14d

# Off by default: turning it on refuses any transitive dependency resolved from
# git or a URL rather than the registry.
blockExoticSubdeps: false

# Nothing is exempt by default: everything this workspace installs, including the
# packages that scaffolded it, waits out the same two weeks.
#
# Exemptions are for what *you* publish, and they only start paying off once you
# do. npm reserves `@<your-username>` for you, so that scope is safe to claim as
# soon as you publish into it — waiting two weeks on your own release protects
# nothing:
#
# scopes:
# - "@____username____"
#
# If you publish under an npm account whose packages are not all in one scope,
# name the account instead and let pnpm-policy ask npm what it publishes
# (`pnpm pnpm-policy inventory`):
#
# maintainers:
# - ____username____
# inventory: ./pnpm-policy.inventory.json
scopes: []

# Dependencies permitted to run install scripts. An install script is arbitrary
# code at install time, so each entry is a deliberate decision and the value is
# the reason it is needed:
#
# allowBuilds:
# esbuild: native binary, downloaded at install time
# sharp: libvips bindings
allowBuilds: []

# Escape hatch for a third-party package that cannot wait — an urgent security
# release, typically. A reason is required, and `until` expires the waiver so
# `check` forces a re-justification instead of letting it become permanent:
#
# exceptions:
# - package: lodash
# versions: ["4.17.21"]
# reason: CVE-2021-23337 fix, published today
# until: 2026-09-01
exceptions: []
9 changes: 9 additions & 0 deletions pgpm/workspace/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
packages:
- 'packages/*'

# Managed by pnpm-policy — run `pnpm-policy generate` after editing pnpm-policy.yaml.

# A third-party release must be 2w old before it can be installed.
# Most malicious releases are found and yanked well inside that window.
minimumReleaseAge: 20160

# Off: transitive dependencies may resolve from git or a URL.
blockExoticSubdeps: false
5 changes: 5 additions & 0 deletions pnpm/workspace/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ jobs:
- name: Install
run: pnpm install

# Fails when pnpm-workspace.yaml no longer matches pnpm-policy.yaml, or when a
# third-party waiver has passed its expiry date.
- name: Check supply-chain policy
run: pnpm run policy:check

- name: Build
run: pnpm -r build

Expand Down
17 changes: 17 additions & 0 deletions pnpm/workspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ pnpm build
pnpm lint
```

### Supply-chain policy

A third-party release must be 14 days old before this workspace will install it, which is where most compromised releases are caught. Nothing is exempt by default. `pnpm-policy.yaml` is where you exempt what you publish yourself, approve an install script, or waive the wait for an urgent security release:

```sh
pnpm run policy # regenerate the managed block in pnpm-workspace.yaml
pnpm run policy:check # CI: fail on drift or an expired waiver
```

See [pnpm-policy](https://www.npmjs.com/package/pnpm-policy) for the full configuration.

Nothing is locked yet on the very first install, so it resolves every version from the registry and trips if any of them is newer than the wait. Get past it once, then commit the lockfile it produces — from then on installs replay the lockfile and the wait only applies to versions you are adding:

```sh
pnpm install --config.minimumReleaseAge=0
```

### Prerequisites

- Node.js 20+
Expand Down
5 changes: 4 additions & 1 deletion pnpm/workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"clean": "pnpm -r run clean",
"test": "pnpm -r run test",
"lint": "pnpm -r run lint",
"deps": "pnpm up -r -i -L"
"deps": "pnpm up -r -i -L",
"policy": "pnpm-policy generate",
"policy:check": "pnpm-policy check"
},
"devDependencies": {
"@types/jest": "^30.0.0",
Expand All @@ -34,6 +36,7 @@
"jest": "^30.2.0",
"lerna": "^9.0.3",
"makage": "^0.5.1",
"pnpm-policy": "^0.2.2",
"prettier": "^3.7.4",
"ts-jest": "^29.4.6",
"ts-node": "^10.9.2",
Expand Down
60 changes: 60 additions & 0 deletions pnpm/workspace/pnpm-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Supply-chain policy for this workspace, enforced by pnpm itself.
#
# The pnpm settings it produces live in pnpm-workspace.yaml under the
# `Managed by pnpm-policy` marker. Edit this file, then run:
#
# pnpm run policy
#
# `pnpm run policy:check` fails CI when the two drift apart.
#
# https://www.npmjs.com/package/pnpm-policy

# A third-party release must be this old before it can be installed. Most
# malicious releases (compromised maintainer account, typosquat, postinstall
# stealer) are found and yanked well inside two weeks, so the wait costs little
# and catches the attacks that move fastest.
minimumReleaseAge: 14d

# Off by default: turning it on refuses any transitive dependency resolved from
# git or a URL rather than the registry.
blockExoticSubdeps: false

# Nothing is exempt by default: everything this workspace installs, including the
# packages that scaffolded it, waits out the same two weeks.
#
# Exemptions are for what *you* publish, and they only start paying off once you
# do. npm reserves `@<your-username>` for you, so that scope is safe to claim as
# soon as you publish into it — waiting two weeks on your own release protects
# nothing:
#
# scopes:
# - "@____username____"
#
# If you publish under an npm account whose packages are not all in one scope,
# name the account instead and let pnpm-policy ask npm what it publishes
# (`pnpm pnpm-policy inventory`):
#
# maintainers:
# - ____username____
# inventory: ./pnpm-policy.inventory.json
scopes: []

# Dependencies permitted to run install scripts. An install script is arbitrary
# code at install time, so each entry is a deliberate decision and the value is
# the reason it is needed:
#
# allowBuilds:
# esbuild: native binary, downloaded at install time
# sharp: libvips bindings
allowBuilds: []

# Escape hatch for a third-party package that cannot wait — an urgent security
# release, typically. A reason is required, and `until` expires the waiver so
# `check` forces a re-justification instead of letting it become permanent:
#
# exceptions:
# - package: lodash
# versions: ["4.17.21"]
# reason: CVE-2021-23337 fix, published today
# until: 2026-09-01
exceptions: []
9 changes: 9 additions & 0 deletions pnpm/workspace/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
packages:
- 'packages/*'

# Managed by pnpm-policy — run `pnpm-policy generate` after editing pnpm-policy.yaml.

# A third-party release must be 2w old before it can be installed.
# Most malicious releases are found and yanked well inside that window.
minimumReleaseAge: 20160

# Off: transitive dependencies may resolve from git or a URL.
blockExoticSubdeps: false