Skip to content

chore(release): v3.19.0 - #855

Merged
fraseragain merged 12 commits into
mainfrom
develop
Oct 26, 2026
Merged

fraseragain merged 12 commits into
mainfrom
develop

Conversation

@fraseragain

Copy link
Copy Markdown
Contributor

Release

Moves Studio production off end-of-life Node 20 (tracker item S-006, the money-path fix). Everything here has run on staging since 23 October (3.18.0-develop.6), with green CI on develop.

PR Change
#848 Node 22.23.4 (Docker on Alpine 3.23, CI); hardened Dockerfile; secret build ARGs removed
#849 Studio starts on Node 22: Veramo credential-ld import patch (patch-package) and http-client override
#850 POST /credential/verify returns a warnings entry when credential status was not checked
#851 CI no longer publishes Playwright traces

Expected version: 3.19.0 (minor, from the feat commit in #850).

Why

  • Node 20 gets no fix for the October 2026 Node.js security release (Brotli decoder RCE CVE-2026-111497, TLS hostname bypasses).
  • Node 22.23.4's root store removes the emSign roots that Mozilla distrusted after the eMudhra intermediate CA compromise. Studio sends Stripe, Logto and faucet credentials to other services, so this is the priority.

Checked on staging

  • Image staging-latest: Node v22.23.4, Alpine 3.23.7, Veramo patch applied.
  • emSign ECC Root CA - G3 is absent from both the Node and system trust stores. emSign Root CA - G1 remains; Mozilla has not removed it.
  • studio-api-staging.cheqd.net/swagger/ responds 200.
  • CI on develop: unit and end-to-end tests pass on Node 22.23.4.

Before merging

  • Merge with a merge commit, not squash, so semantic-release sees the feat commit.
  • No database migrations in this release.
  • Production env vars are unaffected. The removed build ARGs were always empty; runtime values come from the DigitalOcean app spec.

After merging

  1. Confirm the push workflows start on main: Workflow Dispatch (build, release, production image).
  2. Confirm release 3.19.0 is created and production-latest is rebuilt.
  3. Confirm DigitalOcean deploys the new image to cheqd-studio-production.
  4. Check the production image runs Node v22.23.4. Smoke test /swagger/, sign-in, issue and verify a credential, and a Stripe-backed call.
  5. Back-merge main into develop with a merge commit.

Rollback: redeploy the previous production image (release 3.18.0) in DigitalOcean.

🤖 Generated with Claude Code

kaustubhkapatral and others added 9 commits October 22, 2026 16:36
Node 22 removed JSON import assertions and breaks the legacy esm
loader, so the server crashed at start on node:22.23.4:

- patch @veramo/credential-ld 6.0.2 to use `with { type: 'json' }`
  (patch-package, applied on install; patches copied into the runner)
- override @transmute/jsonld's @digitalbazaar/http-client 1.2.0 (esm
  loader) with ^3.4.1, loaded through require(esm)

Veramo 7 fixes the first issue but is a breaking upgrade and is not
supported by @cheqd/did-provider-cheqd 4.8, so it is left for later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /credential/verify only checks revocation and suspension when
verifyStatus=true, so a revoked or suspended credential returns
verified: true by default. When the credential has a credentialStatus
and verifyStatus is not set, add a `warnings` entry to the response and
document the behaviour in the OpenAPI spec. Behaviour is otherwise
unchanged; flipping the default is a later, announced change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## What

Targets #848 (Node 22.23.4 and Dockerfile hardening). On Node 22 the
server crashed at start, which is why "Build & Test / Build Node.js"
failed in #848. The Docker image still builds, so without this fix the
container would crash on deploy.

Two incompatibilities, both in dependencies:

1. **`@veramo/credential-ld` 6.0.2** imports JSON with `assert { type:
'json' }`, which Node 22 removed (`SyntaxError: Unexpected identifier
'assert'`). Fixed with a one-file patch to `with { type: 'json' }`,
applied by `patch-package` on every install
(`patches/@veramo+credential-ld+6.0.2.patch`). `patch-package` is a
runtime dependency because the runner stage installs with
`NODE_ENV=production`, and the Dockerfile now copies `patches/` into the
runner before `npm ci`.
2. **`@digitalbazaar/http-client` 1.2.0** (under `@transmute/jsonld` →
`jsonld` 5) uses the legacy `esm` loader, which fails on Node 22 and 24
(`Function.prototype.apply was called on undefined`). Fixed with an
`overrides` entry forcing ^3.4.1 for that subtree; Node 22.12+ loads it
through `require(esm)`.

## Why not Veramo 7

`@veramo/credential-ld` 7.0.2 already uses `with`, but upgrading
`@veramo/*` to 7 fails to compile: `CredentialIssuerLD` is no longer
exported, several types changed, and `@cheqd/did-provider-cheqd` 4.8
still depends on Veramo 6. That is a separate piece of work.

## Changes to package.json

- Adds a `postinstall` script (`patch-package`) and the `patch-package`
dependency.
- Adds `overrides` for `@transmute/jsonld`.

## How it was tested (node:22.23.4-bookworm)

- Before the fix: `import('@veramo/credential-ld')` fails on Node 22 and
24, and succeeds on Node 20.
- After the fix:
  - clean `npm ci --force` applies the patch;
  - `import('@veramo/credential-ld')` succeeds;
  - `npm run build` exits 0;
- unit tests run with `--runInBand`: 23 suites passed, 1 skipped, 213
tests passed, 30 skipped. The default parallel run was killed for memory
in a local 8 GB Docker VM.
- Server smoke test: `node dist/index.js` with external DB and auth
disabled listens on port 3000, and `/swagger/` returns 200. The only
errors are the five "Failed to seed provider" messages, which appear
identically on Node 20 without a database.
- Prettier passes on the changed files. The end-to-end Playwright suite
has not been run locally; CI will run it on this PR and on #848.

## Risk

- The patch is pinned to `@veramo/credential-ld` 6.0.2. If that version
changes, `patch-package` fails the install loudly rather than silently
skipping.
- The `http-client` override changes the document loader used by
`jsonld` 5 in the LD signature path. Credential issue and verify for LD
proofs should be covered by the e2e suite. Check that before merging.

Part of the October 2026 security remediation (tracker item S-006).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## What

Step 1 of making credential verification fail closed (tracker item
S-019).

`POST /credential/verify` only checks revocation and suspension when
`verifyStatus=true`, which defaults to `false`. So a revoked or
suspended credential returns `verified: true` unless the caller opts in.
This PR makes that visible without changing behaviour:

- When the credential has a `credentialStatus` and `verifyStatus` is not
`true`, the 200 response includes `warnings: ["Credential status was not
checked: ..."]`.
- The OpenAPI description of the endpoint and of `verifyStatus` now says
this plainly. `VerifyCredentialResult` documents the new optional
`warnings` array, and `src/static/swagger-api.json` is regenerated.
- `VerifyCredentialResponseBody` gains an optional `warnings?:
string[]`.

Nothing else changes. `verified` is unaffected, and responses for
credentials without a `credentialStatus`, or with `verifyStatus=true`,
are identical to today.

## Why

A verifier that forgets the flag gets a false "valid" for a revoked
credential. Step 2, flipping the default or rejecting when it is
omitted, is a breaking API change and needs customer notice first.

## Tests

- e2e (`issue-verify-flow.spec.ts`):
  - the JWT credential without status asserts no `warnings`;
- the JWT credential with a status list, verified without
`verifyStatus`, asserts the warning is present.
- Locally on Node 20:
  - `tsc --noEmit` passes;
  - `npm run build` passes and regenerates swagger;
- unit tests run with `--runInBand`: 23 suites passed, 1 skipped, 213
tests passed;
  - Prettier passes on the changed files.
- ESLint (`eslintrc` mode) reports the same 14 pre-existing errors on
these files before and after the change, so nothing new.
- The e2e suite has not been run locally; CI will run it.

## Risk

Low. The response shape only gains an optional field. Clients that
validate responses strictly against an exact schema would see a new
property.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## [3.18.0-develop.6](3.18.0-develop.5...3.18.0-develop.6) (2026-10-23)

### Features

* warn when credential status is not checked on verify ([4cb33fe](4cb33fe))
* warn when credential status is not checked on verify ([#850](#850)) ([5c9c9d1](5c9c9d1))

### Bug Fixes

* make Studio start on Node 22 ([86be5d6](86be5d6))
* make Studio start on Node 22 ([#849](#849)) ([3ecb65d](3ecb65d)), closes [#848](#848)
Traces recorded on failure carried the e2e test user's x-api-key in
their network log and were uploaded as artifacts on this public repo.
Turn tracing off on CI and stop uploading test-results/. Local runs
still keep traces on failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## What

- `playwright.config.ts`: `trace` is now `off` when `CI` is set. Local
runs keep `retain-on-failure`.
- `.github/workflows/build.yml`: the `playwright-report` artifact no
longer includes `test-results/`, where traces and page snapshots are
written.

## Why

When an authenticated end-to-end test failed, Playwright kept a trace
whose network log includes every request header. That included the test
user's `x-api-key`, which is `TEST_USER_API_KEY`, a staging Studio API
key; the auth setup also types it into the Swagger "Authorize" box. The
traces went into the `playwright-report` artifact. On a public
repository any signed-in GitHub user can download artifacts, so the key
was exposed.

The six retained `playwright-report` artifacts (9 to 14 October) have
been deleted. The key itself still needs rotating; that is tracked
separately as S-031.

## Testing

- Prettier passes on both files, and the workflow YAML parses.
- No test behaviour changes. On CI the reporter is already `github`, so
the HTML report folder is typically empty and the artifact step still
uses `if-no-files-found: ignore`.

## Trade-off

Failed CI runs no longer come with a downloadable trace. To debug a
CI-only failure, reproduce it locally, where traces are still recorded.
If traces are needed on CI later, they should stay out of public
artifacts.

Part of the October 2026 security remediation (tracker item S-031).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@fraseragain
fraseragain enabled auto-merge October 26, 2026 12:47
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## What

Brings the v3.18.0 release commits on `main` (#845, #846 and the release
commit) into `develop`. The back-merge after the 14 October release
never happened, so the release PR #855 (`develop` → `main`) currently
conflicts in `CHANGELOG.md` and `package.json`, and its auto-merge
cannot proceed.

Conflict resolution, following the v3.17.0 back-merge (#840):
- `package.json`: version taken from `main` (`3.18.0`).
- `CHANGELOG.md`: both sections kept, newest first: `3.18.0-develop.6`
(23 October), then `3.18.0` (14 October).

No code changes.

## Important

**Merge with a merge commit, not squash.** A squash would not record
`main`'s commits in `develop`'s history, and #855 would still conflict.
After this merges, #855 merges cleanly (checked with `git merge-tree`),
and its auto-merge can complete once it is approved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## [3.19.0-develop.1](3.18.0...3.19.0-develop.1) (2026-10-26)

### Features

* warn when credential status is not checked on verify ([4cb33fe](4cb33fe))
* warn when credential status is not checked on verify ([#850](#850)) ([5c9c9d1](5c9c9d1))

### Bug Fixes

* make Studio start on Node 22 ([86be5d6](86be5d6))
* make Studio start on Node 22 ([#849](#849)) ([3ecb65d](3ecb65d)), closes [#848](#848)
@cheqd-bot

cheqd-bot Bot commented Oct 26, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 3.19.0-develop.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@fraseragain
fraseragain merged commit a46f881 into main Oct 26, 2026
2 checks passed
@cheqd-bot

cheqd-bot Bot commented Oct 26, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 3.19.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@cheqd-bot cheqd-bot Bot added the released label Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants