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 aPermissionGuard.
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.
Customer identity tokens
The customer-facing endpoints (/identity/*, /portal/*) use an identity token, 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.