Remove browser-cookie authentication from the CLI
Summary
Remove browser-cookie authentication from the CLI. Normal browser OAuth, stored bearer tokens, and HEY_TOKEN remain supported. Cookie-only sign-ins now explain that the person must sign in again, instead of appearing authenticated until a write fails.
- Remove
--cookiefrom both login commands, cookie headers, cookie-as-token fallback, and obsolete WebSocket recovery advice. - Preserve OAuth refresh/retry/reconnect and token migration. Legacy cookie fields remain inert for useful migration guidance and cleanup; cookie-only legacy config is scrubbed without creating a usable credential. Existing stored records can be replaced by login or removed by logout.
- Move smoke-test CLI login onto actual browser OAuth/PKCE. Browser checks retain their own browser session; no cookie is passed to the CLI. Consent uses form submission rather than a layout-sensitive coordinate click, and codes/tokens/progress are not printed.
- Make
auth token --storedactually ignoreHEY_TOKEN. - Update help, docs and the acknowledged breaking command surface. No SDK or server change; the malformed-403 fix from hey-sdk#240 is already in pinned SDK v0.35.0.
- Update Go to 1.27.4 to fix GO-2026-6859. Development, smoke and Nix compiler pins agree; Nix uses the verified official source while its locked nixpkgs still supplies 1.27.3. No module dependencies or security gates change.
Verification
- Go 1.27.4:
make checkandgo test -race ./internal/auth ./internal/cable ./internal/cmdpass.govulncheck ./...passes with zero affected vulnerabilities; its existing report of an uncalled module vulnerability is not suppressed. - Actual Nix package build with Go 1.27.4: pass, including its tests. The resulting binary reports Go 1.27.4, and evaluation confirms the development shell shares that compiler. Independent review found no actionable findings across the five-file compiler-update delta.
- New SDK wire tests: 7/7 scenarios; legacy migration: 6/6 scenarios; refresh-only recovery: both token getters, CLI status and actual SDK requests. A 429 hold cannot authenticate an empty access token. Cookie-only authentication counts zero network requests.
- Actual local Haystack: browser OAuth, status, token output, refresh, logout and re-login pass over HTTP and HTTPS. Final helper passes 20 consecutive HTTPS logout/re-login checks.
- Opt-in
verificationsmoke tests: a real HTTPS cookie-only write is refused with 403, while CLI OAuth approves/denies/approves the same disposable clearance; browser reads independently reflect each decision. Realhey watchreaches its ready subscription. This is not an end-to-end mail-change/TUI-rendering claim. - Isolated combination with Jeremy's open #640 at
8875d21: 38 local-command tests pass (including stored and legacy cookie-only fixtures), plus the local socket-client suite. No CLI sign-in or direct server request is needed. Not tested against the real desktop app; its local door is not available here. - Mutation checks: restoring cookie-header authentication fails the wire regression test; breaking refresh-only recovery fails both getter tests; reverting refresh-only status or the 429 hold guard fails the corresponding regression. All four mutations were confined to the separate integration checkout and restored.
- Independent local review: two initial findings corrected, followed by review of all 29 changed files with no actionable findings. The PR-feedback delta was independently reviewed too; a refresh-only/429 interaction was corrected and re-reviewed with no remaining findings. Two PR review rounds are complete on b53910e: Copilot and Greptile approved; Codex reported no findings; cubic's final-head check reports zero issues in the 8-file delta. All 5 review threads are resolved.
Follow-up live verification / resolved security gate
Full strict live smoke re-run with this head's Go 1.27.4 build: 147/147 top-level tests pass, zero skips (403.9 seconds), including browser OAuth and SMTP capture/read-back. The earlier five baseline failures are resolved by running the required Elasticsearch 8, configured image-processing cell and disposable local-mail fixtures. No assertions are skipped or weakened. Temporary development OAuth registration and its sessions were removed afterward.
The run uses go test -v -count=1 -timeout 10m ./... with strict mode and all SMTP prerequisites. The complete suite exceeds the old five-minute overall deadline; main test-reliability PR #642 corrects that budget and documents the setup (its full strict run also passes 147/147). Haystack bootstrap PR #9325 starts the configured ES8 service, waits for health and stops hiding index-reload errors. Neither follow-up is folded into this auth-only PR.
The earlier Go 1.27.3 Security failure was reproduced on unchanged main. This PR now includes the authorized Go 1.27.4 fix in 6183f56; both local vulnerability scanning and the CI Security check pass without any waiver or gate change. Final-head CI is green: 31 checks pass, 5 are skipped, none fail or remain pending, including Security, race detection, Nix builds and native self-update tests on Linux/macOS/Windows. In the third and final review round, Copilot approved, Codex reported no findings, and cubic reports zero issues across the five-file compiler-update delta. No review threads remain open.
CI race detection initially reported a time.Local race in the unchanged timezone test fixture (original job). One bounded, same-head rerun passed, with no suppression or source change; dependency jobs reran as part of that attempt and reproduced the security failure. Local baseline command tests also passed two race runs. Both CI results remain recorded; this PR does not claim to fix that intermittent fixture race. Its permanent fix is independently reviewed in #642, where all packages pass three shuffled race repetitions and CI race detection passes.
No production mutations, merge, deployment, or release performed. This PR intentionally breaks scripts using --cookie; existing cookie users must sign in again.