Skip to content

fix: better cors handling#443

Merged
hanneshapke merged 1 commit into
mainfrom
fix/update-mitm-proxy
May 14, 2026
Merged

fix: better cors handling#443
hanneshapke merged 1 commit into
mainfrom
fix/update-mitm-proxy

Conversation

@hanneshapke
Copy link
Copy Markdown
Collaborator

@hanneshapke hanneshapke commented May 14, 2026

Summary

The bundled browser demo at src/scripts/app_demo/ was failing with Failed to fetch / ERR_CERT_AUTHORITY_INVALID. Two underlying issues:

  1. No CORS on intercepted traffic. Upstream LLM APIs (api.openai.com, etc.) don't return browser-friendly CORS headers, so any page calling them via fetch gets blocked by the browser. The transparent proxy was forwarding preflights upstream and copying upstream headers verbatim — neither produced anything usable for a browser.
  2. Legacy CA branding. CertManager was still generating certs with CN/O Yaak Proxy CA (pre-rebrand leftover), which (a) didn't match what docs and the settings modal told users to look for, and (b) caused stale entries in the system keychain to be orphaned across upgrades.

Also rolled up some smaller polish from the same session.

Changes

Backend — CORS on intercepted responses (src/backend/proxy/)

  • New cors.go with shared helpers: setCORSHeaders, writeCORSPreflight (for http.ResponseWriter), writeCORSPreflightOverTLS (for raw MITM net.Conn), and drainAndClose.
  • transparent.go: in both interceptHTTP (plain) and interceptHTTPOverTLS (MITM-decrypted TLS):
    • Short-circuit OPTIONS preflights → respond 204 No Content + CORS headers, do not forward upstream.
    • Inject CORS headers on the normal response after the upstream header copy, so any incompatible CORS values from the provider get overridden.
  • Header policy: echoes Origin (or *), echoes Access-Control-Request-Headers from the preflight, allows common methods, exposes all response headers, 1h max-age.

Backend — CA rename (src/backend/proxy/certmanager.go)

  • Root CA CN/O: Yaak Proxy CAKiji Privacy Proxy CA.
  • Leaf cert O: Yaak ProxyKiji Privacy Proxy.
  • No other Yaak references remain in src/backend.

Frontend — CA cert setup modal (src/frontend/src/components/modals/CACertSetupModal.tsx)

  • Fixed the install command: the path ~/Library/Application Support/Kiji Privacy Proxy/certs/ca.crt contains spaces, so the shell was splitting it across four security arguments. Now uses ~/"Library/Application Support/..." so ~ still expands while the rest is quoted.
  • Made the command block copiable: added a top-right Copy button that writes the command (with real newlines, not <br>) to the clipboard via navigator.clipboard.writeText and flips to a green Check + "Copied" badge for 2s.
  • Switched the static <code> with <br>s to a <pre><code> driven by a single string constant, so what's rendered and what's copied are guaranteed to match.

Docs (docs/05-advanced-topics.md)

  • New ### Browser-Based Clients (CORS) subsection under ## Transparent Proxy & MITM — explains the preflight short-circuit, response-header injection, the full table of headers added, where the policy lives, prerequisites for browser callers, and the app_demo as an end-to-end verifier.
  • New #### Migrating from "Yaak Proxy CA" under ### Removing Trust — bash to delete the legacy cert from System + login keychains and the on-disk ca.crt/ca.key so the rebuilt backend regenerates under the new name.

Migration for existing dev installs

After pulling this branch you'll need to rotate the CA (one time):

# Stop the backend
rm ~/"Library/Application Support/Kiji Privacy Proxy/certs/ca.crt" \
   ~/"Library/Application Support/Kiji Privacy Proxy/certs/ca.key"
sudo security delete-certificate -c "Yaak Proxy CA" /Library/Keychains/System.keychain
make go-backend-dev   # mints a fresh "Kiji Privacy Proxy CA"
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain \
  ~/"Library/Application Support/Kiji Privacy Proxy/certs/ca.crt"
# Full Cmd+Q on Chrome, then reopen

Test plan

  • go vet ./src/backend/proxy/... clean
  • CGO_LDFLAGS="-L./build/tokenizers" go test ./src/backend/proxy/... passes
  • make build-go succeeds
  • tsc --noEmit clean for the modal
  • eslint clean for the modal
  • Manual: run make go-backend-dev, install the freshly-minted CA, start bash src/scripts/app_demo/run_demo.sh, paste an OpenAI key in the demo at http://localhost:8888, confirm a 200 response and PII masking in the backend logs
  • Manual: open the CA Cert Setup modal in the Electron app, click Copy, paste into a terminal, confirm the command executes without "Usage:" complaints

@hanneshapke hanneshapke merged commit a4a506c into main May 14, 2026
12 checks passed
@hanneshapke hanneshapke deleted the fix/update-mitm-proxy branch May 14, 2026 16:26
@github-actions github-actions Bot locked and limited conversation to collaborators May 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant