Skip to content

fix: forward the API and content-gateway config to the browser engine - #1035

Merged
FSM1 merged 3 commits into
mainfrom
fix/986-browser-engine-bootstrap-and-config
Aug 4, 2026
Merged

fix: forward the API and content-gateway config to the browser engine#1035
FSM1 merged 3 commits into
mainfrom
fix/986-browser-engine-bootstrap-and-config

Conversation

@FSM1

@FSM1 FSM1 commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Closes #986
Closes #987
Closes #970

Browser bootstrap and config wiring. No new primitives, no new KDF edges, no codec changes.

#986 — apiBaseUrl reaches the WASM EngineHandle

packages/client/src/worker/engineHost.ts built EngineHandle with all four config arguments hardcoded undefined, so the engine ran against an empty API base and Engine::start() took its if !self.api_base_url.is_empty() branch — skipping api.login_identity() entirely. Every publish, register and upload ran unauthenticated against an empty base.

apiBaseUrl now flows EngineHostConfig to the worker bootstrap to EngineHost to EngineHandle. EngineHost's positional arguments became an options object derived from EngineHostConfig, so the three layers carry one shape rather than three restatements, and spawnEngineWorker posts a checked spread instead of a hand-written field-by-field copy that nothing typechecked.

An absent base fails closed at the WASM boundary, rather than silently skipping login: EngineHandle::new returns a JsError for a missing, empty, or whitespace-only apiBaseUrl, so a misconfigured host cannot bring an engine up unauthenticated. The engine facade keeps its empty-base skip for the Rust harness — see "Deferred" below.

#987 — accelerator and public gateway config surface

Adds VITE_READ_ACCELERATOR_URL and VITE_PUBLIC_GATEWAYS to the apps/web engine config, threaded into GatewayConfig. No default: unset leaves the gateway dormant and reads fail closed as Unavailable, never degrading to an endpoint nobody chose. The network is canonical and every fetched block is CID-verified in crates/engine/src/content/read.rs, so these are accelerator hints, not trust anchors.

Both are wired to repository variables in the staging web-build step; unset substitutes blank and stays dormant, so nothing changes until an admin sets them.

acceleratorBearer is deferred, deliberately. A VITE_-prefixed variable is inlined into the public browser bundle, and the accelerator token is a per-session credential. TypeScript passes undefined; #1033 tracks sourcing it from the session at runtime.

#970 — VITE_WEB3AUTH_VERIFIER reaches every build

Plumbed alongside every existing VITE_WEB3AUTH_CLIENT_ID — 4 sites in deploy-staging.yml, 3 in desktop-staging-release.yml, 2 plus the .env write in web-e2e.yml.

The reason it went unnoticed is that a missing variable is silent at build time, so this also adds a build-time gate: a build naming a deployed environment that lacks a login-critical variable now fails the build instead of shipping a bundle that throws in the browser at first login. VITE_API_URL is gated too — an unset one falls back to http://localhost:3000, which the engine would then authenticate against.

The predicate lives in apps/web/src/engine/config.ts next to the other config-edge validators and is unit-tested; vite.config.ts and createCoreKitSession read the same list, so the gate and the runtime check cannot drift.

Action required before this deploys

Set the VITE_WEB3AUTH_VERIFIER repository variable. This is a repo-admin action that cannot be done from a PR. Without it the staging deploy now goes red at build time rather than green-and-broken — the intended behaviour, but it will block a staging deploy until the variable exists.

Optionally set VITE_READ_ACCELERATOR_URL and VITE_PUBLIC_GATEWAYS; until then staging ships with a dormant content gateway and every content read fails closed as unavailable.

Verification

Automated:

  • cargo fmt --all, cargo clippy --all-targets clean, cargo test -p cipherbox-engine green across 13 suites.
  • cargo check and cargo test -p cipherbox-wasm --target wasm32-unknown-unknown — 16 tests, including a new one asserting the constructor refuses an absent, empty, or whitespace-only apiBaseUrl before it touches the seam bag.
  • pnpm typecheck, pnpm lint, packages/client 316 tests, apps/web 107 tests, typecheck:browser-test.
  • Client Browser Suite, 30 Playwright tests, green. The engine worker now passes a real base, so cold start performs the identity login against a new in-memory mock of /auth/challenge and /auth/login. The mock refuses a login that does not echo a challenge it issued, and the cold-start test asserts the exchange tally moved — so a regression reinstating the login skip fails there rather than passing silently.
  • The build gate was exercised three ways: a staging build missing the verifier fails, one missing VITE_API_URL fails, and an unconfigured vite build — the Web Bundle CI job — stays green.

Puppeteer against vite dev:

Needs a human:

  • A full staging login once the repository variable is set. That is the half of Staging builds never receive VITE_WEB3AUTH_VERIFIER so login throws at session creation #970 no PR can verify — it needs real Web3Auth credentials against the deployed bundle. Steps: set the repo variable, deploy staging, load the app, confirm no must be configured banner, then complete a Google login and an email login and confirm the vault loads.
  • A content read against a real accelerator, once the gateway variables are set.

Review gates

/simplify, /security-review and /crypto-privacy-review all run; findings folded in as a second commit.

The security pass found no HIGH or MEDIUM issues. It confirmed the verifier is a public routing identifier rather than a credential — sourced from vars., exactly like the client id already in the bundle — that no path can source a bearer from build-time config, that a hostile gateway cannot forge content because every block is CID-verified with a mismatch terminal as a trust violation, and that the browser mock does not weaken any gate the Rust and contract suites already cover.

Folded in from the gates: VITE_API_URL added to the deploy gate; the login variable list single-sourced; the accelerator bearer's Zeroizing wrap moved above the constructor's first fallible step so an early return cannot drop it unzeroized; a whitespace-only API base trimmed; the bootstrap handshake given back its type annotation; the browser suite's login assertion made explicit; comments trimmed where they restated a rule stated elsewhere or defended an absent path.

Deferred

All three carry a native blocked_by edge to the issue that unblocked them.

Merge sequencing

crates/engine/src/facade.rs is shared with in-flight work. This PR touches only two comment regions there — the api_base_url field doc and one stale line above the cold-start login guard — and changes no signature in that file. Every signature change is confined to crates/wasm/src/host.rs, whose seven-argument constructor already existed and only changed how it handles api_base_url, and to packages/client.

Summary by CodeRabbit

  • New Features

    • Added support for configuring read accelerators and public content gateways.
    • Improved authentication configuration for web and desktop builds.
    • Engine startup now accepts and forwards API, gateway, accelerator, and storage settings.
  • Bug Fixes

    • Builds now clearly report missing required deployment or authentication settings.
    • Invalid or blank API URLs are rejected instead of silently defaulting.
  • Tests

    • Expanded coverage for authentication, engine startup, gateway configuration, and login flows.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@FSM1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fffe0d25-2043-4140-b2a1-aba78738a94f

📥 Commits

Reviewing files that changed from the base of the PR and between 380d996 and 13001b2.

📒 Files selected for processing (21)
  • .github/workflows/deploy-staging.yml
  • .github/workflows/desktop-staging-release.yml
  • .github/workflows/web-e2e.yml
  • apps/web/src/auth/coreKit.ts
  • apps/web/src/engine/config.test.ts
  • apps/web/src/engine/config.ts
  • apps/web/src/vite-env.d.ts
  • apps/web/vite.config.ts
  • crates/engine/src/facade.rs
  • crates/wasm/src/host.rs
  • packages/client/src/spawnEngineWorker.test.ts
  • packages/client/src/spawnEngineWorker.ts
  • packages/client/src/worker/engineHost.test.ts
  • packages/client/src/worker/engineHost.ts
  • packages/client/src/worker/engineWorker.ts
  • packages/client/src/worker/serve.test.ts
  • packages/client/test/browser/engine.spec.ts
  • packages/client/test/browser/engine.worker.ts
  • packages/client/test/browser/mockAuth.ts
  • packages/client/test/browser/mockMailbox.ts
  • packages/client/test/browser/vite.config.ts

Walkthrough

The change validates required deployment and login variables, propagates API and content gateway settings through the browser engine, requires a nonblank WASM API URL, and adds mock authentication coverage for browser engine startup.

Changes

Engine configuration and authentication

Layer / File(s) Summary
Deployment and login configuration
.github/workflows/*, apps/web/src/engine/*, apps/web/src/auth/coreKit.ts, apps/web/src/vite-env.d.ts, apps/web/vite.config.ts
Web and desktop staging workflows pass Web3Auth settings. Web configuration parses accelerator and gateway values, validates deployment and login variables, and uses shared login validation.
Engine endpoint propagation
packages/client/src/spawnEngineWorker.ts, packages/client/src/worker/*, crates/engine/src/facade.rs, crates/wasm/src/host.rs
Worker bootstrap and EngineHost forward API, accelerator, gateway, profile, and storage settings. EngineHandle::new trims and requires apiBaseUrl.
Browser authentication validation
packages/client/test/browser/*, packages/client/src/worker/engineHost.test.ts, packages/client/src/spawnEngineWorker.test.ts
Mock authentication endpoints issue challenges and validate logins. Tests verify configuration forwarding and one challenge plus one login during engine startup.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • FSM1/cipher-box#728: Introduced related WASM host and client engine worker configuration paths.
  • FSM1/cipher-box#883: Introduced shared web engine configuration paths extended by this change.
  • FSM1/cipher-box#911: Related Web3Auth configuration changes in the authentication and engine configuration paths.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: forwarding API and content-gateway configuration to the browser engine.
Linked Issues check ✅ Passed The changes satisfy the coding objectives for API forwarding, content-read configuration, fail-closed startup, login validation, and Web3Auth workflow plumbing [#986, #987, #970].
Out of Scope Changes check ✅ Passed The workflow, configuration, engine, and test changes directly support the linked issue objectives, with no unrelated code changes identified.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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/986-browser-engine-bootstrap-and-config

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.

@FSM1
FSM1 marked this pull request as ready for review August 4, 2026 20:16

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/engine/config.ts`:
- Around line 81-103: Reject whitespace-only environment values by applying a
trimmed nonblank check in missingLoginEnv and missingDeployEnv, and make
loginEnv reuse that validation for clientId and verifier; in
apps/web/src/engine/config.ts lines 81-103 update these functions accordingly.
In apps/web/src/engine/config.ts lines 72-76, trim VITE_READ_ACCELERATOR_URL and
return undefined when the trimmed value is blank. In
apps/web/src/engine/config.test.ts lines 61-118, add runtime assertions covering
whitespace-only accelerator URL, API URL, client ID, and verifier values.

In `@packages/client/test/browser/mockAuth.ts`:
- Around line 73-78: Update parse to validate the JSON result before returning
it: return the parsed value only when it is a non-null object, otherwise return
{}. Add a runtime test for posting null to the mock auth challenge/login
endpoint and assert it responds with HTTP 400.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c3240753-9c00-4827-a45c-21958d4ba2f9

📥 Commits

Reviewing files that changed from the base of the PR and between 3c08517 and c20527c.

📒 Files selected for processing (21)
  • .github/workflows/deploy-staging.yml
  • .github/workflows/desktop-staging-release.yml
  • .github/workflows/web-e2e.yml
  • apps/web/src/auth/coreKit.ts
  • apps/web/src/engine/config.test.ts
  • apps/web/src/engine/config.ts
  • apps/web/src/vite-env.d.ts
  • apps/web/vite.config.ts
  • crates/engine/src/facade.rs
  • crates/wasm/src/host.rs
  • packages/client/src/spawnEngineWorker.test.ts
  • packages/client/src/spawnEngineWorker.ts
  • packages/client/src/worker/engineHost.test.ts
  • packages/client/src/worker/engineHost.ts
  • packages/client/src/worker/engineWorker.ts
  • packages/client/src/worker/serve.test.ts
  • packages/client/test/browser/engine.spec.ts
  • packages/client/test/browser/engine.worker.ts
  • packages/client/test/browser/mockAuth.ts
  • packages/client/test/browser/mockMailbox.ts
  • packages/client/test/browser/vite.config.ts

Comment thread apps/web/src/engine/config.ts
Comment thread packages/client/test/browser/mockAuth.ts
@FSM1
FSM1 marked this pull request as draft August 4, 2026 20:26
@FSM1
FSM1 force-pushed the fix/986-browser-engine-bootstrap-and-config branch 2 times, most recently from 0a36d32 to 80dd518 Compare August 4, 2026 21:33
FSM1 and others added 3 commits August 4, 2026 23:46
The browser worker built the WASM EngineHandle with every config argument
hardcoded to undefined, so the engine ran against an empty API base and
cold start skipped identity login entirely. Thread apiBaseUrl through
EngineHostConfig, the worker bootstrap, and EngineHost, and refuse an
absent or blank base at the WASM boundary rather than coming up
unauthenticated.

Add the read-accelerator and public-gateway surface alongside it, with no
default: an unconfigured build reads nothing and the engine reports it as
unavailable, never falling back to an endpoint nobody chose. The
accelerator bearer is deferred — it is a session credential and a VITE_
variable ships in the public bundle.

Plumb VITE_WEB3AUTH_VERIFIER through every workflow that builds the web
app, and fail a deployment build whose login-critical environment is
unset so the gap surfaces in CI rather than in the browser at first login.

Closes #986
Closes #987
Closes #970

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Db7mRD4qUCPxkdc8JHqjfo
Requires VITE_API_URL of a deployed build too: an unset one falls back to
localhost, which the engine would then authenticate against. Single-sources
the login variables so the build gate and the Core Kit session cannot drift
apart. Derives the worker bootstrap and the host options from one config
type and posts the handshake as a checked spread, so a field added upstream
reaches the engine without a copy nothing typechecks.

Wraps the accelerator bearer before the constructor's first fallible step
so an early return cannot drop it unzeroized, and trims a whitespace-only
API base. The browser suite now tallies the identity-login exchange, so a
cold start that skipped login fails the gate instead of passing silently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Db7mRD4qUCPxkdc8JHqjfo
The deploy gate tested truthiness, so `VITE_API_URL="   "` passed it and
shipped a bundle that authenticates against whatever answers on the user's
machine — reopening past the gate the very hole the gate was added to close.
A whitespace accelerator was worse than useless: it configured a gateway
source with an unusable base URL, so reads failed per request instead of
staying dormant, which is the fail-closed state chosen deliberately.

One `configured()` helper now backs the gate, the Core Kit accessor and the
accelerator. The API origin is trimmed because it is concatenated into
request URLs, but a blank one never defaults — defaulting would turn the
engine's fail-closed refusal into a silent localhost fallback.

The browser suite's auth mock answered `JSON.parse('null')` by throwing
inside its response callback, leaving the request unanswered so a failure
surfaced as a timeout with no signal. It now answers 400.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Db7mRD4qUCPxkdc8JHqjfo
@FSM1
FSM1 force-pushed the fix/986-browser-engine-bootstrap-and-config branch from 80dd518 to 13001b2 Compare August 4, 2026 21:48
@FSM1
FSM1 marked this pull request as ready for review August 4, 2026 21:52
@FSM1
FSM1 merged commit 5516bd8 into main Aug 4, 2026
23 checks passed
@FSM1
FSM1 deleted the fix/986-browser-engine-bootstrap-and-config branch August 4, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant