> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useduro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> What each credential is allowed to do — key scopes and dashboard roles.

Authority in Duro comes from two places: the **credential** you authenticate with, and (for dashboard users) the **role** that credential maps to.

## Machine credentials act with full scope

A secret key (`sk_…`) or an OAuth token carries scope `*` — full authority **within its one tenant and one mode**. There's no per-key permission slicing; a server integration is trusted to act as the merchant. Its blast radius is bounded by the tenant boundary and the mode, not by scopes.

A publishable key (`pk_…`) is the exception: it can only start checkout sessions, never read or mutate data, so it's safe in the browser or the inline SDK.

## Dashboard members are role-gated

Human users in the dashboard hold one of five roles. Every write endpoint is gated by a `PermissionGuard`.

| Role           | Can do                                                                           |
| -------------- | -------------------------------------------------------------------------------- |
| **owner**      | Everything, including tenant management. Cannot be removed or demoted.           |
| **admin**      | Everything except tenant management.                                             |
| **developer**  | Plans, customers, subscriptions, invoices, API keys, webhooks, appearance, read. |
| **finance**    | Plans, customers, subscriptions, invoices, refunds, read.                        |
| **read\_only** | Read only.                                                                       |

Team changes (invite, role change, removal) are written to an audit log. Owner and admin roles are flagged for 2FA enforcement.

## The permission set

The guard checks named permissions, derived from the role:

`tenant:manage` · `member:manage` · `plan:write` · `customer:write` · `subscription:write` · `invoice:write` · `refund:write` · `apikey:manage` · `webhook:manage` · `appearance:manage` · `read`

A `403` with code `forbidden` means the credential authenticated but lacks the permission for that route — distinct from a `401`, which means the credential itself was missing or invalid. See [Errors](/api-reference/errors).

## Customer identity tokens

The customer-facing endpoints (`/identity/*`, `/portal/*`) use an [identity token](/api-reference/authentication#customer-identity-tokens), which resolves to a person, not a tenant. It can read and manage only that customer's own data, and is rejected outright by the merchant `/v1` API.
