Skip to content

fix(browser): gate certificate proceed on runtime capability; dedupe cert-error helpers#9070

Merged
AmethystLiang merged 1 commit into
mainfrom
issue-8454-built-browser-cant
Jul 19, 2026
Merged

fix(browser): gate certificate proceed on runtime capability; dedupe cert-error helpers#9070
AmethystLiang merged 1 commit into
mainfrom
issue-8454-built-browser-cant

Conversation

@AmethystLiang

@AmethystLiang AmethystLiang commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the certificate-trust feature (issue #8454). Hardens the "Proceed Anyway (Unsafe)" affordance and dedupes the certificate-error helpers.

  • Gate proceed on runtime capability. A remote runtime that predates browser.certificate-trust.v1 cannot honor a proceed request, so RemoteBrowserPagePane now hides the proceed affordance until the connected runtime positively advertises the capability (probed via runtimeEnvironmentSupportsCapability). The error page still renders — only the unactionable "Proceed Anyway" button is suppressed. Desktop/built browsers advertise the capability whenever they can host a page, so the local HTTPS-dev-server case keeps its proceed button.
  • Single certificate-error normalizer. Extracts normalizeCertificateError into src/shared/browser-certificate-errors.ts so the main-process certificate-error handler and the renderer overlay can never silently diverge on challenge matching (browser-certificate-identity.ts re-exports it for existing importers).
  • Centralize load-error redaction. Both the did-fail-load path and the synthesized certificate failure now build load errors through one BrowserManager.buildLoadError, so Kagi session-token redaction can't be forgotten by a future call site.
  • Fail-closed logging. The trust controller's catch now logs before answering false, so a throw during challenge recording no longer presents as "the cert prompt never appears" with no trace.

Screenshots

No visual change in the supported case. In the unsupported-runtime case the "Proceed Anyway (Unsafe)" button no longer appears on the load-failure overlay.

Testing

  • pnpm lint (oxlint on changed dirs — no new findings)
  • pnpm typecheck (web + node projects — clean)
  • pnpm test (browser-certificate-trust-controller.test.ts, runtime-rpc-client.test.ts — 34 passed)
  • pnpm build
  • Existing unit tests cover the trust-controller fail-closed path and the capability-probe cache; the gating is a thin prop guard over already-tested surfaces.

AI Review Report

Reviewed correctness of the capability gate, the helper extraction, and the logging change.

  • Verified passing certificateFailure={null} suppresses only the proceed button — the overlay body is driven by loadError, so the error page still renders.
  • Confirmed browser.certificate-trust.v1 is a conditional capability (advertised whenever canBrowse), matching browser.headless.v1, so desktop/built browsers keep proceed while pre-feature remote runtimes hide it.
  • Checked the useEffect probe has complete deps and a cancelled guard against out-of-order resolution.
  • Confirmed all normalizeCertificateError importers still resolve after the move.
  • Cross-platform: change is browser-pane/main-process logic with no new shortcuts, labels, paths, or shell invocations; no platform-specific branches touched.

Security Audit

  • Load-error redaction is now centralized, reducing the chance a future call site leaks a Kagi session token from an untrusted URL.
  • The capability gate fails closed (defaults to unsupported, .catch → unsupported), so a probe error hides proceed rather than exposing an unactionable bypass.
  • No new input handling, command execution, auth, or secret paths introduced. IPC surface is the existing status.get capability probe.

Notes

The proceed affordance for the local webview pane (BrowserPagePane) is intentionally left ungated — the local runtime always owns its browser pages and advertises the capability.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds scoped local HTTPS certificate approval with in-memory challenge and grant tracking, certificate identity hashing, request isolation, navigation invalidation, and typed IPC/runtime approval paths. Browser failure metadata now flows through main process, preload, runtime synchronization, and renderer state. A shared overlay presents HTTPS recovery and certificate actions. URL classification is centralized, localization is expanded, and unit, integration, and end-to-end tests cover approval isolation and lifecycle behavior.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.13% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately reflects the main change: gating certificate proceed by runtime capability and deduping certificate-error helpers.
Description check ✅ Passed The description matches the required template and includes all major sections with sufficient detail on summary, screenshots, testing, review, security, and notes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/runtime/orca-runtime.ts (1)

2929-2963: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Advertise browser.certificate-trust.v1 for desktop browser hosts too.
BrowserManager wires certificate-trust handling through both desktop webviews and offscreen guests, so gating this capability on hasOffscreen alone leaves renderer-backed hosts unable to surface the enabled proceed action.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d0f8da1a-4362-4b5a-92c8-45fd75af826a

📥 Commits

Reviewing files that changed from the base of the PR and between 64181fd and 4865ad5.

📒 Files selected for processing (55)
  • docs/reference/browser-local-https-certificate-trust.md
  • src/main/browser/agent-browser-bridge.test.ts
  • src/main/browser/agent-browser-bridge.ts
  • src/main/browser/browser-certificate-challenge.ts
  • src/main/browser/browser-certificate-identity.ts
  • src/main/browser/browser-certificate-request-guard.ts
  • src/main/browser/browser-certificate-trust-controller.test.ts
  • src/main/browser/browser-certificate-trust-controller.ts
  • src/main/browser/browser-manager-grab.test.ts
  • src/main/browser/browser-manager.test.ts
  • src/main/browser/browser-manager.ts
  • src/main/browser/browser-session-registry.persistence.test.ts
  • src/main/browser/browser-session-registry.test.ts
  • src/main/browser/browser-session-registry.ts
  • src/main/index.ts
  • src/main/ipc/browser.test.ts
  • src/main/ipc/browser.ts
  • src/main/runtime/orca-runtime-browser.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/browser-core.ts
  • src/main/runtime/rpc/methods/browser-schemas.ts
  • src/main/runtime/runtime-rpc.test.ts
  • src/preload/api-types.ts
  • src/preload/index.ts
  • src/renderer/src/components/browser-pane/BrowserPane.tsx
  • src/renderer/src/components/browser-pane/browser-load-failure-overlay.test.tsx
  • src/renderer/src/components/browser-pane/browser-load-failure-overlay.tsx
  • src/renderer/src/components/browser-pane/browser-notices.test.ts
  • src/renderer/src/components/browser-pane/browser-notices.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-classifier.test.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-url-classification.ts
  • src/renderer/src/hooks/useIpcEvents.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/runtime/remote-server-parity.test.ts
  • src/renderer/src/runtime/sync-runtime-graph-browser.test.ts
  • src/renderer/src/runtime/sync-runtime-graph.ts
  • src/renderer/src/runtime/web-session-tabs-sync.test.ts
  • src/renderer/src/runtime/web-session-tabs-sync.ts
  • src/renderer/src/store/slices/browser.test.ts
  • src/renderer/src/store/slices/browser.ts
  • src/renderer/src/web/web-preload-api.ts
  • src/shared/browser-certificate-errors.ts
  • src/shared/browser-url.test.ts
  • src/shared/browser-url.ts
  • src/shared/protocol-version.ts
  • src/shared/runtime-types.ts
  • src/shared/types.ts
  • tests/e2e/browser-local-https-certificate-trust.spec.ts
  • tests/e2e/helpers/local-https-test-certificate.ts
  • tests/e2e/helpers/local-https-test-server.ts

Comment thread src/main/browser/browser-certificate-request-guard.ts
Comment thread src/main/browser/browser-manager.ts
Comment thread src/renderer/src/components/browser-pane/BrowserPane.tsx
Comment thread tests/e2e/helpers/local-https-test-server.ts
@nwparker

Copy link
Copy Markdown
Contributor

Superseded by #9104 — takes this design/implementation (credit @AmethystLiang), rebases onto current main, resolves conflicts, and applies adversarial hardening from review. Thanks for the solid design doc + full stack work.

Only offer 'Proceed Anyway (Unsafe)' if the connected remote runtime
advertises browser.certificate-trust.v1 support. Older runtimes cannot
honor the request and would fail silently, creating a false affordance.

Centralize certificate error normalization to prevent divergence
between main and renderer certificate matching, and unify URL redaction
for Kagi session token stripping across load-error paths.
@AmethystLiang
AmethystLiang force-pushed the issue-8454-built-browser-cant branch from 4865ad5 to e21a05a Compare July 19, 2026 04:58
@AmethystLiang AmethystLiang changed the title Issue 8454 built browser cant fix(browser): gate certificate proceed on runtime capability; dedupe cert-error helpers Jul 19, 2026
@AmethystLiang
AmethystLiang merged commit e074bc3 into main Jul 19, 2026
3 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.

2 participants