Skip to content

engine: migrate platform-neutral crypto to Web Crypto#145

Merged
willwashburn merged 1 commit into
mainfrom
fix-143-web-crypto-engine
May 31, 2026
Merged

engine: migrate platform-neutral crypto to Web Crypto#145
willwashburn merged 1 commit into
mainfrom
fix-143-web-crypto-engine

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Summary

  • add Web Crypto helpers for SHA-256, HMAC-SHA-256, random hex, and UUID generation
  • update @relaycast/engine auth, middleware, and engine modules to stop importing node:crypto outside Node adapters
  • make token hashing async through the AuthProvider surface and await direct lookup call sites
  • add engine crypto helper tests

Validation

  • npm run build -- --filter=@relaycast/engine
  • npm run test -- --filter=@relaycast/engine
  • npm run lint -- --filter=@relaycast/engine (0 errors; existing warnings remain)
  • rg node:crypto/createHash/randomBytes/createHmac in packages/engine/src excluding adapters/node returned no matches

Closes #143

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR migrates the @relaycast/engine package from Node's node:crypto module to the Web Crypto API to enable Cloudflare Workers deployments without the nodejs_compat flag. The primary challenge is that Web Crypto's digest operations are async, so token hashing, key generation, and HMAC signing throughout the request path become asynchronous. New shared crypto helpers abstract the Web Crypto implementation; the AuthProvider.hashToken contract becomes async and all callers updated to await results.

Changes

Crypto Migration to Web Crypto

Layer / File(s) Summary
Crypto utilities foundation
packages/engine/src/lib/crypto.ts, packages/engine/src/lib/__tests__/crypto.test.ts
New module exports sha256Hex, hmacSha256Hex (async), and randomHex, randomUuid (sync) using Web Crypto API. Tests verify SHA-256 and HMAC-SHA-256 digests and validate random output patterns.
Auth contract and implementation
packages/engine/src/ports/auth.ts, packages/engine/src/auth/index.ts, packages/engine/src/engine.ts
AuthProvider.hashToken becomes async. SqliteApiKeyAuthProvider delegates to sha256Hex. WebSocket handler awaits token hash before workspace/agent lookup, preserving validation and error flows.
Token and API key generation
packages/engine/src/engine/agent.ts, packages/engine/src/engine/tokenRotate.ts, packages/engine/src/engine/workspace.ts, packages/engine/src/engine/inboundWebhook.ts
Agent registration and rotation now use randomHex(16) for raw material and async sha256Hex for hashing. Workspace API key generation and inbound webhook provisioning adopt the same async pattern, with call sites awaiting hash computation.
Event signing and random IDs
packages/engine/src/engine/eventDelivery.ts, packages/engine/src/engine/a2a.ts, packages/engine/src/engine/certify.ts
Event delivery signPayload becomes async via hmacSha256Hex; relay signature header awaits result. Certification and A2A message IDs replace crypto.randomUUID() with randomUuid() across multiple generation callsites.
Deterministic keys and middleware
packages/engine/src/engine/dm.ts, packages/engine/src/middleware/idempotency.ts, packages/engine/src/middleware/logger.ts
DM pair key derivation becomes async with sha256Hex. Idempotency key building now async, computing scope/key digests concurrently. Logger middleware generates request IDs via randomUuid() and refactors identifier hashing to precompute actor/IP/UA hashes asynchronously.
A2A route integration
packages/engine/src/routes/a2a.ts
Route handlers await hashToken for bearer token validation; conditional null-coalescing ensures safe hash comparison against stored relayAgent.tokenHash.
Task completion documentation
.trajectories/completed/2026-05/traj_gk8yfvbi52hm.json, .trajectories/completed/2026-05/traj_gk8yfvbi52hm.md, .trajectories/index.json
Trajectory records completion of issue #143, documenting Web Crypto migration in @relaycast/engine and scope constraint to engine only (server package frozen). Index entry and timestamps added.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

  • AgentWorkforce/relaycast#138: Introduced the initial AuthProvider.hashToken interface and SqliteApiKeyAuthProvider implementation in packages/engine/src/auth/index.ts; this PR makes both asynchronous and updates all call sites to handle the async contract.

🐰 Web Crypto blooms in every Workers request,
No nodejs_compat flag—our engine's truly blessed!
Async hashes dance where synchronous bytes once lay,
Platform-neutral crypto leads the Workers way.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: migrating platform-neutral crypto to Web Crypto in the engine package.
Description check ✅ Passed The description provides a comprehensive overview of the changes including crypto helper additions, module updates, async hashing changes, and validation performed.
Linked Issues check ✅ Passed The PR fully implements issue #143 objectives: it adds Web Crypto helpers, migrates away from node:crypto in platform-neutral code, makes hashing async, updates call sites, and excludes Node adapters.
Out of Scope Changes check ✅ Passed All changes are scoped to issue #143: Web Crypto migration in @relaycast/engine. The trajectory files document the task completion and the crypto implementation is limited to engine with server kept unchanged.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-143-web-crypto-engine

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the platform-neutral crypto usage in @relaycast/engine from the Node.js node:crypto module to standard Web Crypto APIs. A new utility file packages/engine/src/lib/crypto.ts is introduced, containing helper functions for SHA-256 hashing, HMAC signatures, random hex generation, and UUID generation. Because the Web Crypto APIs are asynchronous, several internal functions (such as hashToken, signPayload, and buildKey) have been updated to return promises, and their callers have been updated to use await or Promise.all. Unit tests have also been added to verify the new crypto helpers. No review comments were provided, so there is no additional feedback.

@github-actions

Copy link
Copy Markdown

Preview deployed!

Environment URL
API https://pr145-api.relaycast.dev
Health https://pr145-api.relaycast.dev/health
Observer https://pr145-observer.relaycast.dev/observer

This preview shares the staging database and will be cleaned up when the PR is merged or closed.

Run E2E tests

npm run e2e -- https://pr145-api.relaycast.dev --ci

Open observer dashboard

https://pr145-observer.relaycast.dev/observer

@willwashburn willwashburn merged commit 2db213d into main May 31, 2026
5 of 6 checks passed
@willwashburn willwashburn deleted the fix-143-web-crypto-engine branch May 31, 2026 07:18
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.

engine: migrate node:crypto → Web Crypto so Workers deploys can drop nodejs_compat

1 participant