Skip to content

Add Tailscale Serve support for WSL gateways#967

Open
andyeskridge wants to merge 4 commits into
openclaw:mainfrom
andyeskridge:codex/tailscale
Open

Add Tailscale Serve support for WSL gateways#967
andyeskridge wants to merge 4 commits into
openclaw:mainfrom
andyeskridge:codex/tailscale

Conversation

@andyeskridge

Copy link
Copy Markdown

Summary

  • Problem: Generated WSL gateways are loopback-only, so Companion cannot use a private tailnet endpoint.
  • Why it matters: Users with Tailscale need secure remote access without LAN exposure, port forwarding, or localhost fallback.
  • What changed: Added opt-in Tailscale Serve provisioning, browser/auth-key authorization, WSS gateway registration, Tailscale-aware recovery, runtime checks, redaction, and docs.
  • User impact: New/replacement generated gateways can publish privately at wss://<wsl-node>.<tailnet>.ts.net; Tailscale identity authentication is trusted when enabled.
  • What did NOT change (scope boundary): No Funnel, Headscale, Tailscale SSH, subnet routing, named services, Windows Tailscale installation/removal, or in-place upgrades of existing gateways.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs / instructions
  • Tests / validation
  • Security hardening
  • Chore / infra

Scope (select all touched areas)

  • Tray / WinUI UX
  • Windows node capability
  • Local MCP / winnode
  • Gateway / connection / pairing
  • Setup / onboarding
  • Permissions / privacy / security
  • Tests / CI / docs

Linked Issue/PR

Validation

  • .\build.ps1
    • Passed: Shared, CLI, WinNode CLI, SetupEngine, and WinUI builds.
  • dotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore
    • Passed: 432, Failed: 0, Skipped: 0.
  • dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore
    • Passed: 2724, Failed: 0, Skipped: 31.
  • dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore
    • Passed: 1668, Failed: 0, Skipped: 0.
  • git diff --check
    • Passed.

Real behavior proof

  • Environment tested: Windows host with authorized Tailscale and MagicDNS; generated OpenClawGateway WSL distro.
  • PR head / commit tested: 12802b95 Add Tailscale Serve support for WSL gateways
  • Exact steps or command run:
    1. Replaced the existing generated WSL gateway through Companion setup with Tailscale Serve enabled.
    2. Authorized the generated WSL Tailscale node in the browser.
    3. Verified WSL status, Serve routing, Windows HTTPS reachability, Companion reconnect, and node invocation.
  • Evidence after fix:
    • WSL Tailscale: BackendState=Running; tailscaled and openclaw-gateway.service active.
    • tailscale serve status --json reported HTTPS on port 443 proxying to http://127.0.0.1:18789.
    • Windows and WSL reported matching MagicDNS tailnets; Windows HTTPS request to the generated .ts.net endpoint returned HTTP 200.
    • Setup state: TailscaleEnabled=true, IsLocalOnly=false, WSS gateway URL.
    • Gateway registry: active app-managed local wss://…ts.net record with SetupManagedDistroName=OpenClawGateway.
    • Live policy verification: gateway.auth.allowTailscale=true, Serve active, and node invocation succeeded.
    • openclaw nodes invoke --node "Windows Node (...)" --command device.info --params '{}' returned "ok": true.
    • Setup log scan found zero tskey-* values and zero Tailscale authorization URLs.
  • Observed result: Companion and its Windows node connected through the generated WSS Tailscale gateway; no localhost fallback was used.
  • Screenshot/artifact links verified? N/A — live command output was used as the direct proof. An isolated setup run was also exercised; the existing-gateway replacement guard was not bypassed for a second visual pass.
  • Not verified / blocked: No Funnel, Headscale, Tailscale SSH, subnet routing, or named Tailscale Services validation; these are intentionally out of scope.

Security Impact (required)

  • New permissions/capabilities? (Yes)
  • Secrets/tokens handling changed? (Yes)
  • New/changed network calls? (Yes)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:
    • Tailscale-enabled gateways trust Tailscale identity authentication via gateway.auth.allowTailscale=true; tailnet ACLs therefore become an authorization control.
    • The feature is opt-in, requires an authorized Windows Tailscale client and matching MagicDNS tailnet, keeps OpenClaw loopback-bound inside WSL, and supports private Serve only—never Funnel.
    • Auth keys are transient, never accepted through CLI arguments or persisted config, and setup logs redact auth keys and Tailscale authorization URLs.
    • Device and token credentials remain available for pairing and compatibility.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (Yes)
  • Migration needed? (No)
  • If yes, exact upgrade steps:
    • No migration is required. Existing gateways remain unchanged.
    • To opt in, create or replace an app-generated WSL gateway and enable Tailnet access with Tailscale Serve.
    • Optional headless inputs: --tailscale, --tailscale-auth browser|auth-key, --tailscale-hostname, and OPENCLAW_SETUP_TAILSCALE_AUTH_KEY for auth-key mode.

Review Conversations

  • [] I replied to or resolved every bot review conversation I addressed in this PR.
  • [] I left unresolved only conversations that still need reviewer or maintainer judgment.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 10, 2026
@clawsweeper

clawsweeper Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed July 10, 2026, 6:34 PM ET / 22:34 UTC.

Summary
The PR adds opt-in Tailscale Serve provisioning, enrollment, private WSS registration, recovery guidance, redaction, documentation, and tests for generated WSL gateways.

Reproducibility: yes. for the patch defect: current-head source directly shows the gateway service account being configured as the Tailscale operator. The requested Tailscale mode itself is a new capability rather than a current-main bug.

Review metrics: 2 noteworthy metrics.

  • Feature surface: 23 files, +1070/-27. The branch crosses setup, WinUI, authentication, persisted setup state, recovery, documentation, and tests.
  • Prior blockers: 1 fixed, 1 remains. The latest commit fixes Serve-backend parsing while leaving operator delegation unchanged.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #966
Summary: This PR is the candidate implementation for the linked open Tailscale Serve feature issue.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

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

Rank-up moves:

  • Remove the gateway account's Tailscale operator authority and provide updated runtime proof for the root-owned path.
  • Obtain maintainer approval for identity authentication versus transport-only Tailscale support.

Risk before merge

  • [P1] The gateway service account receives Tailscale control-plane authority through --operator, so compromise of that account could change or disable the private Serve exposure.
  • [P1] Enabling gateway.auth.allowTailscale=true makes Tailscale identity headers and tailnet ACL configuration a supported gateway authorization boundary.
  • [P1] Setup executes a mutable remote installer as root without content pinning or digest verification, leaving a supply-chain decision that ordinary test coverage cannot settle.

Maintainer options:

  1. Fix privilege separation, then decide identity trust (recommended)
    Remove the gateway-account operator delegation, retain exact Serve validation, and obtain maintainer approval for either identity authentication or transport-only behavior.
  2. Accept the expanded security model
    Merge only with explicit maintainer acceptance of gateway-account Tailscale authority, tailnet identity authorization, and mutable root installer execution.
  3. Pause core provisioning
    Narrow or close the PR if a maintainable privileged control path and long-term security ownership are not justified.

Next step before merge

  • [P2] The privilege repair is concrete, but identity authentication and installer trust require explicit maintainer security judgment before repair automation should modify the branch.

Maintainer decision needed

  • Question: After separating Tailscale administration from the gateway account, should generated gateways support gateway.auth.allowTailscale=true as a core authentication boundary?
  • Rationale: Treating tailnet identity and ACLs as gateway authorization creates a lasting security and product contract that cannot be inferred from implementation correctness or successful runtime proof.
  • Likely owner: steipete — Their merged history owns the generated gateway onboarding architecture where this authentication mode would become a supported product contract.
  • Options:
    • Approve opt-in identity trust (recommended): Support Tailscale identity with clear disclosure, preserved token and device flows, root-owned daemon control, and focused security and failure-path proof.
    • Use private transport only: Provision Tailscale Serve connectivity but continue requiring OpenClaw token or device authentication for every connection.
    • Defer core integration: Pause the feature until authentication policy, installer trust, and long-term Tailscale ownership are established.

Security
Needs attention: The patch adds Tailscale identity trust, gateway-account daemon authority, and mutable remote installer execution as root.

Review findings

  • [P1] Keep Tailscale daemon control out of the gateway account — src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:239
Review details

Best possible solution:

Keep Tailscale daemon and persistent Serve administration root-owned, preserve token and device authentication, and support tailnet identity only after explicit approval of its threat model and installer trust policy.

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

Yes for the patch defect: current-head source directly shows the gateway service account being configured as the Tailscale operator. The requested Tailscale mode itself is a new capability rather than a current-main bug.

Is this the best way to solve the issue?

No, not yet; private Serve over a loopback gateway is focused, but daemon administration must remain least-privileged and the identity-authentication contract needs explicit maintainer approval.

Full review comments:

  • [P1] Keep Tailscale daemon control out of the gateway account — src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:239
    Remove --operator=<gateway user> and keep persistent Serve setup and status operations in a root-owned path. The current code gives the same account that runs OpenClaw control of tailscaled, expanding a gateway-service compromise into the network control plane even though setup can perform this administration without ongoing delegation.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 622c0e27c6b0.

Label changes

Label changes:

  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp. Replaced prior rating: 🦪 silver shellfish.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.

Label justifications:

  • P1: The patch introduces a high-impact privilege-boundary defect in a security-sensitive gateway setup path.
  • merge-risk: 🚨 security-boundary: The PR delegates tailscaled control to the gateway account, trusts tailnet identity for authorization, and executes a mutable remote installer as root.
  • merge-risk: 🚨 auth-provider: The PR adds Tailscale identity and ACL policy as a gateway authorization path alongside existing device and token credentials.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp. Replaced prior rating: 🦪 silver shellfish.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The supplied live output from a real Windows and Tailscale environment directly shows enrollment, Serve routing to the expected backend, HTTPS and WSS reachability, managed registration, node invocation, and redaction behavior.
  • proof: sufficient: Contributor real behavior proof is sufficient. The supplied live output from a real Windows and Tailscale environment directly shows enrollment, Serve routing to the expected backend, HTTPS and WSS reachability, managed registration, node invocation, and redaction behavior.
Evidence reviewed

Security concerns:

  • [high] Gateway account gains Tailscale operator control — src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:239
    The --operator setting allows the account running OpenClaw to administer tailscaled and Serve, broadening the impact of a gateway-account compromise.
    Confidence: 0.98
  • [medium] Tailnet identity becomes an authorization path — src/OpenClaw.SetupEngine/SetupSteps.cs:1417
    Enabling gateway.auth.allowTailscale makes tailnet identity headers and ACL configuration part of the gateway's access-control boundary.
    Confidence: 0.96
  • [medium] Mutable installer executes as root — src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:205
    Setup downloads https://tailscale.com/install.sh and immediately runs it as root without pinning its content or verifying a digest, adding supply-chain execution risk.
    Confidence: 0.94

What I checked:

  • Effective PR scope: The merge-base diff changes 23 files across setup, WinUI, gateway authentication, recovery, documentation, and tests, with 1,070 additions and 27 deletions. (ff211c2d88ea)
  • Prior parser finding fixed: The follow-up commit parses the Tailscale Serve JSON Web handlers and verifies that the proxy URI targets the expected loopback gateway port instead of accepting any occurrence of the port. (src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:94, ff211c2d88ea)
  • Privilege finding remains: Authorization still passes the configured WSL gateway user through tailscale up --operator, granting the account running OpenClaw ongoing Tailscale CLI administration rights, including Serve reconfiguration. (src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:239, ff211c2d88ea)
  • New authentication boundary: Generated gateways are configured to trust Tailscale identity in addition to existing token and device credentials, making tailnet identity and ACL policy part of gateway authorization. (src/OpenClaw.SetupEngine/SetupSteps.cs:1417, ff211c2d88ea)
  • Mutable root installer: The setup downloads tailscale.com/install.sh at runtime and immediately executes it as root without pinning its content or verifying a digest. (src/OpenClaw.SetupEngine/TailscaleSetupSteps.cs:205, ff211c2d88ea)
  • Real behavior proof: The PR body reports a real Windows and Tailscale run demonstrating WSL daemon health, exact Serve proxying, Windows HTTPS reachability, managed WSS registration, Companion reconnection, successful node invocation, and secret-redaction checks. (ff211c2d88ea)

Likely related people:

  • steipete: Merged history introduced the Windows gateway onboarding wizard and maintained its setup behavior; this is the strongest route for deciding whether tailnet identity becomes a supported core authentication contract. (role: generated gateway onboarding owner; confidence: high; commits: adcb4c378f90, 7ad7fcacccf8; files: src/OpenClaw.SetupEngine, src/OpenClaw.SetupEngine.UI, tests/OpenClaw.SetupEngine.Tests)
  • shanselman: History connects this contributor to setup configuration, gateway authentication defaults, connection recovery planning, and existing Tailscale endpoint normalization and classification. (role: setup and connection architecture contributor; confidence: high; commits: 4166e0fd63f8, f78d2ed27ef0, b3a2b4ee75e2; files: src/OpenClaw.SetupEngine/SetupContext.cs, src/OpenClaw.Tray.WinUI/Pages/ConnectionPagePlan.cs, src/OpenClaw.Shared/GatewayUrlHelper.cs)
  • Paul Campbell: Recent merged work integrated Windows node context into the same generated-gateway onboarding pipeline affected by this feature. (role: adjacent setup integration contributor; confidence: medium; commits: 698efcc2bd33; files: src/OpenClaw.SetupEngine, tests/OpenClaw.SetupEngine.Tests)
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.
Review history (1 earlier review cycle)
  • reviewed 2026-07-10T22:13:54.709Z sha 12802b9 :: found issues before merge. :: [P1] Keep Tailscale daemon control out of the gateway account | [P2] Parse the Serve backend instead of matching any quoted port

@andyeskridge

Copy link
Copy Markdown
Author

The tailscale daemon needs to be in the openclaw account to allow openclaw to run tailscale whois for the tailscale authentication. That's why I have it there. It is convienent for me to trust tailscale with the authentication instead of needing to share a token with my devices that are already on the tailscale network.

I've addressed the other finding for parsing the tailscale serve status --json and added some regression tests around it.

@arturict

Copy link
Copy Markdown

Great improvement. If WSL/Tailscale path now changes, please call out migration expectations for existing gateway installs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P1 Urgent regression or broken agent/channel workflow affecting real users now. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add opt-in Tailscale Serve with tailnet identity authentication for generated WSL gateways

2 participants