# Access And Capabilities

Divine does not invent its own permission system. It answers the question of *what you may do* with native WordPress capabilities, the same ones WordPress already uses to gate administration. This keeps access reasoning in one place: if a user can administer the site, they can use Divine, and if they cannot, Divine does not respond. The only credential Divine creates is a signed preview token, and that token is deliberately narrow.

## Authorization is a single WordPress capability

Every interaction with Divine begins with an authenticated WordPress user, and Divine checks one capability to decide whether that user may act. There is no separate Divine account system, no per-worktree role, and no privilege path around WordPress. An agent reaches Divine the same way a person does, as a WordPress user, and inherits exactly that user's capabilities.

The capability Divine requires depends on the install. The values are summarized below.

| Install | Required capability | Where Divine runs |
| --- | --- | --- |
| Single-site | `manage_options` | Normal `wp-admin`, against the one active theme. |
| Multisite | `manage_network` | Network admin, against each network site's active theme. |

The admin page, the workspace REST routes, and the export routes all require this same management capability. Divine resolves the active capability from the workspace backend, so a single check governs the admin app and the REST surface alike. The check fails closed: REST permission callbacks deny the request, and the runtime services assert the capability again before doing work, so a caller that reaches a service without going through a REST permission callback is still rejected.

## Every Divine action is capability-gated

Authentication only proves identity; it grants nothing on its own. Immediately after a user is identified, Divine checks the management capability on every operation that creates, lists, reads, edits, deploys, or destroys a worktree, and on every export. The same check applies whether the request arrives from a human in the admin app or from an agent over REST, because both resolve to the same WordPress user and the same capability.

Because the gate is a single native capability rather than a graduated set, Divine does not offer read-only or reviewer-only roles of its own. A user either can manage Divine or cannot. When you need to let someone see a specific render without granting them administration, you share a signed preview token instead, which is the one thing Divine exposes outside the admin capability.

## Preview tokens are the only shared credential

A signed preview token is the only Divine credential that can travel outside an administrator's session. Tokens exist so that a render can be shown to someone, or captured by an agent's browser tool, without handing over the management capability. Each token is purpose-scoped and time-limited: Divine stores only a hash of the token, issues it for a single purpose against a single theme target, and checks it on every request. An expired, revoked, or mismatched token is refused, and the request falls back to the live theme.

The token purposes are summarized below.

| Purpose | Issued for | Binding |
| --- | --- | --- |
| `session` | The in-app browser preview | Bound to the issuing user, the target stylesheet, and the site. |
| `share` | A shareable or capturable render URL, including `dv show` output | Bound to the target stylesheet and the site; carried in the URL. |

Tokens default to a one-hour lifetime with a minimum floor, and they record the stylesheet, app slug, and `blog_id` they were issued for. Validation rejects a token whose target does not match the registered worktree or the current site, and a `session` token used by a different user than the one it was issued to is rejected as well.

## What a preview token grants

A preview token is a way to look, not a way to act. Possessing a token, or a link that carries one, lets the holder see a render and nothing more. The separation is deliberate, and it is what makes a preview safe to share with someone who has no Divine access at all.

| A preview token lets you | A preview token does not let you |
| --- | --- |
| View a worktree or app theme render in the browser | Edit any worktree or theme file |
| Open a capturable `dv show` render URL | Create, deploy, or destroy a worktree |
| Exercise agent-built frontend behavior against real data | Reach the WordPress admin through the token |
| | Use any Divine REST workspace operation |
| | Change Divine or WordPress settings |

Because of this separation, a preview link can be handed to a reviewer who holds no `manage_options` or `manage_network` capability, and they still cannot change anything. They see the proposed theme rendered; they cannot touch the worktree, the app, or the site behind it.

## Sharing and ending access

Even though a preview token grants no power to act, treat any link that carries one as private. A render can expose unfinished templates, work-in-progress pages, or functionality an agent is still building, so share it only with people who are meant to evaluate the change.

Access ends on its own. A token expires at its timestamp, can be revoked by an administrator, and is invalidated when the worktree it points at is deployed or destroyed, because the registry record that backed it no longer exists. After any of those, the link fails closed and the site renders its live theme, so there is no long-lived credential left behind to clean up.
