Skip to content

feat: upgrade legacy managed Gateways to Tailscale auth - #1128

Open
TheAngryPit wants to merge 7 commits into
openclaw:mainfrom
TheAngryPit:codex/tailscale-legacy-upgrade-20260807
Open

feat: upgrade legacy managed Gateways to Tailscale auth#1128
TheAngryPit wants to merge 7 commits into
openclaw:mainfrom
TheAngryPit:codex/tailscale-legacy-upgrade-20260807

Conversation

@TheAngryPit

@TheAngryPit TheAngryPit commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

What problem this solves

Existing Companion-managed WSL Gateways can remain token-backed for Dashboard access after the operator explicitly adopts verified Tailscale identity authentication.

Closes #1117 only if maintainers approve the product/security boundary below.

Core-first design

Official Core owns the authorization and ingress contract. The Windows Companion adapts to Core; this PR does not patch, replace, or require a compatibility change in Core.

The Companion now offers a confirmation-gated migration for eligible active managed Gateways. It:

  • asks Core to enable gateway.auth.allowTailscale;
  • persists a matching local trust marker only after authoritative Core readback;
  • verifies that Tailscale Serve is owned by the configured Core Gateway process before generating a token-free Dashboard link;
  • retains the existing approved shared browser credential as compatibility fallback while live readiness is unavailable;
  • fails closed if neither verified identity nor an approved browser credential is available.

Exact source

  • PR head: 0ad95b5edc4ce3745a4724d171a73447df7a1a03
  • Current Windows main merged: ccd64bbb7d687d9929091109c8d722ad9ba962d9
  • Official Core runtime: f68503084b7ad967d9ba763dbe06065d8762042f (2026.8.1)
  • Exact WinUI SHA-256: 032B956F7B42FD356AF37C15EF571FF2A1BFE97BDB50AAAE22614FDBF3790C0B

Validation

  • Supported WinUI Release build: PASS.
  • Focused Tailscale/ownership Connection tests: 96/96.
  • Dashboard/recovery/App-wiring Tray tests: 99/99.
  • App capability/Gateway client Shared tests: 258/258.
  • Setup/Tailscale policy tests: 333/333.
  • Full Connection project: 775/776. The sole failure is the unchanged 10-second ConnectWithSharedTokenAsync_RevalidatesDurableTokensUnderTransitionSemaphore timeout already reproduced on the clean parent baseline.
  • git diff --check: PASS.
  • Two independent exact-diff reviews: no actionable findings.

The first full-Connection attempt also hit seven current-main Local AI fixture failures because the system drive lacked space for their synthetic model files. Re-running the unchanged suite with TEMP on the project drive removed all seven environmental failures.

Exact-head real behavior proof

The exact Release binary ran side-by-side against unmodified official Core and its Core-owned managed Tailscale ingress.

{
  "ownershipClassification": "owned",
  "dashboard": {
    "scheme": "https",
    "queryEmpty": true,
    "fragmentEmpty": true,
    "hasTokenQuery": false,
    "hasCredentialMarker": false,
    "httpStatus": 200,
    "expectedControlUiContent": true
  },
  "browser": {
    "openedTokenFree": true,
    "boundedControlUiMarkers": 2,
    "boundedConnectMarkers": 1,
    "boundedAuthFailures": 0
  }
}

No URL, hostname, token, Gateway/device/pairing identifier, Tailscale identity, private path, or raw journal line is included.

The exact candidate, local MCP listener, temporary config and disposable Gateway runtime were removed after proof. Local MCP was restored to disabled. The installed production Companion and all credentials/pairings were untouched.

Compatibility truth

The existing fallback remains intentional. During a disposable Core restart, the first immediate request used the approved shared-credential fragment while ownership revalidation converged; a later request returned to a token-free URL and HTTP 200. Therefore this PR does not claim that every link is always token-free or that restart recovery is atomic.

Maintainer decision

Should an explicitly opted-in existing managed Gateway be allowed to authorize Control UI access through Core-verified Tailscale identity, with authoritative Core readback, Core-process ownership verification, retained shared-credential fallback, and fail-closed behavior when no approved path exists?

Contributor recommendation: approve this bounded Core-owned authorization path.

Proof level

implemented, code_proven, test_proven, and runtime_proven for exact-head token-free Control UI link generation/opening against unmodified official Core. Merge, release, installed-package promotion, and the maintainer policy decision remain unclaimed.

@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: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. 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 Aug 8, 2026
@clawsweeper

clawsweeper Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 22, 2026, 6:22 AM ET / 10:22 UTC.

ClawSweeper review

What this changes

The PR adds a confirmed in-place upgrade for existing managed Tailscale gateways that enables Core-verified identity dashboard access while preserving shared-token fallback.

Merge readiness

⚠️ Ready for maintainer review - 3 items remain

Keep open for a maintainer security-boundary decision. Current main supports the same explicit Tailscale trust model for new setup, but does not provide this in-place migration for existing managed gateways; the patch’s Core readback and live-ingress checks make it a viable candidate rather than an obsolete duplicate.

Priority: P2
Reviewed head: 0ad95b5edc4ce3745a4724d171a73447df7a1a03
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) Exact-head runtime evidence and focused coverage support a mergeable implementation, subject to the maintainer-owned authorization decision.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.
Evidence reviewed 7 items Current-main policy: Current main already treats Tailscale identity as an explicit setup opt-in and writes gateway.auth.allowTailscale during generated-gateway setup, but it has no legacy-record upgrade service or durable legacy marker.
Published authorization boundary: Current documentation says verified Tailscale identities and tailnet ACLs become part of the gateway access-control boundary only after explicit setup opt-in, while token and device credentials remain available.
PR authority chain: The proposed migration requires an active connected gateway with config read/write scopes, records the upgrade state, and revalidates Core plus live ingress before a token-free dashboard URL is returned.
Findings None None.
Security None None.

How this fits together

The Windows Companion persists managed gateway records, connects them to Core, and generates dashboard links for WinUI and local MCP callers. This change takes an explicit Connection-page opt-in through Core configuration and a durable local marker, then revalidates Core and Tailscale ingress before omitting a browser credential.

flowchart LR
A[Existing managed gateway] --> B[Connection settings confirmation]
B --> C[Core configuration patch]
C --> D[Durable gateway trust marker]
D --> E[Core readback]
E --> F[Live Tailscale ingress verification]
F --> G[Dashboard link policy]
G --> H[Browser or local MCP link]
Loading

Decision needed

Question Recommendation
Should explicitly opted-in, existing managed Tailscale gateways be allowed to join the same Core-verified Tailscale dashboard-authentication boundary already available during new setup? Approve the bounded migration: Allow the explicit legacy upgrade with Core readback, live ingress ownership verification, retained credential fallback, and fail-closed behavior.

Why: The implementation is bounded and proof-positive, but accepting tailnet identity for installed legacy gateways is an authorization-policy extension that cannot be settled by tests alone.

Before merge

  • Resolve merge risk (P1) - Merging extends an existing authentication option from newly provisioned gateways to already-installed managed gateways, so maintainers must explicitly accept the upgrade and authorization boundary.
  • Resolve merge risk (P2) - The durable marker and dashboard credential behavior alter existing gateway records; compatibility depends on preserving the documented shared-token fallback whenever Core or live ingress revalidation is unavailable.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope 34 files, +3,590/-49 lines, including 2,004 test additions The change spans persisted state, Core configuration, WSL verification, WinUI, MCP, and compatibility coverage.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #1117
Summary: This PR is the concrete candidate implementation for the legacy managed-gateway migration requested by the canonical issue.

Members:

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

Merge-risk options

Maintainer options:

  1. Approve the explicit legacy upgrade (recommended)
    Accept the existing Tailscale trust model for eligible legacy records, with the retained shared-credential fallback protecting unavailable readiness checks.
  2. Preserve the fresh-install-only policy
    Pause or close this PR if maintainers intend Tailscale identity trust to remain unavailable for legacy managed gateways.

Technical review

Best possible solution:

Either approve this narrowly scoped legacy migration under the existing explicit Tailscale trust policy, or retain the current fresh-setup-only boundary and close the PR as an intentionally unsupported upgrade path.

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

Yes, source-reproducible: current main supports TrustTailscaleAuth during fresh setup but has no durable legacy-record marker or in-place upgrade action for an existing managed gateway.

Is this the best way to solve the issue?

Yes, conditionally: the PR reuses the existing explicit Core authorization setting and preserves fallback behavior, but the legacy authorization-policy extension needs maintainer approval.

AGENTS.md: found and applied where relevant.

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

Labels

Label changes:

  • add P2: This is a bounded upgrade feature for existing managed gateways, with meaningful but opt-in user impact.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove P1: Current review triage priority is P2, so this older priority label is no longer current.

Label justifications:

  • P2: This is a bounded upgrade feature for existing managed gateways, with meaningful but opt-in user impact.
  • merge-risk: 🚨 compatibility: The PR persists a new gateway-record marker and changes dashboard credential behavior for upgraded installations.
  • merge-risk: 🚨 auth-provider: The migration changes when dashboard access uses an approved shared credential versus Core-verified Tailscale identity.
  • merge-risk: 🚨 security-boundary: It extends an authentication path that makes tailnet identity and ACLs part of Control UI authorization.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body contains exact-head redacted live output showing an owned Tailscale route, a token-free dashboard link, HTTP 200 Control UI content, browser opening, and zero observed authentication failures.

Evidence

What I checked:

  • Current-main policy: Current main already treats Tailscale identity as an explicit setup opt-in and writes gateway.auth.allowTailscale during generated-gateway setup, but it has no legacy-record upgrade service or durable legacy marker. (src/OpenClaw.SetupEngine/ConfigureGatewayStep.cs:130, b37307cbd51f)
  • Published authorization boundary: Current documentation says verified Tailscale identities and tailnet ACLs become part of the gateway access-control boundary only after explicit setup opt-in, while token and device credentials remain available. (docs/WSL_GATEWAY_ADMIN.md:123, 4206611f2b2e)
  • PR authority chain: The proposed migration requires an active connected gateway with config read/write scopes, records the upgrade state, and revalidates Core plus live ingress before a token-free dashboard URL is returned. (src/OpenClaw.Connection/GatewayTailscaleAuthUpgrade.cs:360, 0ad95b5edc4c)
  • Final-effect gate: The dashboard service falls back to an approved browser credential or fails closed when revalidation cannot establish trusted Tailscale access. (src/OpenClaw.Tray.WinUI/Services/GatewayDashboardLinkService.cs:50, 0ad95b5edc4c)
  • History and ownership: Blame attributes the current setup-side allowTailscale configuration to Barbara Kudiess’s setup refactor, while the current dashboard URL builder and Tailscale policy documentation date to Scott Hanselman’s commit. (src/OpenClaw.SetupEngine/ConfigureGatewayStep.cs:136, b37307cbd51f)
  • Release and main status: The PR head is not contained in any local release tag; the latest release tag contains current main’s earlier commit, so this migration is neither released nor implemented on main. (0ad95b5edc4c)

Likely related people:

  • Barbara Kudiess: Introduced the current-main setup-side configuration that writes the explicit Tailscale authorization setting. (role: recent setup and Tailscale contributor; confidence: high; commits: b37307cbd51f; files: src/OpenClaw.SetupEngine/ConfigureGatewayStep.cs, src/OpenClaw.SetupEngine/PairOperatorStep.cs)
  • Scott Hanselman: Blame ties the current dashboard URL builder and the documented Tailscale access-control policy to this commit. (role: established dashboard and Tailscale policy contributor; confidence: medium; commits: 4206611f2b2e; files: src/OpenClaw.Tray.WinUI/Helpers/GatewayDashboardUrlBuilder.cs, docs/WSL_GATEWAY_ADMIN.md)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (17 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-12T10:20:52.807Z sha 653135c :: needs maintainer review before merge. :: none
  • reviewed 2026-08-12T12:24:05.454Z sha 653135c :: needs maintainer review before merge. :: none
  • reviewed 2026-08-17T18:36:53.823Z sha b51aa91 :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-18T08:49:04.788Z sha c2b6c59 :: needs real behavior proof before merge. :: [P3] Localize the new Tailscale dashboard copy
  • reviewed 2026-08-18T11:57:29.355Z sha e34272f :: needs real behavior proof before merge. :: [P2] Centralize the Dashboard credential decision | [P3] Localize the new Tailscale Dashboard copy
  • reviewed 2026-08-19T15:25:41.845Z sha bd8ab21 :: needs real behavior proof before merge. :: [P1] Preserve the QR/bootstrap dashboard URL contract | [P2] Move dashboard credential policy out of App | [P3] Localize the new Tailscale dashboard copy
  • reviewed 2026-08-19T18:24:45.870Z sha bac278a :: needs real behavior proof before merge. :: [P1] Preserve the QR/bootstrap dashboard URL contract | [P3] Localize dashboard authentication errors
  • reviewed 2026-08-21T21:09:14.578Z sha 1ebebfa :: needs real behavior proof before merge. :: none

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Thanks for flagging the config.patch boundary. I checked it against both the pinned Core used by the runtime and current main:

Both pass the submitted object to applyMergePatch(snapshot.config, normalizedPatch, ...). The partial leaf patch in this PR is therefore intentional. Sending the full config.get snapshot would be unsafe because unrelated null values would become JSON Merge Patch deletion markers.

The regression test deliberately verifies that an unrelated top-level field is absent from the submitted patch. I added a source comment documenting this invariant; no behavior changed in that follow-up commit.

The draft remains blocked on the product/security decision in #1117 and does not claim exact-head runtime proof for the new failure branches.

@clawsweeper please re-review the updated head.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Aug 8, 2026
@TheAngryPit

Copy link
Copy Markdown
Contributor Author

CI follow-up on exact head 00bfdd70:

The setup-connect E2E exposed a real regression in ExternalLike_QrOnlyFreshTray_RequiresExplicitDeviceApproval: the new early guard rejected the existing bootstrap credential path before the Dashboard URL could be returned.

The fix removes only that guard. Existing behavior remains:

  • QR/bootstrap onboarding may return its Dashboard URL without appending the bootstrap token;
  • shared-token URLs still append the token when Tailscale identity is not trusted;
  • shared-token omission still requires the persisted marker plus authoritative Core revalidation.

Fresh proof after the correction:

  • Dashboard URL builder tests: 4/4 passed
  • Tray suite: 2166/2166 passed
  • git diff --check: passed
  • scoped Auto-review: no findings, patch correct, confidence 0.96

The draft remains blocked on #1117's product/security decision and exact-head runtime-proof gate. The new CI run is the supported E2E proof for this head.

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Exact-head architecture and upstream reconciliation proof for b57cc9c6:

  • Addressed the prior P2 by extracting GatewayDashboardLinkService, shared by the tray launch and local MCP paths. App.xaml.cs now retains composition, logging, UI error display, and launch only.
  • Preserved the existing native contract: authoritative Tailscale revalidation omits the shared credential; failed revalidation falls back only to an already-approved browser credential; otherwise the action fails closed.
  • Merged current upstream main (9f9a8eda). The two conflicts were additive: retained upstream GatewayDirectConnectService/validation tunnel wiring and this PR's dashboard-link service.

Fresh proof after the merge:

  • focused dashboard/service/architecture tests: 10/10
  • full build: Shared, CLI, WinNodeCli, SetupEngine, and WinUI succeeded
  • dependency preflight: passed
  • canonical sequential closeout: Shared 3636/3636 with 32 skipped; Tray 2253/2253
  • git diff --check: passed
  • whole-branch Auto-review against current origin/main: no accepted/actionable findings, patch correct, confidence 0.87

The first closeout run had one unrelated telemetry-listener test failure. The exact test passed on one bounded rerun, and the canonical closeout then passed in full; no telemetry code was changed.

This is test/build/review proof, not current-head runtime or end-to-end proof. The draft remains blocked on the legacy-gateway authorization-policy decision and an inspectable redacted runtime artifact showing Core/local convergence, retained fallback credentials, and token-free Dashboard authentication.

@TheAngryPit
TheAngryPit marked this pull request as ready for review August 8, 2026 14:11
@TheAngryPit
TheAngryPit force-pushed the codex/tailscale-legacy-upgrade-20260807 branch from b57cc9c to afc9111 Compare August 9, 2026 19:20
@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Current-head Windows runtime proof

I tested the published #1128 head as part of a combined Windows Companion candidate at 00a61d3a75a615ff4f2b80b30da4df4eb6df18ee.

The supported build passed all five projects. Focused validation passed 1,073 tests with zero failures, and the canonical Shared/Tray closeout passed 5,896 tests with zero failures (32 existing integration-category skips).

The exact candidate was then installed and exercised through the supported app.dashboard.url entrypoint. The sanitized result was:

{
  "revalidated": true,
  "success": true,
  "trustTailscaleAuth": true,
  "credentialFragmentPresent": false,
  "errorCode": null
}

This provides runtime proof that the installed Companion revalidated the authoritative Core setting and produced a successful trusted-auth dashboard result without including the retained fallback credential. No browser or Launcher was invoked, and no URL, token, endpoint, gateway identifier, or raw Core response was persisted.

The temporary Local MCP proof surface was returned to Off immediately afterwards. The original settings hash, process identity, binary identity, and zero-listener state were confirmed. The generated MCP credential file remains stored by the product's normal design; its value was never read or emitted.

Scope note: this Gateway had already adopted trusted auth, so the proof exercises current-head revalidation and token-free result construction rather than replaying the initial false -> true adoption transition. An independent test on a Gateway that has not adopted the setting yet would usefully cover that remaining transition.

Sanitized agent transcript
[assistant]
I will work only in the #1128 staging worktree and the allowed surfaces. I am checking the saved-row path, focused service entrypoint, and contract tests before changing production code.

[assistant]
Failed-first was captured: the saved-row method did not delegate to the focused service. The minimal change retains the credential-provenance gate and routes policy through the authoritative service.

[assistant]
The supported build passed all five projects. Focused Connection, Setup, Shared, and Tray validation passed 1,073 tests with zero failures; canonical Shared/Tray closeout passed 5,896 tests with zero failures.

[assistant]
The exact combined candidate was installed. Read-only inspection confirmed the running executable and assemblies identify the expected SHA, with trusted auth active and the approved shared fallback retained.

[assistant]
After explicit operator authorization, the supported `app.dashboard.url` capability returned `revalidated=true`, `success=true`, `trustTailscaleAuth=true`, and `credentialFragmentPresent=false`. Browser and Launcher were not invoked, and no URL or credential value was persisted.

[assistant]
Local MCP was restored to Off. The settings hash, process, binary identity, and zero-listener state matched the pre-probe state. The product retained its generated bearer-token file by design; its value was never read or emitted.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 10, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 10, 2026
@TheAngryPit

TheAngryPit commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the remaining contributor-owned localization finding on exact head 653135c.

  • Replaced the six new hard-coded Tailscale dashboard-authentication strings with resource lookups.
  • Added localized resources for all five supported locales: en-US, fr-FR, nl-NL, zh-CN, and zh-TW.
  • Added a focused source-contract regression covering every lookup.

Validation:

  • Failed first: the new focused regression failed 0/1 because the resource lookups were absent.
  • LocalizationValidationTests: 16/16 passed.
  • Supported build: 5/5 projects passed.
  • Shared: 3,636 passed, 32 skipped, 0 failed.
  • Tray: 2,257 passed, 0 failed.
  • git diff --check: passed.

The maintainer policy decision for the legacy identity authorization boundary and current-head proof of the initial untrusted-to-trusted transition remain open gates; this commit does not claim to resolve either.

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 10, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

TheAngryPit commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Initial-adoption proof — provenance correction

Correction: the installed combined Windows build 00a61d3a75a615ff4f2b80b30da4df4eb6df18ee contained PR #1128 commit afc91117402e0ca46834faee791150ded570a90a, not the later localization-only head 653135ce02ad3814604879b516b8e18e7f1b4593. The previous wording incorrectly described the installed candidate as containing the exact current head.

The operator and Codex ran one bounded, explicitly authorized, reversible transition through the installed Companion's supported Connection UI. The transition observations and receipt below are runtime evidence for the authentication implementation at afc91117402e0ca46834faee791150ded570a90a.

The current PR head is one descendant commit ahead. Its complete afc911...653135 delta only replaces six UI strings with resource lookups, adds the corresponding values to the five existing locale files, and adds a localization source-contract test. It does not change the upgrade transaction, persisted trust marker, Core patch/revalidation, credential fallback, dashboard-link policy, or rollback behavior. Exact-head CI is green, including both Windows builds, the full test job, setup/connect, network-recovery and revocation-recovery E2E lanes, repository hygiene, and the advanced setup gate.

Accordingly, the strongest accurate proof is: runtime_proven for the unchanged authentication path at afc911, plus code_proven source equivalence and test_proven exact-head validation at 653135. This does not claim that a binary built from 653135 itself was installed or exercised.

Sanitized result:

{
  "status": "pass",
  "proofLevel": "runtime_proven_plus_exact_head_equivalence",
  "runtimeProvenPrCommit": "afc91117402e0ca46834faee791150ded570a90a",
  "currentHead": "653135ce02ad3814604879b516b8e18e7f1b4593",
  "currentHeadDelta": "localization_only",
  "initial": {
    "coreAllowTailscale": true,
    "localTrustMarker": true,
    "sharedFallbackPresent": true
  },
  "controlledReset": {
    "coreAllowTailscale": false,
    "localTrustMarker": false,
    "sharedFallbackRetained": true
  },
  "adoption": {
    "entrypoint": "supported_companion_connection_ui",
    "fallbackReconnectSucceeded": true,
    "coreAllowTailscale": true,
    "localTrustMarker": true,
    "sharedFallbackRetained": true
  },
  "rollback": {
    "originalBooleanStateRestored": true,
    "companionRunning": true
  }
}

What this proves:

  • both authoritative Core state and the local trust marker were placed in the initial untrusted state;
  • the approved shared fallback credential remained retained;
  • the supported UI action reconnected through that fallback;
  • Core accepted gateway.auth.allowTailscale=true;
  • the local marker converged to true;
  • fallback material remained present after adoption;
  • rollback restored the original boolean state and the Companion remained running;
  • a separate visual readback showed the Companion Connected, with no update modal or visible error.

The receipt SHA-256 is 77FAE217592B1BDE1B88778370C11217DFF874BF7611E1AC32C255BCAC2D169D.

Receipt provenance note: the hashed receipt's prHead metadata repeats the same mistaken 653135 label; treat that field as superseded by this correction. The observed runtime values are unchanged, and the installed candidate provenance is afc911 within combined build 00a61d3.

Redaction: no URL, token, Gateway identifier, raw response, or secret value was persisted or included here. No update was installed. The two disposable identity runtimes used during diagnosis were removed after verification.

This closes the behavioral initial-adoption proof gap through runtime evidence for afc911 and exact, reviewable source/test equivalence for the localization-only current head. The maintainer decision about the legacy tailnet authorization boundary remains intentionally open.

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 12, 2026
@TheAngryPit

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@TheAngryPit
TheAngryPit force-pushed the codex/tailscale-legacy-upgrade-20260807 branch from 653135c to b51aa91 Compare August 17, 2026 18:31
@clawsweeper clawsweeper Bot removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: sufficient Contributor real behavior proof is sufficient. labels Aug 17, 2026
@TheAngryPit
TheAngryPit force-pushed the codex/tailscale-legacy-upgrade-20260807 branch from b51aa91 to c2b6c59 Compare August 18, 2026 08:45
@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Current-head runtime proof and bounded remaining ask

The PR branch is now rebuilt as one exact commit, c2b6c59530c0e648f80c10f509b151075392133e, directly on current upstream main f8a8825ccbb441caaf51f5509102adb53aa1dbfc.

Current-head production-path evidence:

  • Side-by-side Dev Companion installed and paired through the supported flow.
  • Explicit Tailscale identity adoption persisted the durable trust marker and authoritative Core policy while retaining the approved fallback credential.
  • After the expected Gateway restart and automatic reconnect, a fresh Chrome Incognito window opened a URL with no token parameter.
  • At that exact launch time, the Gateway recorded an authenticated Tailscale user and served the Dashboard. The healthy tokenless branch is therefore end_to_end_proven on this head.

The remaining negative-readiness branch is deliberately reported as test_proven, not runtime_proven. On this production topology, the same tailscaled instance owns both the local readiness surface and Tailscale Serve ingress. Stopping it removes the route as well as the verifier, so doing that would not exercise authenticated fallback and would disrupt the working production path without producing honest evidence.

Maintainer or Crabbox-user request: if you have a supported topology where Dashboard ingress remains reachable while the local WSL Tailscale verifier is unavailable, could you run the four-step fallback/recovery check now documented in the PR body? A redacted transcript with boolean credential-fragment presence, marker/config preservation, and authentication outcome is enough. Please do not include URLs, tokens, Gateway identifiers, or credential values.

This limitation is a topology-specific proof gap, not a request to weaken the safety checks or to block the larger current-main validation picture.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 18, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@TheAngryPit
TheAngryPit force-pushed the codex/tailscale-legacy-upgrade-20260807 branch from c2b6c59 to e34272f Compare August 18, 2026 11:51
@TheAngryPit
TheAngryPit force-pushed the codex/tailscale-legacy-upgrade-20260807 branch from e34272f to bd8ab21 Compare August 19, 2026 15:21
@clawsweeper clawsweeper Bot added P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 19, 2026
@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Exact-head follow-up for 1ebebfa81e3c547c5fe33030b8f210cfd8efc1ac (base b37307cbd51f26eb926e980d96554e9cab71db7d). This addresses the two actionable review findings without deciding the separate maintainer-owned Tailscale product/security policy.

What changed

  • Preserved the established non-Tailscale QR/bootstrap contract: the dashboard URL is generated without embedding a credential.
  • Kept explicitly opted-in Tailscale links fail closed when identity revalidation fails and no approved shared browser credential is available.
  • Routed both dashboard-policy errors through localization and added keys for all five supported locales.
  • Updated the real QR-only E2E assertion so it no longer encodes the regression.

Validation

  • Failed first: BuildAsync_TokenFreeBootstrapRequest_PreservesDashboardUrl returned Success=false before the fix; the localization injection test also failed to compile before the production constructor accepted the localizer.
  • build.ps1: PASS (46 documentation files; Shared, CLI, WinNodeCli, SetupEngine, WinUI).
  • Focused dashboard/localization tests: 13 passed, 0 failed.
  • Shared tests: 3703 passed, 32 environment-only skipped, 0 failed.
  • Tray tests: 2633 passed, 0 skipped, 0 failed.
  • Full-branch autoreview against the exact base: TruffleHog clean, 155031-byte bundle, no accepted/actionable findings, patch correct (0.99).

Real behavior proof

ExternalLike_QrOnlyFreshTray_RequiresExplicitDeviceApproval passed 1/1 against a disposable loopback-only WSL Gateway (official OpenClaw 2026.6.34, protocol v4) and an isolated Tray profile:

  • a real Gateway setup code was applied through app.connection.applySetupCode;
  • the fresh record had no shared gateway token and retained only bootstrap recovery material while explicit device approval was pending;
  • app.dashboard.url succeeded with a non-null URL, usesSharedGatewayToken=false, hasTokenQuery=false, and no token= substring;
  • the pending device request was rejected through the Connection-page path;
  • official uninstall exited 0, and the disposable distro, temp roots, candidate Tray processes, and proof listeners were absent afterward.

Proof hashes: WinUI executable 49F136EC4CA707EF54A776F12FBA3466A815DC8C2244403CEC4D36D2137EEED5; QR-only Tray log BA868BC8F60645BCAE1DB9A8F7F8225A102F9EA40AC71E95CC5283F5192A90B0; setup log 539793560B712A493ECA971AF4F17C8EC86B99064F1BF250B1D831287C2FF2F0; uninstall log 8801E37309E6FBEBF5A55F47BF3F30963D1BA376D9A484BFC7CD588E62320959.

The remaining question is the maintainers' intended policy for enabling verified Tailscale dashboard identity; this follow-up deliberately leaves that decision explicit.

@clawsweeper please re-review the exact head.

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

CI follow-up for exact head 1ebebfa81e3c547c5fe33030b8f210cfd8efc1ac:

  • Build and Test run 32526717884 completed with 6 successful checks, 6 intentional skips, and one failed check.
  • The only failure was the unchanged accessibility screenshot test NativeToolIdentityScreenshotProofTests.SyntheticNativeRows_RenderTrustedIdentitySafeInputAndTruthfulFallback timing out while waiting 10 seconds for ChatComposerInput.
  • In the same CI job, the ordinary ChatPage accessibility scan subsequently found the same marker and passed after 12 seconds; all other 20 accessibility tests passed.
  • A fresh local rerun of the exact failed test against the exact PR head passed 1/1. Its test body took 17 seconds and the complete invocation took about 30 seconds.
  • The contributor account cannot rerun the failed GitHub Actions job (Must have admin rights to Repository).

This is evidence of an unrelated timing-sensitive UI test gate, not a failure of the dashboard-link behavior changed by this PR. Maintainer action requested: rerun failed jobs. The PR remains honestly CI-red until that rerun passes; no timeout/harness change has been mixed into this dashboard/auth patch.

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Exact-head current-main reconciliation and real Core compatibility proof for 0ad95b5edc4ce3745a4724d171a73447df7a1a03:

  • merged canonical Windows main ccd64bbb7d687d9929091109c8d722ad9ba962d9 without conflicts or Core changes;
  • supported WinUI Release build passed; exact executable SHA-256 032B956F7B42FD356AF37C15EF571FF2A1BFE97BDB50AAAE22614FDBF3790C0B;
  • focused selections passed 96/96 Connection, 99/99 Tray, 258/258 Shared and 333/333 Setup;
  • full Connection passed 775/776; the sole failure is the unchanged 10-second transition-semaphore timeout already reproduced on the clean parent baseline;
  • two independent post-merge reviews found no actionable issue;
  • exact binary ran against unmodified official Core f68503084b7ad967d9ba763dbe06065d8762042f (2026.8.1);
  • live Core-route ownership classified owned;
  • generated Dashboard link was HTTPS with empty query and fragment, no token/credential marker, and returned HTTP 200 with expected Control UI content;
  • the token-free link was opened in the browser; the bounded Core interval recorded Control UI/connect markers and zero auth failures;
  • cleanup removed the candidate, MCP listener, temporary config and disposable Gateway runtime; Local MCP was restored to disabled; installed production Companion, credentials and pairings were untouched.

Compatibility boundary: the retained shared-credential fallback remains intentional while live ownership revalidation is unavailable. This does not claim every link is always token-free or that restart recovery is atomic.

The contributor-owned proof gap is now closed at runtime_proven for exact-head token-free Control UI link generation/opening against official Core. The explicit decision to approve Tailscale identity as an authorization path for opted-in existing managed Gateways remains maintainer-owned.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 22, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P1 Urgent regression or broken agent/channel workflow affecting real users now. labels Aug 22, 2026
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: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. 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. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: allow existing managed Tailscale gateways to adopt tailnet identity safely

2 participants