Skip to content

Rewrite aws-sst on SST v4 with pnpm 11 supply-chain hardening#41

Merged
Gabrielpanga merged 2 commits into
masterfrom
feat/aws-sst-v4-rewrite
May 16, 2026
Merged

Rewrite aws-sst on SST v4 with pnpm 11 supply-chain hardening#41
Gabrielpanga merged 2 commits into
masterfrom
feat/aws-sst-v4-rewrite

Conversation

@Gabrielpanga
Copy link
Copy Markdown
Member

Summary

`examples/aws-sst` was on SST v1 (deprecated for years) and shipped with 97 npm-audit findings — 7 critical, 38 high — all routing through breaking framework upgrades. Patching a dead framework was not viable, so this PR rebuilds the example on the current SST release (v4 / Ion engine) and brings it onto the same pnpm 11 supply-chain hardening as the other Node projects in this repo.

Stack rewrite

Old (SST v1, @serverless-stack) New (SST v4)
`sst.json` + `stacks/index.ts` + `stacks/PluggyStack.ts` `sst.config.ts`
`new sst.Table(...)` `new sst.aws.Dynamo("ItemsTable", ...)`
`new sst.Api(...)` with `routes` `new sst.aws.ApiGatewayV2(...)` + `api.route(...)`
CDK constructs under the hood Pulumi providers under the hood

Stack name (`pluggy-aws-sst`), region (`sa-east-1`), and the two routes (`POST /connect-token`, `POST /notification`) carry over unchanged.

Lambda code

  • `src/repositories/items.ts` ported off the bundled `aws-sdk` v2 onto modular `@aws-sdk/client-dynamodb` v3 (`PutItemCommand`).
  • `src/connect-token.ts` and `src/notification.ts` kept their existing `APIGatewayProxyHandlerV2` contract — only the `pluggy-sdk` import surface changed, and that already worked against 0.85.2.

Toolchain

  • `pluggy-sdk` 0.12.3 → 0.85.2 (5 years of fixes; required by the new `preinstall` audit gate, which would otherwise refuse to install)
  • Modular `@aws-sdk/client-dynamodb` v3 replaces the deprecated bundled `aws-sdk` v2
  • `@tsconfig/node14` + `@types/node` 14.18.5 dropped (Node 24+)
  • `sst` 4.12.10 pinned (latest >14d-old release)
  • `typescript` / `@types/aws-lambda` bumped to current

pnpm setup (matches the other migrated projects)

`package.json`

  • `packageManager: pnpm@11.1.1`
  • `engines: { node: >=24.0.0, pnpm: >=11.0.0 }`
  • `devEngines.runtime` with `onFail: error`
  • `scripts.preinstall: pnpm audit && pnpm audit signatures`
  • `scripts.lint:lockfile: pnpm install --frozen-lockfile`
  • Project scripts moved to pnpm-native (`pnpm dev`, `pnpm build`, `pnpm deploy`, `pnpm remove`)

`pnpm-workspace.yaml`

  • `minimumReleaseAge: 20160` (14 days)
  • `minimumReleaseAgeIgnoreMissingTime: true`
  • `engineStrict: true`
  • `trustPolicy: no-downgrade`, `trustPolicyIgnoreAfter: 129600` (90d)
  • `blockExoticSubdeps: true`
  • `savePrefix: ""`
  • `resolutionMode: highest`
  • `minimumReleaseAgeExclude`:
    • `@pluggyai/*` (own pipeline)
    • `fast-xml-builder` — `# Remove after 2026-05-18 — multiple high/moderate advisories patched in 1.1.7 (released 2026-05-04)`
  • `overrides`:
    • `fast-xml-parser: '>=5.7.2'` — clears the entity-encoding bypass, DoS, CDATA/comment injection, and stack-overflow advisories that ship via `@aws-sdk` transitives
    • `fast-xml-builder: '>=1.1.7 <1.2.0'` — clears the attribute-quote-bypass advisory while staying below `1.2.0`'s brand-new `xml-naming` transitive (7 days old)
  • `allowBuilds: {}` — no postinstall scripts in the resolved tree

`.gitignore` — blocks `package-lock.json` and `yarn.lock` so a stray `npm install` / `yarn install` cannot introduce a second lockfile.

`.npmrc` removed.

Files removed

  • `sst.json` (replaced by `sst.config.ts`)
  • `stacks/index.ts`, `stacks/PluggyStack.ts` (SST v4 has no stack dir)
  • `test/MyStack.test.ts` (SST v1 test scaffold, no v4 equivalent yet)
  • `.npmrc`, `package-lock.json`

Verification

  • `pnpm install` succeeds (183 packages, 0 vulnerabilities)
  • `pnpm install --frozen-lockfile` succeeds
  • `pnpm audit && pnpm audit signatures` clean
  • `tsc --noEmit` passes after `sst install` bootstraps platform types
  • `pnpm deploy` to a Pluggy AWS account — manual follow-up

Required follow-up

  • 2026-05-18 — remove `fast-xml-builder` from `minimumReleaseAgeExclude` once 1.1.7's 14-day window closes.

The previous quickstart used SST v1 (@serverless-stack/cli@0.60.6,
@serverless-stack/resources@0.60.6), which has been deprecated for
years and shipped with 97 npm-audit findings (7 critical, 38 high)
that all routed through breaking framework upgrades. Rather than
patch a dead framework, rebuild the example on the current SST
release.

Stack rewrite
- sst.config.ts replaces stacks/index.ts + stacks/PluggyStack.ts
- sst.aws.Dynamo for the ItemsTable
- sst.aws.ApiGatewayV2 with two routes (connect-token, notification)
- Stack name / app name carried over; region pinned to sa-east-1

Code
- src/repositories/items.ts ported off aws-sdk v2 onto
  @aws-sdk/client-dynamodb v3
- src/connect-token.ts and src/notification.ts kept their handler
  contract (APIGatewayProxyHandlerV2) — only the pluggy-sdk import
  surface changed (already compatible with 0.85.2)

Toolchain
- pluggy-sdk 0.12.3 -> 0.85.2 (5 years of fixes; required by the
  preinstall audit gate)
- aws-sdk v2 (in pluggy-sdk-transitive form too) dropped in favour
  of modular @aws-sdk/client-dynamodb
- @tsconfig/node14 + @types/node 14.18.5 dropped
- typescript / @types/aws-lambda bumped to current

package.json (matches the repo's pnpm baseline)
- packageManager: pnpm@11.1.1
- engines: node >=24.0.0, pnpm >=11.0.0
- devEngines.runtime with onFail: error
- preinstall: pnpm audit && pnpm audit signatures
- lint:lockfile: pnpm install --frozen-lockfile
- scripts moved to pnpm-native commands (sst dev / build / deploy /
  remove)

pnpm-workspace.yaml
- Full supply-chain template: minimumReleaseAge 14d,
  minimumReleaseAgeIgnoreMissingTime, trustPolicy no-downgrade,
  trustPolicyIgnoreAfter 90d, blockExoticSubdeps, engineStrict,
  savePrefix "", resolutionMode highest
- minimumReleaseAgeExclude: '@pluggyai/*' plus a date-stamped CVE
  bypass for fast-xml-builder (1.1.7 fixes the attribute-quote
  advisory, released 2026-05-04)
- overrides.fast-xml-parser '>=5.7.2' and
  fast-xml-builder '>=1.1.7 <1.2.0' to clear @aws-sdk's bundled
  copies. The upper bound on fast-xml-builder avoids 1.2.0's
  brand-new xml-naming transitive (7 days old)
- allowBuilds {} (no postinstall scripts in the resolved tree)

Removed
- sst.json (replaced by sst.config.ts)
- stacks/ (SST v4 has no stack directory)
- test/MyStack.test.ts (SST v1 test scaffold, no v4 equivalent yet)
- .npmrc (pnpm-workspace.yaml is the single source of truth)
- package-lock.json (replaced by pnpm-lock.yaml)

Verified: pnpm install, pnpm install --frozen-lockfile, preinstall
audit + signatures hook, and tsc --noEmit all pass clean. Local
'sst install' completes without errors.
@Gabrielpanga Gabrielpanga requested a review from a team as a code owner May 16, 2026 13:16
CI workflow runs on pushes to master and on PRs that touch
examples/aws-sst/** or the workflow itself.

Steps:
1. Set up pnpm 11.1.1 + Node 24 (matches package.json engines/
   packageManager).
2. pnpm install --frozen-lockfile - the preinstall hook runs
   pnpm audit + pnpm audit signatures, so a vulnerable or
   unsigned package fails the install before anything else runs.
3. pnpm exec sst install - downloads the SST v4 platform/provider
   code locally. Required to generate .sst/platform/config.d.ts,
   which sst.config.ts references; no AWS credentials needed.
4. pnpm run lint  -> tsc --noEmit
   pnpm run test  -> tsc --noEmit
   pnpm run build -> tsc --noEmit

SST v4 does not ship a separate `sst build` command (deploys go
straight through `sst deploy`). For CI purposes "build" is the
TypeScript compile check; the same tsc invocation backs lint and
test for now. Each script is wired separately so they can grow
into eslint / a real test runner / deploy-time bundling without
touching the workflow.

Concurrency-cancel older runs on the same ref so a fast-pushed
branch doesn't queue stale builds.

Verified end-to-end locally with Node 24.14.1 + pnpm 11.1.1.
@Gabrielpanga Gabrielpanga merged commit e40873e into master May 16, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant