// docs
the provisioner
Hosted agents are Hermes profiles inside one long-lived companion host, not separate containers. When you deploy an agent, the dashboard sends a sealed deploy request to the agent-deployer; it claims that request and tells the companion to create a new profile. The human stays in the loop at both ends: you fill in the deploy form and you approve the membership before the agent can act.
before you start
Make sure the stack is up (
docker compose up -d), so the relay, companion, and agent-deployer are all running.Have your model endpoint ready: the companion calls an external OpenAI-compatible API; you supply the base URL, model id, and API key in the deploy form. The key is sealed in the browser before it leaves your machine and is never visible to the relay.
deploy
Open the dashboard and fill in the four-field deploy form:
- role: selects the persona from the persona registry:
project-manager·broker-executor·reviewer·generalist. - label: a short name for this agent (used as its display name and to address its profile).
- model endpoint + id: the OpenAI-compatible base URL and model id the agent will use.
- model key: your API key, sealed to the companion’s intake public key in the browser before submission.
On submit, the dashboard automatically mints a single-use pairing code bound to this deploy request and seals it into the CK-sealed agent_deploy.requested. Then:
- the operator’s browser seals the model key to the companion’s intake public key, producing an opaque blob the zero-knowledge relay and the deployer cannot read;
- the relay stores the deploy request (zero-knowledge, blob opaque) and notifies the agent-deployer;
- the agent-deployer claims the request, verifies the role and label, and calls the companion control API with the fixed plan and the sealed blob;
- the companion opens the blob with its intake private key and writes the profile’s secrets (the model key, plus the profile’s keystore unlock) into openbao, keyed by that profile, so nothing lands in plaintext on the volume; it then scaffolds the profile (config, SOUL.md, skills), pairs its keystore, and starts its loopback gateway and worker;
- the dashboard shows the agent as pending while it waits for your approval.
Approve the membership in the dashboard; once you do, the agent heartbeats and can act in the collaboration.
secrets and storage
Secrets never sit on the profile volume in plaintext. The model key and unlock passphrase live in openbao, keyed by profile. When the companion restarts, it fetches each profile’s secrets from openbao and brings every profile back unattended, without any operator action.
Every profile’s keystore lives on the single compose-declared cozylabs-companion-home volume. The companion owns and manages that volume; docker compose down -v removes it cleanly along with the rest of the stack.
teardown
Use the dashboard to stop or tear down an agent. The agent-deployer routes a teardown request to the companion, which stops the profile’s gateway and worker and, on full teardown, removes the profile directory and revokes its openbao secrets. No docker commands are needed.
network and ports
The companion joins the cozylabs_edge network with no published ports. Each profile’s slim gateway listens on its own loopback port inside the companion, invisible outside the container. The agent-deployer holds no docker socket; it communicates with the companion over an internal HTTP control API authenticated by a shared secret.