Logging in (still one click).

Per-agent credentials sound expensive in clicks. They do not have to be. Solo desktop can default to brokered convenience. Strict agents, Teams, and Cloud should default to separate provider homes.

01
UserDesktop UI
Clicks "Log into Claude for Sales".
02
Desktop UIEngine
POST /v1/agents/Sales/providers/anthropic/login (new scoped route).
03
Engineclaude CLI
Spawn as hou_sales inside the Linux runtime.
04
claude CLIEngine
Prints login URL on stdout.
05
EngineDesktop shell
Pushes URL to the host shell via the runtime bridge.
06
Desktop shellSystem browser
Opens the URL.
07
UserAnthropic
Logs in.
08
AnthropicProvider callback
Completes the CLI-owned OAuth flow. Houston does not control this callback.
09
Providerclaude CLI
CLI detects completion through its own callback or polling path.
10
claude CLIAnthropic
Exchanges provider-owned code and saves token in the agent provider home.
11
EngineLogin state
Observes CLI success, verifies provider status, records login state.
12
EngineDesktop UI
WS event "Sales logged in". UI updates.
13
Houston OAuthDesktop shell
Only Houston-owned OAuth flows use houston://... deep links.

One click for the user. Provider tokens stay inside the provider CLI flow. Houston only forwards the login URL out of the runtime and observes success.

What you already have

Houston already has host-side OAuth plumbing for Google sign-in via Supabase. A click in the UI starts a Houston-owned OAuth flow. The system browser does the work. A custom URL scheme (houston://...) brings the result back into the app.

Provider CLI logins are different. The current provider login route is global (/v1/providers/:name/login). The future scoped route should start a provider login for one agent home, but it should not pretend Houston owns Anthropic or OpenAI callback URLs.

The new piece: host-to-runtime bridge

When the engine lives inside a Linux runtime (Chapter 3), the host UI must bridge two things: opening provider login URLs printed by a CLI, and delivering Houston-owned deep links back to the engine. Do not mix those flows.

Two things to get right:

What about provider CLI callback URLs?

The Claude Code CLI and the Codex CLI each open their own hosted OAuth flow. We don't control their callback URL. We capture it by:

  1. Spawning the CLI inside the runtime.
  2. Reading the login URL it prints to stdout.
  3. Asking the host shell to open that URL.
  4. Waiting for the CLI subprocess to finish the exchange.

No houston:// hijack belongs in the common provider path; the CLI handles its own callback. The deep link is only for Houston OAuth flows such as Supabase.

Per agent vs broker

Two flavors, both compatible with the same plumbing. The honest defaults differ by deployment.

Desktop solo user: broker by default

One provider login for the whole desktop profile. Houston can seed or broker agent provider homes for convenience. This is acceptable for a solo user who treats agents as slices of one trust boundary.

It is not acceptable for "two clients, two legal boundaries." Desktop needs a visible strict mode per agent or per workspace, before Teams exists.

Teams or Cloud: per-agent by default

Each agent gets its own provider home and its own login state. It may still be the same human account, but tokens and tool grants are not shared by default. This is the mode the regulated-industry pitch leans on.

What works today

Single-account Anthropic, OpenAI, and Composio logins work today, but they are machine-wide. The current engine route is global, not agent-scoped. M2 should add per-agent provider homes on native hosts. M3 should move those homes under per-agent Linux users if the runtime ships.

Where to look in the code

Today's provider login route: engine/houston-engine-server/src/routes/providers.rs. Today's Supabase OAuth deep-link handler: app/src-tauri/src/commands/auth.rs (host side). New bridge: app/houston-tauri/runtime/bridge.rs (new). CLI spawn for per-agent: same site as Chapter 7, engine/houston-terminal-manager/src/cli_process.rs with the HOME override.