Skip to content

fix(setup): sync Windows CA certificates to WSL before CLI install#819

Open
jkf87 wants to merge 2 commits into
openclaw:mainfrom
jkf87:fix/sync-windows-ca-certs-to-wsl
Open

fix(setup): sync Windows CA certificates to WSL before CLI install#819
jkf87 wants to merge 2 commits into
openclaw:mainfrom
jkf87:fix/sync-windows-ca-certs-to-wsl

Conversation

@jkf87

@jkf87 jkf87 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Problem

On corporate/enterprise networks a TLS-intercepting proxy injects a self-signed certificate into the chain. WSL Ubuntu's curl does not trust Windows-managed certificates by default, so install-cli fails with:

curl: (60) SSL certificate problem: self-signed certificate in certificate chain

Confirmed from setup log (setup-engine-20260625-023033.jsonl):

cmd.done: wsl.exe exit=60 (2132ms)
stderr: curl: (60) SSL certificate problem: self-signed certificate in certificate chain
step.completed: install-cli → Failed

This affects any Windows machine on a network with TLS inspection (common in enterprise environments).

Fix

Add SyncWindowsCaCertsStep between ValidateWslLockdownStep and InstallCliStep:

  1. Read Windows LocalMachine\Root + LocalMachine\CA certificate stores via X509Store and serialise to PEM
  2. Write the bundle directly to the WSL distro via \wsl$\<distro>\usr\local\share\ca-certificates\windows-ca-bundle.crt (no stdin piping needed)
  3. Run update-ca-certificates as root in WSL so curl picks up the corporate CA trust anchors

The step is non-fatal: if the Windows cert store is unreadable, the UNC path is unreachable, or update-ca-certificates warns, the step logs and continues — so non-proxied setups are completely unaffected.

RollbackAsync removes the written bundle on uninstall.

Test plan

  • Run setup on a machine behind a TLS-intercepting proxy — install-cli should now succeed
  • Run setup on a standard (non-proxied) network — no behaviour change, step completes in < 1 s
  • Uninstall — confirm windows-ca-bundle.crt is removed from WSL

🤖 Generated with Claude Code

jkf87 and others added 2 commits June 19, 2026 08:50
…utdown

On Windows, after `wsl --terminate` + `wsl --shutdown`, the localhost
proxy process that forwards 127.0.0.1:18789 → WSL2 may take longer than
the previous fixed 3-second delay to release the port.  When that
happened the next step (`preflight-port`) immediately hard-failed with
AddressAlreadyInUse and `CanRetry = false`, leaving the user stuck.

Changes:
- Add `PreflightPortStep.WaitForPortFreeAsync` — polls CanBind every
  500 ms up to a configurable ceiling (default 20 s) and returns as soon
  as the port is free, logging elapsed time when it had to wait.
- Replace the fixed `Task.Delay(3000)` in `CleanupStaleDistroStep` with
  a call to `WaitForPortFreeAsync` so cleanup waits only as long as
  needed and never longer than necessary.
- `PreflightPortStep.ExecuteAsync` also calls `WaitForPortFreeAsync`
  (10 s ceiling) before the hard check as belt-and-suspenders for the
  case where cleanup was skipped and something else holds the port
  briefly.
- Expose `CanBind` as `internal static` to enable reuse across the two
  classes and in new tests.
- Add three unit tests covering: immediate return when port is free,
  successful poll until port is released mid-wait, and full
  `ExecuteAsync` succeeding after a simulated 300 ms proxy teardown lag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On corporate/enterprise networks a TLS-intercepting proxy injects a
self-signed certificate that WSL Ubuntu's curl does not trust, causing
`install-cli` to fail with exit 60:

  curl: (60) SSL certificate problem: self-signed certificate in
  certificate chain

Fix: add `SyncWindowsCaCertsStep` between `ValidateWslLockdownStep` and
`InstallCliStep` that:

1. Reads the Windows LocalMachine\Root and \CA certificate stores using
   X509Store and serialises them to PEM format.
2. Writes the bundle directly to the WSL distro filesystem via the
   `\wsl$\<distro>\usr\local\share\ca-certificates\` UNC share that
   WSL2 exposes on Windows (no stdin piping required).
3. Runs `update-ca-certificates` as root inside WSL so curl picks up the
   new trust anchors for the install-script download.

The step is intentionally non-fatal: if the Windows cert store cannot be
read, the UNC path is unreachable, or update-ca-certificates warns, the
step logs and continues so non-proxied setups are not affected.
RollbackAsync removes the written bundle file on uninstall.

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

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed June 24, 2026, 10:50 PM ET / 02:50 UTC.

Summary
The PR adds a setup step that exports Windows machine CA certificates into WSL before CLI install and also carries setup port-release polling changes already present on main.

Reproducibility: no. high-confidence current-main reproduction was run here. Source inspection shows current main downloads the installer with curl before any CA import, and the PR body provides a setup log with curl exit 60 behind TLS inspection.

Review metrics: 3 noteworthy metrics.

  • Setup steps changed: 1 step added before install-cli. The new step runs on every default setup before the installer download and changes TLS trust for that download.
  • Changed files: 3 files affected. The branch touches setup pipeline code, setup step code, and setup tests, keeping the code surface bounded.
  • After-fix real setup proof: 0 runs shown. The PR body does not show this branch completing setup after the CA sync on the affected network or on a normal network.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Fix rollback so WSL's generated CA store is refreshed after removing the imported bundle.
  • [P1] Add redacted after-fix setup logs from this branch for both the corporate TLS-inspection network and a normal network.
  • Get maintainer confirmation on whether default Windows machine-root mirroring is acceptable or should become opt-in/warned.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body includes a before-fix setup log and a checklist, but no after-fix real setup run from this branch on either the corporate proxy or normal-network path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The PR changes the managed WSL distro trust store before downloading and running the installer, so maintainers need to accept the default host-root mirroring policy or choose an opt-in/warning path.
  • [P1] The PR body has a before-fix failure log but no after-fix setup log from this branch behind the corporate proxy or on a normal network.
  • [P1] Rollback currently removes only the source certificate file and can leave generated WSL trust-store artifacts active after rollback or uninstall.

Maintainer options:

  1. Fix cleanup and prove setup before merge (recommended)
    Update rollback to refresh WSL's generated CA store after removing the bundle, then require redacted real setup logs for corporate-proxy and normal-network installs.
  2. Accept default trust mirroring explicitly
    Maintainers can choose to accept default Windows machine-root mirroring, but should still require the rollback repair and after-fix setup proof.
  3. Pause in favor of the earlier trust-policy PR
    If maintainers want the broader stdin-based approach or a config policy first, keep this branch paused until fix: import Windows root CA certs into WSL before CLI install (fix curl exit 60) #693 is resolved.

Next step before merge

  • [P1] Needs maintainer/security judgment on trust policy plus contributor-supplied real setup proof; ClawSweeper should not queue an automated repair while proof is missing.

Security
Needs attention: The diff intentionally broadens WSL installer TLS trust and currently leaves a concrete cleanup gap in rollback.

Review findings

  • [P1] Regenerate the WSL CA store on rollback — src/OpenClaw.SetupEngine/SetupSteps.cs:1238-1239
Review details

Best possible solution:

Land the enterprise CA repair only after rollback fully removes generated trust-store state, maintainers accept the trust policy, and redacted end-to-end setup logs prove both corporate-proxy and normal-network behavior.

Do we have a high-confidence way to reproduce the issue?

No high-confidence current-main reproduction was run here. Source inspection shows current main downloads the installer with curl before any CA import, and the PR body provides a setup log with curl exit 60 behind TLS inspection.

Is this the best way to solve the issue?

No, not as submitted. The CA sync may be the right repair direction, but rollback must refresh the WSL trust store and maintainers still need to accept the default trust policy with real setup proof.

Full review comments:

  • [P1] Regenerate the WSL CA store on rollback — src/OpenClaw.SetupEngine/SetupSteps.cs:1238-1239
    After this step runs update-ca-certificates, deleting only windows-ca-bundle.crt leaves the generated WSL CA store stale, so rollback or uninstall can leave the imported Windows trust active. Refresh the CA store after removing the file and cover that rollback path.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 4e7982bafb86.

Label changes

Label changes:

  • add P2: This is a normal-priority setup reliability fix for enterprise networks, with bounded user impact and clear merge-readiness blockers.
  • add merge-risk: 🚨 security-boundary: The PR changes the managed WSL distro TLS trust store before downloading and running the CLI installer.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body includes a before-fix setup log and a checklist, but no after-fix real setup run from this branch on either the corporate proxy or normal-network path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P2: This is a normal-priority setup reliability fix for enterprise networks, with bounded user impact and clear merge-readiness blockers.
  • merge-risk: 🚨 security-boundary: The PR changes the managed WSL distro TLS trust store before downloading and running the CLI installer.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body includes a before-fix setup log and a checklist, but no after-fix real setup run from this branch on either the corporate proxy or normal-network path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

Security concerns:

  • [medium] Rollback can leave imported CA trust active — src/OpenClaw.SetupEngine/SetupSteps.cs:1238
    The new step runs update-ca-certificates after writing the bundle, but rollback only deletes the source bundle file and does not regenerate the WSL trust store, leaving generated trust artifacts behind after rollback or uninstall.
    Confidence: 0.86
  • [medium] Default trust-store mirroring needs policy approval — src/OpenClaw.SetupEngine/SetupSteps.cs:1206
    The setup flow imports Windows machine CA roots/intermediates into the managed WSL distro before installer download, which intentionally broadens what can terminate TLS for the installer path and should be an explicit maintainer decision.
    Confidence: 0.78

What I checked:

Likely related people:

  • jkf87: Current main includes recent WSL setup port-release polling work by this author in the same SetupSteps and setup-test area. (role: recent setup contributor; confidence: medium; commits: 09298e6b3c57; files: src/OpenClaw.SetupEngine/SetupSteps.cs, tests/OpenClaw.SetupEngine.Tests/SetupStepsTests.cs)
  • RBrid: Local blame and GitHub commit metadata for the current SetupStepFactory and InstallCliStep baseline point to this author, though the checkout has grafted history. (role: baseline setup implementation contributor; confidence: low; commits: 6623cb8410a4; files: src/OpenClaw.SetupEngine/SetupSteps.cs, src/OpenClaw.SetupEngine/SetupPipeline.cs)
  • ranjeshj: Recent history includes setup-step refactoring in SetupSteps.cs, making this a plausible adjacent reviewer for setup ownership boundaries. (role: recent adjacent setup contributor; confidence: low; commits: d4284d43fb6a; files: src/OpenClaw.SetupEngine/SetupSteps.cs)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant