cgcardona / muse public
hub.md markdown
311 lines 7.2 KB
368bcde6 Add security test coverage and reference documentation Gabriel Cardona <gabriel@tellurstori.com> 9h ago
1 # `muse hub` — MuseHub Fabric Connection Reference
2
3 The hub is not just a remote. It is the **primary identity fabric** — the
4 shared coordination layer where authentication, plugin discovery, and
5 multi-agent state synchronisation come together.
6
7 ---
8
9 ## Table of Contents
10
11 1. [Hub vs. Remote](#hub-vs-remote)
12 2. [Commands](#commands)
13 - [muse hub connect](#muse-hub-connect)
14 - [muse hub status](#muse-hub-status)
15 - [muse hub disconnect](#muse-hub-disconnect)
16 - [muse hub ping](#muse-hub-ping)
17 3. [HTTPS Enforcement](#https-enforcement)
18 4. [Redirect Refusal](#redirect-refusal)
19 5. [Configuration](#configuration)
20 6. [Typical Setup Workflow](#typical-setup-workflow)
21
22 ---
23
24 ## Hub vs. Remote
25
26 Muse uses two distinct concepts for network connections:
27
28 | | `muse hub` | `muse remote` |
29 |---|---|---|
30 | **Purpose** | Primary identity fabric | Generic push/pull endpoint |
31 | **Cardinality** | At most one per repo | Many per repo |
32 | **Manages** | Authentication, discovery, coordination | Object transport |
33 | **Config location** | `[hub] url` in `.muse/config.toml` | `[remotes.<name>]` in `.muse/config.toml` |
34 | **Credentials** | Stored in `~/.muse/identity.toml` | Inherited from hub identity |
35 | **Commands** | `connect`, `status`, `disconnect`, `ping` | `add`, `remove`, `rename`, `list`, `get-url`, `set-url` |
36
37 A repository has **at most one hub**. It may have many remotes. When you
38 `muse push` to a remote that lives on the same MuseHub instance as the
39 configured hub, the hub's token is used automatically.
40
41 ---
42
43 ## Commands
44
45 ### muse hub connect
46
47 Attach this repository to a MuseHub instance.
48
49 ```
50 muse hub connect <URL>
51 ```
52
53 **Arguments:**
54
55 | Argument | Description |
56 |---|---|
57 | `URL` | MuseHub URL (e.g. `https://musehub.ai` or just `musehub.ai`). |
58
59 **What connect does:**
60
61 1. Normalises the URL (see [HTTPS Enforcement](#https-enforcement)).
62 2. Warns if the repo is already connected to a different hub.
63 3. Writes `[hub] url = "<url>"` to `.muse/config.toml`.
64 4. If an identity already exists for this hub in `~/.muse/identity.toml`,
65 shows the stored name and type.
66 5. If no identity exists, prompts to run `muse auth login`.
67
68 **Does not** modify `~/.muse/identity.toml` — use `muse auth login` to
69 authenticate after connecting.
70
71 **Examples:**
72
73 ```bash
74 # With full HTTPS URL
75 muse hub connect https://musehub.ai
76
77 # Bare hostname — HTTPS added automatically
78 muse hub connect musehub.ai
79
80 # Switch hubs (warns before overwriting)
81 muse hub connect https://staging.musehub.ai
82 ```
83
84 ---
85
86 ### muse hub status
87
88 Show the hub connection and identity for this repository.
89
90 ```
91 muse hub status [--json]
92 ```
93
94 **Options:**
95
96 | Flag | Description |
97 |---|---|
98 | `--json` | Emit JSON instead of human-readable output. |
99
100 **Human-readable output:**
101
102 ```
103 Hub
104 URL: https://musehub.ai
105 Type: human
106 Name: Alice
107 ID: usr_abc123
108 Token: set (Bearer ***)
109 Caps: read:* write:midi
110 ```
111
112 **JSON output** (`--json`):
113
114 ```json
115 {
116 "hub_url": "https://musehub.ai",
117 "hostname": "musehub.ai",
118 "authenticated": true,
119 "identity_type": "human",
120 "identity_name": "Alice",
121 "identity_id": "usr_abc123"
122 }
123 ```
124
125 When no identity is stored, `authenticated` is `false` and no identity fields
126 appear.
127
128 **Agent pattern:**
129
130 ```bash
131 muse hub status --json | jq .authenticated
132 ```
133
134 ---
135
136 ### muse hub disconnect
137
138 Remove the hub association from this repository.
139
140 ```
141 muse hub disconnect
142 ```
143
144 Removes `[hub] url` from `.muse/config.toml`. Credentials in
145 `~/.muse/identity.toml` are **preserved** — use `muse auth logout` to remove
146 them as well.
147
148 **Examples:**
149
150 ```bash
151 # Remove hub association only
152 muse hub disconnect
153
154 # Remove hub association + credentials
155 muse hub disconnect
156 muse auth logout --hub https://musehub.ai
157 ```
158
159 ---
160
161 ### muse hub ping
162
163 Test HTTP connectivity to the configured hub.
164
165 ```
166 muse hub ping
167 ```
168
169 Sends `GET <hub_url>/health` and reports the result.
170
171 **Exit codes:**
172
173 | Code | Meaning |
174 |---|---|
175 | `0` | Hub is reachable (2xx response) |
176 | Non-zero | Hub is unreachable or returned an error |
177
178 **Examples:**
179
180 ```bash
181 muse hub ping
182 # Pinging musehub.ai… ✅ HTTP 200 OK
183
184 muse hub ping
185 # Pinging staging.musehub.ai… ❌ timed out
186
187 # Use in a healthcheck script
188 muse hub ping || notify-send "MuseHub unreachable"
189 ```
190
191 ---
192
193 ## HTTPS Enforcement
194
195 All hub URLs are required to use HTTPS. The `_normalise_url()` function:
196
197 - Adds `https://` when no scheme is present.
198 - Raises `ValueError` (shown as a user-facing error) when an explicit
199 `http://` scheme is given.
200
201 ```bash
202 # These are all equivalent
203 muse hub connect musehub.ai
204 muse hub connect https://musehub.ai
205 muse hub connect https://musehub.ai/
206
207 # This is rejected — bearer tokens must not travel over cleartext HTTP
208 muse hub connect http://musehub.ai
209 # ❌ Insecure URL rejected: 'http://musehub.ai'
210 # MuseHub requires HTTPS. Did you mean: https://musehub.ai
211 ```
212
213 The HTTPS enforcement is a hard requirement, not a preference. Bearer tokens
214 are authentication credentials — sending them over cleartext HTTP exposes them
215 to any network observer between the agent and the hub.
216
217 ---
218
219 ## Redirect Refusal
220
221 The `ping` command uses a custom `_NoRedirectHandler` that refuses all HTTP
222 redirects. When the hub returns a 3xx response:
223
224 ```
225 ❌ Redirect refused (301): hub redirected to 'https://other.host/'.
226 Update the hub URL.
227 ```
228
229 **Why this matters:**
230
231 A hub that silently redirects `GET /health` to a different host is misleading
232 about what was actually reached. More importantly, allowing redirects on the
233 `push` and `fetch` paths would cause the `Authorization: Bearer <token>` header
234 to be forwarded to the redirect destination — potentially a different host
235 entirely.
236
237 If your MuseHub instance redirects (e.g. from `www.musehub.ai` to
238 `musehub.ai`), update the hub URL to the final destination:
239
240 ```bash
241 muse hub connect musehub.ai # not www.musehub.ai
242 ```
243
244 ---
245
246 ## Configuration
247
248 Hub connection state is stored in `.muse/config.toml`:
249
250 ```toml
251 [hub]
252 url = "https://musehub.ai"
253 ```
254
255 This file is per-repository and may be committed to version control — it
256 contains only the hub URL, never any credentials. Credentials live in
257 `~/.muse/identity.toml` (see [`auth.md`](auth.md)).
258
259 ---
260
261 ## Typical Setup Workflow
262
263 ### New repository
264
265 ```bash
266 # 1. Initialise
267 muse init --domain midi
268
269 # 2. Connect to hub
270 muse hub connect https://musehub.ai
271
272 # 3. Authenticate
273 muse auth login
274
275 # 4. Add the remote (MuseHub creates it on first push)
276 muse remote add origin https://musehub.ai/repos/my-song
277
278 # 5. First push
279 muse push origin -u
280 ```
281
282 ### Cloned repository
283
284 `muse clone` sets the `origin` remote automatically. Connect the hub
285 separately if you want `muse hub status` to work:
286
287 ```bash
288 muse clone https://musehub.ai/repos/my-song
289 cd my-song
290 muse hub connect https://musehub.ai
291 muse auth login # if not already logged in on this machine
292 ```
293
294 ### CI/CD agent
295
296 ```bash
297 # In the pipeline environment
298 muse hub connect https://musehub.ai
299 MUSE_TOKEN="$CI_MUSE_TOKEN" muse auth login \
300 --agent \
301 --name "ci-agent-${BUILD_NUMBER}"
302 muse push origin
303 ```
304
305 ---
306
307 *See also:*
308
309 - [`docs/reference/auth.md`](auth.md) — `muse auth login/whoami/logout`
310 - [`docs/reference/remotes.md`](remotes.md) — `muse push/fetch/clone`
311 - [`docs/reference/security.md`](security.md) — security architecture