Skip to content

Extension Permissions

Declare the Host API methods an extension calls, read the consent areas CompozyOS derives from them, and understand the ceilings applied per install source.

For people running agent work11 pages in this section

An extension declares one list: the Host API methods it calls. CompozyOS derives everything else — the consent summary an operator sees, the enforcement set, and the ceiling that applies to the install source.

compozysdk.NewExtension(compozysdk.ExtensionDefinition{
	Name:    "release-notes",
	Version: "0.1.0",
	Permissions: compozysdk.PermissionsConfig{
		Requires: []compozysdk.HostAPIMethod{"sessions/list", "skills/list"},
	},
	Subprocess: compozysdk.DescribeSubprocess{Command: "./bin"},
})

compozy extension build writes that list into the generated manifest:

[permissions]
  requires = ["sessions/list", "skills/list"]

Closed set

permissions.requires is validated against the closed Host API method set at build, validate, install, and daemon load. An unknown value is a hard error, never a silent no-op:

ERROR permissions.requires[0]  unknown Host API permission

Both SDKs export the method names as typed constants, so a typo fails before the daemon sees it.

The retired memory/* methods, together with the memory.read and memory.write entries, are the one exception: a manifest that still requires them keeps loading with those entries dropped. See Retired manifest entries.

CompozyOS maps every method to one area:access pair and shows the deduplicated set wherever consent is presented. compozy extension validate prints exactly what an operator will be asked to accept:

compozy extension validate ./dist/gen-<hash>
Extension package validation
===========================
Status:   valid
Issues:   0
Consent:  sessions:read, skills:read

The same summary is available structurally:

compozy extension validate ./dist/gen-<hash> -o json
{
  "manifest": {
    "name": "hello",
    "provides": ["tool.provider"],
    "permissions": ["sessions/list", "skills/list"]
  },
  "issues": [],
  "consent_areas": [
    { "area": "sessions", "access": "read" },
    { "area": "skills", "access": "read" }
  ]
}

Consent areas are a display and policy projection. Enforcement always runs against the declared method list, per call.

A subprocess bound to a workspace and named profile retains both owners for domain Host API calls. For example, tasks/create can omit the workspace and scope: the daemon binds them to the process's workspace and stamps the task with its profile. Explicit global or foreign workspace requests are refused. Resource methods retain the complete workspace_profile scope for kernel authorization; approving a palette command does not expand the extension's scope.

Permission catalog

Twenty-four consent areas cover the cataloged methods.

Consent areaHost API methods
automation:readautomation/jobs, automation/jobs/get, automation/jobs/runs, automation/runs, automation/triggers, automation/triggers/get, automation/triggers/runs
automation:writeautomation/jobs/create, automation/jobs/delete, automation/jobs/trigger, automation/jobs/update, automation/triggers/create, automation/triggers/delete, automation/triggers/fire, automation/triggers/update
clarify:askclarify/ask
heartbeat:readagents/heartbeat/get, agents/heartbeat/history, agents/heartbeat/status, agents/heartbeat/validate
heartbeat:writeagents/heartbeat/delete, agents/heartbeat/put, agents/heartbeat/rollback, agents/heartbeat/wake
logs:readlogs/list
model:readmodels/list, models/status
model:writemodels/refresh
observe:readobserve/health
resources:readresources/get, resources/list
resources:writeresources/snapshot
sessions:readsessions/events, sessions/health/get, sessions/list, sessions/status, sessions/status/get
sessions:writesessions/archive, sessions/create, sessions/prompt, sessions/stop, sessions/unarchive
skills:readskills/list
soul:readagents/soul/get, agents/soul/history, agents/soul/validate
soul:writeagents/soul/delete, agents/soul/put, agents/soul/rollback, sessions/soul/refresh
task:readtasks, tasks/dashboard, tasks/get, tasks/inbox, tasks/runs, tasks/runs/get, tasks/runs/result, tasks/timeline, tasks/tree
task:writetasks/cancel, tasks/create, tasks/runs/attach_session, tasks/runs/cancel, tasks/runs/complete, tasks/runs/enqueue, tasks/runs/fail, tasks/runs/start, tasks/update

Read and write are separate areas everywhere, so a read-only reviewer extension never requests a mutation grant. Paged collection methods (tasks, tasks/inbox, automation/jobs, automation/triggers) return bounded envelopes with page metadata — read the collection field and its page metadata together, never as a bare array.

Source ceilings

The install source decides how much of the declared list can be granted.

Install sourcePersisted tierGranted permissions
Dev link (compozy extension dev)workspaceEvery declared method.
Local path (compozy extension install ./dir)userEvery declared method.
Bundled with the daemonbundledEvery declared method.
Published (curated, github, git)marketplaceOnly methods inside the read-oriented ceiling below. Everything else is dropped at grant time with a recorded diagnostic.

The published ceiling is logs.read, observe.read, session.read, skills.read, and tool.read. A published extension that declares sessions/prompt, models/refresh, or tasks/create still installs, but those methods are not granted, and the trust report names each dropped request. Read the outcome with:

compozy extension provenance <name> -o json

Design for it: keep the published surface read-oriented, and ship anything that must mutate runtime state as a local or workspace-linked extension.

Enforcement

Every Host API call is checked against the extension's effective grant at call time. A denied call returns the protocol capability_denied error with the method name; it does not fall back to a partial result. The grant is computed once per session scope from three inputs — the declared list, the source ceiling, and the operator resource policy under [extensions.resources] — and never widens at runtime.

Resource publication (resources/snapshot) carries a second axis: the manifest declares the resource families and scope ceiling it requests under [resources.publish], and the effective grant is the narrowest of manifest request, source tier, operator policy, and session scope.

On this page