Permissions reference
This page catalogs the granular permission model that governs every CM Box API call: the key format, scopes, type-aware variants, the built-in bundles, and the full permission catalog. The identity making the call — a user or a service account — must hold the permission an endpoint requires, or the call is denied.
Permission keys
Section titled “Permission keys”A permission is a dotted key in the form domain.action[.qualifier], for
example content.create, sites.publish, or admin.security.roles.update.
Only registered keys are meaningful; the full catalog is
below.
Scopes
Section titled “Scopes”Every permission has one of three scopes, which determines where a grant applies:
| Scope | Domains | A grant applies to |
|---|---|---|
global |
admin.* |
The whole instance |
repo |
content.*, folders.*, packages.* |
A specific repository (or all, if granted globally) |
site |
sites.* |
A specific site (or all, if granted globally) |
Type-aware permissions
Section titled “Type-aware permissions”Most content.* permissions are type-aware: they can be held in a
type-qualified form <key>:<typeId> (for example content.create:Article)
to grant the action for one content type only. The type-aware keys are:
content.create, content.update, content.update.metadata,
content.update.security, content.delete, content.copy,
content.publish, content.unpublish, content.publish.schedule,
content.skip_workflow, content.version.restore,
content.rendition.create, content.rendition.delete
Enforcement OR-checks the base key and the qualified variant:
| Grant held | Effect |
|---|---|
content.create (base key) |
Create items of any type |
content.create:Article |
Create items of type Article only |
A check for a type-aware key with no specific type (for example, “can this identity create anything at all?”) matches if the identity holds the base key or any type-qualified variant of it.
How a check is resolved
Section titled “How a check is resolved”For each API call, enforcement resolves the calling identity’s effective permissions and matches the required key against them:
- Admin wildcard. An identity with the
adminrole passes every check. - Effective grants are built by walking the identity’s roles (assigned
directly or through groups) and accumulating: bundle permissions and
overrides.grant[]into the global set,permissions.global[]into the global set,permissions.repos[repoId][]into that repository’s set, andpermissions.sites[siteId][]into that site’s set. - Revokes apply last. Keys in
overrides.revoke[]are removed from the global set and from every repository and site set. Revoke wins over any grant. - Match. The check passes if the key (or its type-qualified / any-typed variant) is in the global set, the set for the request’s repository, or the set for the request’s site.
Because bundle permissions land in the global set, assigning a bundle
grants its permissions across all repositories and sites. To limit a role to
one repository or site, put keys in the role’s scoped map
(permissions.repos[<repoId>] / permissions.sites[<siteId>]) instead of
using a bundle.
Role anatomy
Section titled “Role anatomy”Roles carry all grants. The permission-related fields:
| Field | Type | Purpose |
|---|---|---|
users |
string[] |
Users assigned this role |
groups |
string[] |
Groups whose members get this role |
bundles |
string[] |
Bundle IDs the role inherits from (grant globally) |
permissions.global |
string[] |
Keys granted at global scope |
permissions.repos |
{ <repoId>: string[] } |
Per-repository grants; entries may be type-qualified (content.update:Article) |
permissions.sites |
{ <siteId>: string[] } |
Per-site grants |
overrides.grant |
string[] |
Extra keys granted globally, on top of bundles |
overrides.revoke |
string[] |
Keys removed from every scope; applied last |
Built-in bundles
Section titled “Built-in bundles”A bundle is a named permission set referenced from a role’s bundles[].
Eleven bundles ship by default; administrators can edit them or create new
ones at runtime. Remember that a bundle grants its permissions globally.
| Bundle ID | Name | Grants (summary) |
|---|---|---|
bundle.viewer |
Viewer | Read-only — the *.view permissions plus sites.preview |
bundle.content_contributor |
Content Contributor | Create/edit content, folders, renditions. No publish, no delete |
bundle.content_editor |
Content Editor | Contributor plus delete, publish, schedule, version restore, bulk actions |
bundle.site_builder |
Site Builder | Edit sites, pages, navigation, settings, preview. No publish |
bundle.site_publisher |
Site Publisher | Site Builder plus sites.publish and sites.publish.schedule |
bundle.package_author |
Package Author | Create/edit/stage packages, manage package items, update-from-base, diff view |
bundle.package_publisher |
Package Publisher | packages.merge, packages.publish, packages.merge_publish, diff view |
bundle.content_architect |
Content Architect | Taxonomies, categories, content types |
bundle.repo_admin |
Repository Admin | Repository settings, security config, features, crawls, migrations |
bundle.security_admin |
Security Admin | Users, groups, roles, service accounts, directory sync |
bundle.system_admin |
System Admin | Settings, storage, webhooks, indexes, workflows, queue, repository create/delete, instance setup |
Workflow approve/reject decisions are governed by the workflow engine on a
per-package basis, not by the package bundles: bundle.package_author and
bundle.package_publisher control who can author and merge/publish, while
the workflow definition controls who approves.
Permission catalog
Section titled “Permission catalog”All registered keys, by domain. Type-aware keys are marked (T).
sites.* — scope: site
Section titled “sites.* — scope: site”| Key | Description |
|---|---|
sites.create |
Create a new site |
sites.delete |
Delete a site |
sites.edit |
Open the site builder for editing |
sites.update.settings |
Edit site name/description/domain/theme |
sites.update.permissions |
Change site read/write/delete permissions |
sites.publish |
Publish site |
sites.publish.schedule |
Schedule a future site publish |
sites.page.add |
Add a page to a site |
sites.page.remove |
Remove a page from a site |
sites.page.reorder |
Reorder site navigation |
sites.page.update |
Edit a page’s slug/title/template binding |
sites.preview |
Open a site preview |
content.* — scope: repo
Section titled “content.* — scope: repo”| Key | Description |
|---|---|
content.create (T) |
Create a content item |
content.update (T) |
Edit a content item’s body/fields |
content.update.metadata (T) |
Edit non-body metadata (tags, categories, slug) |
content.update.security (T) |
Edit read/write/delete permissions on the item |
content.delete (T) |
Delete/archive an item |
content.copy (T) |
Duplicate an item |
content.publish (T) |
Publish an item directly |
content.unpublish (T) |
Unpublish an item |
content.publish.schedule (T) |
Schedule an item publish |
content.skip_workflow (T) |
Bypass strict auto-package/workflow rules and save directly to the main repository |
content.version.view |
View an item’s version history |
content.version.restore (T) |
Restore a previous version |
content.references.view |
View an item’s references / dependencies |
content.rendition.create (T) |
Generate or upload a rendition |
content.rendition.delete (T) |
Remove a rendition |
content.bulk |
Perform bulk actions (move, delete, tag) |
folders.* — scope: repo
Section titled “folders.* — scope: repo”| Key | Description |
|---|---|
folders.create |
Create a folder |
folders.update |
Rename / move a folder |
folders.delete |
Delete a folder |
folders.delete.recursive |
Delete a folder along with its contents |
packages.* — scope: repo
Section titled “packages.* — scope: repo”| Key | Description |
|---|---|
packages.create |
Create a package |
packages.update |
Edit package metadata |
packages.delete |
Delete a package |
packages.items.add |
Add items to a package |
packages.items.remove |
Remove items from a package |
packages.update_from_base |
Pull base changes into a package |
packages.diff.view |
View merge / page diff for a package |
packages.merge |
Merge a package into base (no publish) |
packages.publish |
Publish merged items |
packages.merge_publish |
Combined approve/merge/publish |
packages.auto_package.configure |
Manage auto-package rules |
admin.* — scope: global
Section titled “admin.* — scope: global”| Key | Description |
|---|---|
admin.taxonomies.create |
Create a taxonomy |
admin.taxonomies.update |
Edit a taxonomy |
admin.taxonomies.delete |
Delete a taxonomy |
admin.categories.create |
Create a category |
admin.categories.update |
Edit a category |
admin.categories.delete |
Delete a category |
admin.types.create |
Create a content type |
admin.types.update |
Edit a content type schema |
admin.types.delete |
Delete a content type |
admin.types.lock |
Lock a content type from edits |
admin.types.unlock |
Unlock a content type |
admin.repositories.create |
Create a repository |
admin.repositories.delete |
Delete a repository |
admin.repositories.update |
Edit repository settings |
admin.repositories.security.update |
Edit a repository’s security membership (maintainers, contributors, viewers) |
admin.repositories.features.toggle |
Enable repository-level features (GraphQL, renditions, etc.) |
admin.repositories.crawl |
Start a repository crawl/sync |
admin.repositories.migration.run |
Run a content migration |
admin.security.users.view |
View users |
admin.security.users.create |
Create users |
admin.security.users.update |
Edit users |
admin.security.users.delete |
Delete users |
admin.security.groups.view |
View groups |
admin.security.groups.create |
Create groups |
admin.security.groups.update |
Edit groups |
admin.security.groups.delete |
Delete groups |
admin.security.roles.view |
View roles |
admin.security.roles.create |
Create roles |
admin.security.roles.update |
Edit roles |
admin.security.roles.delete |
Delete roles |
admin.security.serviceAccounts.view |
View service accounts |
admin.security.serviceAccounts.create |
Create service accounts |
admin.security.serviceAccounts.update |
Edit service accounts |
admin.security.serviceAccounts.delete |
Delete service accounts |
admin.security.serviceAccounts.regenerate_key |
Regenerate a service account key |
admin.security.sync |
Sync users/groups from the identity directory |
admin.settings.view |
View system settings |
admin.settings.update |
Edit system settings |
admin.storage.configure |
Configure storage backends |
admin.webhooks.view |
View webhooks |
admin.webhooks.create |
Create webhooks |
admin.webhooks.update |
Edit webhooks |
admin.webhooks.delete |
Delete webhooks |
admin.webhooks.trigger |
Manually trigger a webhook |
admin.indexes.view |
View search indexes |
admin.indexes.manage |
Create/manage/rebuild search indexes |
admin.workflows.definitions.view |
View workflow definitions |
admin.workflows.definitions.create |
Create workflow definitions |
admin.workflows.definitions.update |
Edit workflow definitions |
admin.workflows.definitions.delete |
Delete workflow definitions |
admin.workflows.connections.view |
View workflow connections |
admin.workflows.connections.create |
Create workflow connections |
admin.workflows.connections.update |
Edit workflow connections |
admin.workflows.connections.delete |
Delete workflow connections |
admin.queue.view |
View job queue state |
admin.queue.manage |
Retry/cancel queue jobs |
admin.instance_setup |
Run the initial instance setup |
Endpoint permission requirements
Section titled “Endpoint permission requirements”Endpoints that enforce a specific permission state it in their OpenAPI
description in the form “Requires the <key> permission” — for example,
POST /api/settings requires admin.settings.update, and the package-merge
preview endpoint requires packages.merge. Check the endpoint’s entry in the
REST API Reference section of the sidebar for the permission it requires.
Permission gates fail closed: if the check does not pass, the call is denied.
To see the permissions your own token holds, call
GET /api/security/me/permissions — see
Authentication.