Concepts

RBAC and approvals

Roles, scopes, and how production publishes get gated.

Showly's access model has three layers: roles on the workspace, scopes on the action, and approvals for production-impacting changes. This page covers how each layer composes.

Roles

A user's role is set at the workspace level:

RoleCan do
ownerFull access, including members, tokens, billing, workspace security, Preview, Live publishing, delete and rollback.
memberCreate projects and sites, manage product features, create Preview, and publish Live; no members or billing.
developerManage and publish existing sites and Preview; cannot create projects or manage workspace governance.
viewerRead sites, projects, deployments, notifications, and affiliate data.
billingRead projects/sites and manage billing, payment methods, refunds, coupons, and finance audit; no site writes.

Workspaces can also define custom roles (via role permissions) when the five built-ins don't fit.

A user can have at most one role per workspace. Memberships across workspaces are independent — being owner of one workspace gives you nothing in another.

Scopes

MCP tokens, API tokens, and service tokens carry scopes that are a strict subset of what their issuer can grant. A scope describes a resource:verb pair. The ten MCP scopes are:

project:read
site:read
site:write
preview:read
preview:create
checks:run
publish:request
logs:read
template:read
template:create

Roughly, viewer maps to the basic read scopes. member and developer receive the Preview/checks/publish/log scopes used by the agent loop; member additionally creates projects and has broader product-management access. billing receives finance scopes but no site or deployment writes. Only owner carries member, invite, token, workspace security, and the full billing scope set.

A token can only do what's in its scope set, regardless of who issued it. Issuing a token with a scope you don't have is rejected.

See the scope reference for the canonical scope-to-tool mapping.

Approvals

Approvals gate production-impacting changes. The most common rule: publishing to production requires N approvals from a set of allowed roles.

Approval-request defaults:

  • requiredApprovals defaults to 1.
  • allowedRoles defaults to an empty list, meaning any role may approve.
  • A reject is final — a rejected request cannot be re-approved.

When an agent calls request_publish over MCP, the resulting publish request is created with requiredApprovals: 1 and allowedRoles: ["owner", "member"]. This MCP-driven approval workflow requires the approvalWorkflows entitlement (Team and Enterprise plans).

Customize per site or per workspace in Workspace settings → Approval policy.

Separation of duties

A user cannot approve their own request. This is enforced at the data-model level: if you proposed the publish, someone else with an allowed role must approve it.

What gets audited

Every action — agent, human, API — writes an audit row:

  • actor (user id + role at the time, or MCP client id + scopes)
  • action (the scope verb + resource id)
  • outcome (allowed, denied, pending_approval, approved, rejected)
  • when

Audit rows are append-only and exported to your SIEM if you've connected one.

Emergency overrides

Showly does not currently expose an emergency publish bypass through MCP or the public Web flow. Emergency work is handled by accelerating approval on a ready Preview and then explicitly publishing it; OTP enrollment is not required. If a future break-glass path is added, it must:

  • still pass an approval (the gate is approvals, not authorization).
  • write a special emergency=true audit row.
  • open a follow-up post-mortem task automatically.