Skip to content

Release 2026.07.22 (v2.4.0) - #40

Merged
aviba merged 15 commits into
mainfrom
release/2026.07.22
Jul 22, 2026
Merged

Release 2026.07.22 (v2.4.0)#40
aviba merged 15 commits into
mainfrom
release/2026.07.22

Conversation

@mgk-fb

@mgk-fb mgk-fb commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • WebSocket push delivery (v2.4.0 — default-on, opt-out with WEBSOCKET_ENABLED=false)
  • Process-level unhandledRejection / uncaughtException handlers
  • Cluster mode example server (docs/cluster-setup-guide.md, docker-compose.cluster.yml, nginx.conf)

Cleanup

  • Removed committed env files; .env.example updated with new WEBSOCKET_ENABLED and optional WS tuning vars
  • Fixed package.json repository URL

After merge

Tag the merge commit as 2026.07.22:

git tag 2026.07.22 <merge-commit-sha>
git push origin 2026.07.22

🤖 Generated with Claude Code

cshooker-tech and others added 13 commits July 20, 2026 07:00
The example customer server signs serially: one process, one PKCS#11
session, and synchronous pkcs11js calls that block Node's single event
loop, capping signing throughput at about one CPU core.

Add an opt-in docker-compose.cluster.yml that scales signing across
cores on a single host: nginx (sole published port, optional TLS
termination) routes /api/hsm/ (key generation, token writes) to a
single primary replica and round-robins /api/ (signing, token reads)
across a scalable signer pool. All replicas share the existing SoftHSM
token volumes and MongoDB. The default single-process compose file and
its per-process SSL behavior are unchanged.

Document how to run, how to choose the replica count, the
keygen-single-process and restart-after-keygen caveats, and the SSL
model per mode in examples/server/README.md.
Every sign/verify re-scanned the whole token via C_FindObjects; with
many keys on the token this scan dominates signing latency. PKCS#11
object handles stay valid for the lifetime of the session (the process
lifetime here), so keep a per-process map from key id to handle and
skip the scan after the first lookup.
Required by the check_version_change CI job, which expects every merge
request to modify AGENT_VERSION in src/version.ts.
Review feedback: the example mongo has no authentication, so the new
cluster compose file no longer publishes 27017 on the host. The
customer-server containers reach it over the internal Docker network.
This reverts commit f51b29579e52efbf2890d5e5011a4fe4c449d298.

The security pre-merge check rightly expects tests around changed key
handling, and examples/server has no test infrastructure today. Keep
this MR scoped to the opt-in cluster mode; the per-process handle cache
(skipping the per-sign C_FindObjects token scan) is noted in the MR
description as a recommended follow-up together with test coverage.
The format and test jobs ran 'npm install' against the public registry
(registry.npmjs.org), which is unreachable from the Fireblocks CI runners
(ECONNREFUSED), so both jobs failed. Add the shared configure_jfrog_npmrc
before_script (writes an .npmrc pointing at the internal JFrog registry,
authed via JFROG_NPM_READ_TOKEN) to the format and test jobs, matching the
working setup on !21.
Address CodeRabbit review on !20: (1) the guide claimed cluster mode needs Agent v2.4.0+, but this MR ships AGENT_VERSION 2.2.9 -> correct to v2.2.9+; (2) the 'port already allocated' troubleshooting row said `docker compose down`, which only stops the single-process compose and leaves a cluster instance running -> document `docker compose -f docker-compose.cluster.yml down` for cluster mode.
main advanced (via !19) to AGENT_VERSION 2.3.0, which conflicted with this
branch's 2.2.9. Resolve by bumping to 2.4.0 (the version the cluster-setup
guide already documents for cluster mode) and align the guide's "Applies to"
line back to v2.4.0+ so code and docs match.
- Remove .gitlab-ci.yml (internal CI; JFrog npmrc goes with it)
- Remove .env.local/.env.prod/.env.test; add .env.example with
  placeholders including new WEBSOCKET_ENABLED and WS tuning vars
- Update .gitignore to exclude .env* (allow .env.example)
- Fix package.json: GitHub repo URL, drop @semantic-release/gitlab
- Add CHANGELOG 2.4.0 entry (WebSocket delivery, resilience, cluster mode);
  strip GitLab hyperlinks from historical entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@socket-security

socket-security Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​ws@​8.18.11001007380100
Addedws@​8.21.19910010097100

View full report

ws@7.4.6, ws@7.5.11, ws@8.21.1 and @types/ws@8.18.1 were resolved
from the internal Artifactory mirror — unreachable from GitHub CI.
Point all four back to registry.npmjs.org. Integrity hashes unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread package-lock.json
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"version": "8.21.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:
package-lock.json contains a reference to a public package registry or CDN (https://registry.npmjs.org/ws/-/ws-8.21.1.tgz). Dependencies must be resolved through the approved internal JFrog/Artifactory registry. Update your .npmrc to point at the approved registry, delete node_modules and package-lock.json, then re-run npm install and commit the regenerated lockfile.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
"resolved": "https://example.com/artifactory/api/npm/npm/ws/-/ws-8.21.1.tgz",
View step-by-step instructions
  1. Update the project’s .npmrc so npm uses the approved internal registry instead of the public npm registry. Set registry= to your internal JFrog/Artifactory URL, for example registry=https://example.com/artifactory/api/npm/npm/.

  2. Add the lockfile replacement setting to .npmrc if your environment requires it, so regenerated entries use the internal host consistently. For example, keep .npmrc with only approved registry settings such as registry=https://example.com/artifactory/api/npm/npm/.

  3. Delete the existing lockfile and installed modules so npm can regenerate resolved URLs from the approved registry. Remove package-lock.json and node_modules/.

  4. Regenerate dependencies through the internal registry by running npm install after the .npmrc change. This should recreate package-lock.json with resolved entries that point to your internal registry instead of https://registry.npmjs.org/....

  5. Confirm the specific ws entry now resolves through the internal registry, for example the node_modules/ws lockfile entry should use your approved Artifactory/JFrog URL rather than the public registry.npmjs.org tarball URL.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by block-public-registry-refs-in-package-lock.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment thread package-lock.json
},
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:
package-lock.json contains a reference to a public package registry or CDN (https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz). Dependencies must be resolved through the approved internal JFrog/Artifactory registry. Update your .npmrc to point at the approved registry, delete node_modules and package-lock.json, then re-run npm install and commit the regenerated lockfile.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
"resolved": "https://example.com/artifactory/api/npm/npm/@types/ws/-/ws-8.18.1.tgz",
View step-by-step instructions
  1. Update your project’s npm registry configuration to use the approved internal JFrog/Artifactory registry instead of the public npm registry.
    Add or update .npmrc with registry=https://example.com/artifactory/api/npm/npm/ or your approved internal registry URL.

  2. Remove any npm settings that force public downloads, such as @scope:registry=https://registry.npmjs.org/ or direct registry=https://registry.npmjs.org/ entries in .npmrc, user-level npm config, or CI config.

  3. Regenerate the lockfile so the resolved entries are rewritten to the internal registry.
    Run $ rm -rf node_modules package-lock.json and then $ npm install.
    The new package-lock.json should replace entries like https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz with your internal registry URL.

  4. Verify that the regenerated lockfile no longer contains public URLs in resolved, registry, or tarball fields for packages such as @types/ws and @types/node.
    This works because package-lock.json records the exact download source used during install.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by block-public-registry-refs-in-package-lock.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment thread package-lock.json
Removing .env.prod over-cleaned: it is non-secret (empty auth token,
public gateway URL) and is the project's shipped default config, required
by `npm run build` (copy:env), the test suite (dotenv loads .env.prod for
MOBILE_GATEWAY_URL), the Dockerfile (COPY .env.prod), and the README.

Restore it, gitignore-allow it (!.env.prod), and drop .env.example (the
README uses .env.prod as the template). .env.local/.env.test stay removed
(dev/test scaffolding with demo JWTs). Build + 184 tests pass on Node 20.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aviba
aviba merged commit 510b221 into main Jul 22, 2026
4 checks passed
AmeerAssadi pushed a commit that referenced this pull request Jul 27, 2026
- WebSocket push delivery, default-on (opt out with WEBSOCKET_ENABLED=false)
- Process-level unhandledRejection / uncaughtException handlers
- Cluster mode for the example customer server (see docs/cluster-setup-guide.md)
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.

4 participants