The short version: bootstrap authority and normal request authority are different
The Node creates a persistent bootstrap key under the local AgentSight configuration directory. On Unix, the file is created with mode 0600. The binding URL carries that key only so the browser can identify the Node and ask it to mint a capability. The browser then uses the capability—not the bootstrap key—for ordinary snapshot, overview, session-read, and session-message requests.
Controller relay follows the same principle with a shorter lifetime. Controller authorizes a semantic action, the Node relay client mints a local capability valid for 60 seconds for that action and optional session, and the relayed request is forwarded to the same Node HTTP protocol. The Node remains the final capability-enforcement boundary.
The credential lifecycle
| Credential | Created or supplied by | Where it lives | What it can do | Lifetime |
|---|---|---|---|---|
| Node bootstrap key | agentsight bind | Persistent private Node config; temporarily present in the binding URL fragment. | Pair a Direct browser and mint Node capabilities; authenticate the Node relay connection. | Survives Node restarts until the local key is replaced. |
| Direct browser capability | Node capability endpoint after Direct pairing | Browser Direct-connection state and Node capability store. | node.info, evidence.read, session.read, and session.message. | Requested for 12 hours by the v1.0.30 browser client. |
| Relay capability | Node relay client after Controller authorizes the requested route/action | Node-local capability state for the relayed operation. | One semantic action, optionally restricted to one session. | 60 seconds in the v1.0.30 relay client. |
| Optional synced Direct configuration | Signed-in user opt-in | Controller D1 as ciphertext plus IV; decrypted only with the Controller secret and user/Node-derived key. | Restore a compact Direct endpoint/bootstrap configuration in another browser. | Until the account copy is deleted or replaced. |
The binding key is put in a URL fragment, not a query string
cmd_bind.rs serializes action=bind, protocol version, Node endpoint, and token after #. The unit test explicitly checks that the generated binding URL contains no query string. This is a meaningful boundary: standard browsers process URI fragments client-side and do not send the fragment as part of the HTTP request for the page.
That design reduces accidental disclosure to the hosted page request path, but it does not make a binding URL harmless. Anything that can read the full URL before the browser consumes it—clipboard history, screenshots, shell history, another local process, or a person you send it to—can potentially obtain bootstrap authority. Treat the complete binding link as a secret until pairing is complete.
Direct pairing immediately exchanges bootstrap authority for scoped authority
The browser first normalizes the supplied Direct endpoint to an HTTP(S) origin with no embedded credentials, path, query, or fragment. It probes /api/v1/info with the bootstrap key, then POSTs to /api/v1/capabilities asking for the four normal Direct actions and a 12-hour TTL. The returned cap_...token becomes the credential used by the browser's normal Node client.
This makes a leaked normal Direct capability materially different from a leaked bootstrap key. The capability is bounded by action and expiry. The bootstrap key can mint new capabilities and therefore should be exposed more narrowly. Do not copy the bootstrap key into automation or long-lived browser configuration when a scoped capability is enough.
Direct still means the browser talks to the Node
A Direct connection performs browser fetch() calls against the configured Node endpoint and supplies the capability in the Authorization header. The frontend marks loopback and local address spaces explicitly for browser local-network handling. A Direct endpoint can be loopback, a private address, or an HTTPS hostname; the browser has to be able to reach it.
The Node's --app-url determines the allowed browser origin for Direct access. If the Node listens on an unspecified address such as 0.0.0.0 or ::, AgentSight requires an explicit browser-reachable --endpoint instead of pretending the wildcard listen address is a usable URL. These checks solve endpoint identity and browser access; they do not provide network-layer encryption for a plain HTTP endpoint.
Relay changes the transport, not the Node protocol
With the default hosted app, agentsight bind also starts a WebSocket relay connection to the Controller. The Node authenticates that outbound connection with its bootstrap credential. Controller can then forward only an allowlisted subset of the Node protocol: capability minting internally, snapshot, overview, one-session reads, and session messages. Arbitrary Node paths and query shapes are rejected by the relay client before local forwarding.
For normal relayed data and control operations, the relay client does not forward the persistent bootstrap key. It maps the request to a semantic action, mints a 60-second Node-local capability, and forwards the request to the local Node with that capability. The implementation also bounds concurrent relay requests to eight, sets a 24-second request timeout, and caps a relay response at 16 MiB.
Detailed payloads can transit Controller relay without becoming Controller history
“Node-authoritative” does not mean a relayed response never crosses Controller. A snapshot or session response requested through Relay necessarily transits the relay path while that request is active. The architecture boundary is persistence: Controller coordinates the request and the response can exist in runtime memory, while detailed Node payloads are not stored as a Controller telemetry history.
This distinction matters when choosing a deployment mode. If the requirement is that detailed evidence never transit the hosted relay, use Local or a Direct path you control. If managed remote connectivity is acceptable, Relay provides a constrained path while the Node remains authoritative for the session data.
Cloud-synced Direct configuration is explicit and encrypted, but it is still bootstrap material
Direct configuration stays in the current browser by default. AgentSight also has an explicit signed-in opt-in that can save a compact Direct configuration for use from another browser. The Controller code encrypts that configuration with AES-256-GCM. The encryption key is derived with HKDF-SHA-256 from a 32-byte Controller secret plus the user and Node identifiers; those identifiers are also bound as authenticated additional data.
D1 stores ciphertext, IV, and version rather than plaintext Direct configuration. That is a storage protection boundary, not an argument that the synced configuration is low-value. The decrypted object still contains the endpoint and bootstrap access key, so enabling cross-browser sync deliberately moves recoverable bootstrap material into the hosted coordination path.
Choose the connection mode from the trust requirement
| Requirement | Prefer | Reason |
|---|---|---|
| One machine; no hosted coordination needed | Local | No Controller account or remote transport is required. |
| Browser can reach the Node over loopback, LAN, VPN, or your HTTPS endpoint | Direct | The browser reads the Node directly with a scoped capability. |
| Need hosted identity, organization discovery, roles, or managed remote connectivity | Controller-managed / Relay | Controller authorizes access and relays the bounded Node protocol when Direct is unavailable. |
| Detailed runtime payload must not transit AgentSight-hosted infrastructure | Local or Direct | Do not use Relay for the payload path; keep connectivity under your control. |
What not to infer from the design
A capability system does not make an exposed HTTP Node safe on an untrusted network; transport security and endpoint exposure are separate controls. A URL fragment reduces server-side request leakage but does not protect a copied binding URL from whoever can read it. Encrypted cross-browser Direct sync protects stored plaintext in D1 but still places recoverable bootstrap material behind the Controller secret and account authorization. Finally, Relay being non-authoritative storage does not mean payload bytes never transit Relay memory.
Primary sources
- AgentSight v1.0.30 bind implementation: Node bootstrap key, URL fragment, endpoint normalization, CORS origin, and relay startup
- AgentSight v1.0.30 browser Node client: pairing, Direct capability minting, transport selection, and browser persistence
- AgentSight v1.0.30 relay client: allowlisted Node routes, short-lived relay capabilities, request bounds, and local forwarding
- AgentSight v1.0.30 Controller crypto: optional Direct configuration encryption with HKDF-SHA-256 and AES-256-GCM
- AgentSight v1.0.30 Node capability enforcement
- MDN URI fragment reference: fragments are handled by the client and are not sent with the resource request