Repository navigation
Replace the RFS file plane with a storage-independent agent Space API and per-run credentials #359
Description
Problem
External agents reach a Space through RFS ($HUABU_RFS_URL, the huabu-rfs client, guided by apps/server/src/prompt/external-agent/rfs-cli/access-huabu.md). Two gaps make that unusable for a multi-user deployment.
1. RFS refuses every request off Disk. A route-wide hook in apps/server/src/modules/remote_fs/rfs.route.ts returns 409 unless both the structured and blob backends are Disk (the space-file-plane capability in apps/server/src/modules/storage/capabilities.ts). On Postgres + Azure, the shape a Bubble deployment needs, an external agent can't use download, upload, query, execute, agent, service or skill. That holds for administrators too.
Only download and upload really need Disk. They resolve a path through safeResolve into the Space directory and stream the file, and paths like nodes/<label>.md exist only because Disk names its sidecar files after labels. query and execute already run on the portable Space query and command layer, but they sit behind the same hook.
The capability's rationale says an external agent off Disk "reaches it through the Canvas API", but nothing in the agent prompts tells it so.
2. The RFS credential is unrestricted. The client sends Authorization: Bearer $AGENTLET_TOKEN. Agentlet gives that token, the daemon's own machine credential, to every agent process, and it reaches every Workspace and Space. The Workspace and Space in the URL (/api/rfs/w/<workspaceId>/<canvasId>) only say where to look. They don't limit access, because an agent can rewrite the URL. For this reason, #357 keeps external agents administrator-only.
Proposal
Replace the "Space as files" model with one agent-facing Space API that works on every storage backend.
| Need | Shape |
|---|---|
| Orient, inspect, search | query as it is |
| Change the Space | execute as it is |
| A node's body | Fetched by node id. Rendered from the record on any backend, with its revision for conditional requests. |
| An artifact or snapshot | Fetched by artifact key from blob storage |
| Staging bytes for a command | Upload into blob storage, then referenced by an execute command |
| Delegation, services, guides | agent, service, skill as they are |
The client should still write fetched bytes to an output file. An external agent works with its own tools (read, grep, vision, scripts), and keeping large bodies, PDFs, snapshots and Service Packages out of its context is the reason bytes arrive as files. Only the address changes, from a Disk path to a node id or artifact key.
Agents shouldn't use the web app's /api/canvas routes. Those are shaped for the UI (live updates, change-review records, browser sessions). The agent API stays agent-shaped (bounded results, generated ids, --help guidance, per-command results) and calls the same Space and storage code the web routes use.
Credentials.
- Huabu issues a per-run token bound to the person, Workspace, Space and thread.
- The agent API goes through the same request admission and Space-access check as browser requests, running in the run's Workspace scope.
- Agentlet stops handing agent processes the daemon token, or Huabu stops accepting that token on this API. Without one of these, a scoped token doesn't contain anything.
With both parts done, members could run external agents, which lifts that limitation of #357.
Scope
- Lift the blanket
space-file-planerefusal for the portable operations, and serve node bodies and artifacts by id or key from records and blob storage. - Update
access-huabu.mdand its sub-guides, thehuabu-rfsclient (packages/client-runtime/src/rfs.ts) and the shared contract inpackages/shared/src/types/api/rfs.ts. - Rename "RFS" and
HUABU_RFS_URL, since the file-system model no longer applies. Keep a compatibility path for existing agents. - Write the design as a proposal under
docs/proposals/. It replaces the file-plane parts ofdocs/proposals/agent-reachback-rfs.md. - Coordinate the Agentlet change in
external/agentlet.
Related
- Integrate Bubble with Huabu: shared identity, storage, and one server #228, the multi-user service
- feat: request-scoped Workspaces — each person works in their own #356, request-scoped Workspaces (adds the Workspace to the reachback URL)
- feat: members use the Built-In agent with their own keys; People admin; session renewal #357, member agents (keeps external agents administrator-only for the credential reason above)
- Unify RFS Skills and create/update authoring across workspace and Space scopes #244, unify RFS Skills
— posted by Claude Code (Claude Opus 5.5) (via the issue-tracker skill)
Activity