Files
paseo/docs/permissions.md
T
Mohamed Boudra adf80a9fe0 Keep Hub daemon access explicit (#4088)
* feat(hub): make daemon authority explicit

Connecting a daemon establishes presence without granting execution. Hub authority now uses semantic session permissions, with workflow execution granted explicitly and inspectable through the normal session protocol.

Attention frames remain part of the existing agent and terminal subscriptions, keeping session output solicited.

* test(server): match sentence-case tool labels
2026-08-30 22:46:24 +02:00

3.6 KiB

Daemon permissions

The daemon authorizes principals with semantic permissions. RPC names and protocol namespaces are not authority.

Model

principal -> grants
    |
    +-- authenticated by a device or service credential
    `-- opens a session with equal or narrower authority

A principal is the durable identity the daemon authorizes. A credential proves that a device or service represents it. Keep them separate so you can rotate credentials, attach more than one device, and revoke a Hub user without inventing daemon user accounts.

A pairing invitation is neither. It is an expiring, single-use exchange that creates a principal and credential with the permissions selected by its issuer.

Permissions

Permission Authority
daemon.read Daemon status, diagnostics, configuration, and provider information
daemon.manage Restart, update, configuration changes, providers, skills, and plugins
tunnel.manage Relay, Hub, service tunnel, and public endpoint relationships
access.manage Pairing invitations, principals, credentials, grants, and revocation
workspace.read Projects, workspaces, agents, timelines, files, diffs, and terminal output
workspace.write Prompts, agent control, files, terminals, git operations, and scripts
workspace.manage Create, rename, archive, and remove projects and workspaces
automation.manage Schedules, heartbeats, and loops
hub.execute The Hub-owned execution lifecycle

Agents and terminals use workspace authority. Both can execute code and mutate the workspace, so separate write permissions would claim an isolation boundary the daemon cannot enforce.

Owner, operator, and viewer are UI presets expanded into explicit permissions. Do not persist them as roles. Adding a permission must not silently widen an existing principal.

Permissions are additive allows. Missing authority denies the operation. Do not add deny precedence.

Resources

Permissions are daemon-wide today. Future grants may select workspaces or agents, but operation classification remains inside the authorization module:

type Grant = {
  permission: Permission;
  resource: { kind: "daemon" } | { kind: "workspace"; ids: string[] };
};

A delegating principal can grant only authority it already possesses. A session may attenuate its principal's grants but cannot widen them.

Workspace-scoped grants require every resource-bearing operation and outbound observation to enforce the same workspace boundary. File preview currently accepts any daemon-readable regular file, so it must gain resource enforcement before workspace-specific access ships.

Hub

The Hub authenticates as a service principal. Its locally selected grants decide whether it may execute agents, manage the daemon, manage tunnels, or manage access.

Hub user and role identifiers remain opaque external subjects. The Hub may create and revoke linked daemon principals when granted access.manage; the daemon does not interpret accounts, organizations, or roles.

Hub enrollment and permission updates exchange these semantic permissions directly. Legacy persisted Hub relationships that contain hub.execution.* migrate once to hub.execute when the daemon loads them; new relationships never persist or emit transport scopes as authority.