Add durable Paseo Hub CLI login (#3022)

* feat(cli): add durable Hub login

Keep organization-scoped human credentials separate from daemon relationship authority. Connect now exchanges explicit or stored CLI authority for a one-time enrollment token, while logout removes human access without implicitly disconnecting automation.

* fix(cli): require TLS for remote Hub credentials

Durable Hub credentials are bearer secrets, so remote origins must not receive them over cleartext HTTP. Keep literal loopback HTTP available for local Hub development.

* fix(cli): make Hub destinations explicit

Resolve optional Hub origins through one shared precedence policy so active logins remain the default context and credentials stay origin-bound. Report the selected destination before human-facing work, keep structured output auditable, and preserve login authority until requested daemon disconnection succeeds.
This commit is contained in:
Mohamed Boudra
2026-08-08 15:27:43 +02:00
committed by GitHub
parent e36842b234
commit b669dad221
40 changed files with 2369 additions and 1032 deletions
+10 -2
View File
@@ -196,10 +196,14 @@ Use `PASEO_HOME` to run multiple isolated daemon instances.
## Hub
```bash
paseo hub connect <url> # Enroll this daemon with a Paseo Hub
paseo hub login [url] # Approve and store organization-scoped CLI access
paseo hub connect [url] # Enroll this daemon using CLI access
paseo hub projects # List projects in the authenticated organization
paseo hub status # Show the current Hub relationship
paseo hub disconnect # End it
paseo hub deploy [file] # Install and activate a Hub configuration
paseo hub deploy --dry-run # Validate without installing or activating
paseo hub logout # Remove the active stored CLI login
```
`file` defaults exactly to `.paseo/hub.yml` relative to the current directory. Pass a file to use another path. The CLI does not search parent directories or alternate filenames.
@@ -208,7 +212,11 @@ Pass `-p, --project <slug>` to select the project, or add optional top-level `pr
Prompt `include` blocks are read from `.paseo/partials/` under the current directory, even when you pass an explicit configuration file. The CLI sends only the files referenced by the main YAML. Nested include-looking text inside a partial is content and is not resolved recursively. Inline-only configurations omit the partial bundle.
Deployment requires an explicit Hub origin and organization API key. `--hub <origin>` overrides `PASEO_HUB_URL`; `--api-key <secret>` overrides `PASEO_HUB_API_KEY`. The key's organization supplies organization scope. Durable Hub login and credential persistence are not implemented.
`login` opens the Hub approval page and stores a durable organization-scoped CLI credential under `PASEO_HOME`. The stored login is separate from the daemon relationship created by `connect`. Interactive logout checks the same-origin daemon relationship and asks whether to disconnect before deleting the login. Declining removes only the login. JSON and noninteractive logout never prompt or disconnect implicitly; `--disconnect-daemon` is the explicit automation path, and `--force` applies to that daemon disconnection. If a requested disconnection fails, the login is preserved.
Every command resolves and normalizes its destination before Hub or daemon work. Origin precedence is an explicit command origin or `--hub`, then `PASEO_HUB_URL`, then the active stored login origin, then the hosted default `https://hub.paseo.sh`. The hosted default never overrides an active login. Credential precedence is `--api-key <secret>`, then `PASEO_HUB_API_KEY`, then a stored login for the exact resolved origin. A stored credential is never sent to a different origin. API keys passed through flags or the environment are not stored.
Human output reports the resolved destination before each action. JSON output keeps stdout machine-readable and includes the normalized Hub origin in command results where the destination would otherwise be lost.
See [Daemons in Hub](/docs/hub/daemons), [Hub configuration](/docs/hub/configuration), and the [Hub public API](/docs/hub/api).