Access
capsol treats every install as hosted mode. MCP URLs are addresses, not credentials. Identity comes from the authenticated credential subject.
Credential layers
Section titled “Credential layers”| Credential | Scope | Stored at rest |
|---|---|---|
| Operator bootstrap key | Registry setup and dashboard login | plaintext only in ~/.capsol/admin.key when generated; dashboard cookie stores sha256(key) |
| OAuth access token | One MCP client install/session/grant | sha256(token) in credentials.json; issued through OAuth |
| Enrollment token | Pending agent signup, then enrollment-scoped MCP credential after approval | sha256(token) |
Set CAPSOL_SECRET_KEY or CAPSOL_SECRET_KEY_FILE for hosted deployments. Keep it outside CAPSOL_DATA_DIR.
MCP connections
Section titled “MCP connections”Every capsule has a stable MCP URL:
https://capsol.example.com/mcp/<capsule-id>OAuth-capable clients should connect to that URL and let the client discover auth:
/.well-known/oauth-protected-resource/mcp/<capsule-id>/.well-known/oauth-authorization-server/.well-known/openid-configuration/oauth/registerThe client registers dynamically, runs authorization-code + PKCE S256, and receives a connection credential for that one client install/session. plain PKCE is not accepted.
The registry-level /mcp URL is allowed for OAuth when exactly one capsule exists. If there are multiple capsules and a client starts from /mcp, the authorization page asks the operator to choose the capsule before issuing the credential.
Manually copied MCP bearer credentials are disabled by default. OAuth access tokens are still transported with Authorization: Bearer <access-token> because that is the OAuth protected-resource mechanism, but capsol does not expose copy-paste connection tokens as the normal product path.
?token=... URLs return a migration error. Revoke a connection when a credential is lost or exposed.
Scopes
Section titled “Scopes”Connections are whitelist-based:
| Scope | Effect |
|---|---|
capsule:read | list, search, read allowed entries |
capsule:append | create new entries |
capsule:write | create, replace, and patch entries |
capsule:manage | operator-level capsule management in dashboard/REST/CLI surfaces |
signal:send | broadcast capsol_signal messages |
registry:manage | exposes the capsol_manage tool — agent-as-operator inside policy ceilings |
registry:approve | lets the designated supervisor principal decide the approvals queue |
Roles map to scopes for convenience: reader, appender, writer, owner. The two registry:* scopes are never part of a role, an enrollment request, or an OAuth scope set — only a human operator grants them (dashboard share creation, REST, or capsol init --grant-operator).
Operator roles (0.19)
Section titled “Operator roles (0.19)”Humans get OIDC-backed operator identities with roles instead of sharing one root key:
| Role | Can |
|---|---|
admin | Everything |
approver | Decide grants, enrollments, and proposals; read everything |
auditor | Read everything (logs included); mutate nothing |
member | Full control over capsules they own; read-only on team-visible capsules; create capsules |
OIDC logins map email → operator. Unknown emails on the allow-list auto-provision with oidc.default_operator_role (default member). Every authorization decision flows through one chokepoint (canAct(actor, action, resource)); every approval and mutation records its actor (operator:<id> or break-glass).
The admin key is break-glass: it still works everywhere, acts as a virtual admin, is logged loudly once real operators exist, and the dashboard shows a persistent banner while you use it. Prefer your operator account.
Invite teammates from Operators (or POST /v1/operators/invites): a single-use signed link, mailed when SMTP is configured and always displayed in the dashboard. Accepting binds the invited email through OIDC — password login does not exist; access is OIDC or break-glass only.
Capsule visibility and the org library (0.19)
Section titled “Capsule visibility and the org library (0.19)”Capsules are private by default. Owners can publish them: team (every operator sees them in the dashboard Library and can request access; members get read-only content access) or discoverable (additionally listed — names and descriptions only — to authenticated agents via capsol_capsules(action="discover")). Access requests are standard grant requests routed to the capsule owner and approvers.
Agent-as-operator (registry:manage)
Section titled “Agent-as-operator (registry:manage)”A principal holding registry:manage sees the capsol_manage tool: create_capsule, list_capsules, update_capsule, archive_capsule (soft — hard delete stays human-only), create_share (never above the agent’s own role or the max_share_role ceiling), and request_grant_for (files a normal request; a human approves). Every action becomes a proposal: within policy it applies instantly; a hard-ceiling breach is vetoed with a machine-readable reason the agent can adapt to; everything else queues for approval in the dashboard Proposals view.
Ceilings live in Settings → Approval policy: manage_enabled (off by default), max_capsules_per_principal, capsule_name_pattern, max_share_role, allowed_manage_actions, and manage_rate_per_hour. Bootstrap in one command:
capsol init --grant-operator my-agentSupervisor mode (registry:approve)
Section titled “Supervisor mode (registry:approve)”With approval policy autonomous_mode: "supervisor" and a supervisor_principal_id, pending enrollments and proposals route to a queue that principal decides — a human session or an agent credential carrying registry:approve — via GET /v1/approvals/pending and POST /v1/approvals/:id/approve|deny. Agent supervisors are hard-blocked (escalation_forbidden) from approving anything that would grant registry:manage or registry:approve; only humans hand out registry-level scopes. Under autonomous_mode: "policy", queued proposals auto-apply and grant requests matching an access profile flagged auto_approve clear with no human.
Content scoping
Section titled “Content scoping”Connections can be narrowed by:
allowed_schemes:["docs", "skills"]allowed_uris:["docs://readme"]allow_prefixes:["docs://public/"]deny_prefixes:["docs://public/drafts/"]
Deny wins. Effective access is the intersection of principal scope, connection scope, and content scope.
OAuth and enrollment
Section titled “OAuth and enrollment”Remote MCP clients can discover auth metadata:
/.well-known/oauth-protected-resource/mcp/<capsule-id>/.well-known/oauth-authorization-serverDynamic Client Registration is available at /oauth/register when enabled in Settings → OAuth clients. That settings panel also controls native redirect schemes, web redirect hosts, whether DCR clients need a client secret, CIMD support, and the localhost CIMD test override. Unauthenticated MCP requests return 401 with WWW-Authenticate, protected-resource metadata, and the recommended collaborator scope capsule:read capsule:append capsule:write signal:send. /.well-known/openid-configuration is available for clients that probe OIDC discovery before OAuth authorization server metadata.
When an unauthenticated user or agent reaches /oauth/authorize, capsol shows a request-access page instead of an admin-key prompt. The requester can choose scopes, schemes, exact entries, URI prefixes, label, and client type. That creates or updates a pending OAuth grant in the dashboard Grants queue. After an operator approves it, the MCP client should retry authorization; capsol recognizes the approved grant and returns the OAuth authorization code.
MCP transport requests also enforce hosted safety checks: unexpected browser Origin headers are rejected, POST requests must accept both application/json and text/event-stream, and malformed JSON-RPC payloads fail with HTTP 4xx before tool handlers run.
Operator OIDC
Section titled “Operator OIDC”For hosted registries, configure operator login from Settings → Operator OIDC in the dashboard. The dashboard stores the client secret encrypted with CAPSOL_SECRET_KEY and only returns client_secret_set status to the browser.
Environment variables are still supported for bootstrapping:
CAPSOL_OIDC_ISSUER=https://issuer.example.comCAPSOL_OIDC_CLIENT_ID=...CAPSOL_OIDC_CLIENT_SECRET=...CAPSOL_OIDC_ALLOWED_EMAILS=alice@example.com,bob@example.com# orCAPSOL_OIDC_ALLOWED_DOMAINS=example.comThe dashboard shows Continue with OIDC. The bootstrap admin key remains available for first setup and break-glass access.
Enrollment email
Section titled “Enrollment email”Configure approval email from Settings → Enrollment email in the dashboard. The SMTP URL is write-only and encrypted with CAPSOL_SECRET_KEY. Use Send test after saving settings to verify the transport. When SMTP is enabled, POST /v1/agent-enrollments attempts to email the human approver and returns email_sent.
Agent enrollment
Section titled “Agent enrollment”Agents can request access without receiving capsule data:
curl -X POST https://capsol.example.com/v1/agent-enrollments \ -H "Content-Type: application/json" \ -d '{ "client_id": "openclaw-worker-1", "capsule_id": "<capsule-id>", "agent_label": "OpenClaw worker 1", "requested_role": "appender" }'The response includes pending_human_approval, pending_supervisor_approval, or approved depending on the approval policy, plus enrollment_id, grant_request_id, verification_uri, user_code, expiry, and a one-time enrollment token. Pending polls do not return MCP connection details. After dashboard or grant approval, that token becomes an enrollment-scoped MCP credential for the new connection.
Operators can review pending OAuth grants, approve OAuth or enrollment grants, deny, expire, or revoke approved grants from the dashboard Grants page. Enrollment grants can also be approved or denied from the CLI:
capsol grants list --registry https://capsol.example.comcapsol grants approve <grant-id> --registry https://capsol.example.com --scopes capsule:readcapsol grants deny <grant-id> --registry https://capsol.example.com --reason "not needed"Approval is never a blind copy of the request. Approved scopes are intersected with the requested scopes and the registry approval-policy ceiling. The default policy is human approval with the Collaborator ceiling and no capsule:manage.