Extensions

Extension Scopes

Extensions operate within a strict scope ceiling. Only scopes marked extensionAllowed may appear in an extension manifest. Human, admin, and management scopes are never grantable to extensions.

Choose the smallest scope set that supports demonstrated behavior. Once selected, continue to installation and configuration.

How scopes flow

Scopes are declared in the extension manifest, snapshotted into a published version, and issued to an install. At each stage Throttle enforces the extensionAllowed ceiling:

  1. Manifest declaration. You list the scopes your extension needs in POST /api/v1/extensions or PATCH /api/v1/extensions/:id. validateScopesForExtension runs immediately — any scope with extensionAllowed: false (or an unknown scope) returns 400 invalid_scope.
  2. Version snapshot. When you publish a version, the manifest scopes are frozen into the version record. Subsequent manifest edits do not change the published version.
  3. Install. POST /api/v1/extensions/:id/install pins the install to a version. The install's API key is granted exactly the version's scopes — no more, no less.
  4. Iframe JWT. The launch-token endpoint mints a JWT whose scopes claim is the pinned version's scope list. Every bridge.api.* call is authorized against those scopes.
Manifest with scopes
// Extension manifest with scopes
{
  "name": "Order Inspector",
  "iframeUrl": "https://extensions.example.com/orders",
  "webhookUrl": "https://extensions.example.com/webhooks",
  "eventSubscriptions": ["order.created", "order.updated", "payment.captured"],
  "scopes": [
    "orders:read",     // required for order.* events + GET /api/v1/orders
    "payments:read",   // required for payment.* events + GET /api/v1/payments
    "customers:read"   // optional — allows reading customer records
  ]
}
Scope ceiling in practice
// The extension's JWT token carries the scopes from the pinned version.
// Calling a route that requires a scope not in that list returns:
// HTTP 403 { error: { code: "insufficient_scopes", ... } }
// Good — orders:read is in the manifest scopes:
const orders = await bridge.api.get('/api/v1/orders?limit=10');
// Bad — payment_refunds:write is NOT extensionAllowed; the manifest
// would have been rejected at registration time:
// await bridge.api.post('/api/v1/payments/pay_xxx/refund', { amount: 500 });
// → 400 invalid_scope at extension create/update time

Scope implication rules

The same implication rules that apply to API keys apply to extension scopes:

  • * covers all scopes — but * is never extensionAllowed and cannot appear in an extension manifest.
  • resource:write implies resource:read on the same resource. For example, orders:write covers orders:read.
  • Read never implies write. orders:read does NOT grant orders:write.
  • No cross-resource implication. orders:read does not grant customers:read.

Management scopes for extensions

The management scopes (extensions:read, extensions:write, extensions:install) control who can author and install extensions. These are Taxonomy B (human) scopes — they are not extensionAllowed. Extensions cannot manage other extensions.

Management scope summary

  • extensions:read — view the extension catalog and installation list. Required for GET /api/v1/extensions, GET /api/v1/extensions/:id, GET /api/v1/extensions/:id/versions, GET /api/v1/installations, GET /api/v1/installations/:id/deliveries.
  • extensions:write — author, version, and publish extensions. Required for POST /api/v1/extensions, PATCH /api/v1/extensions/:id, POST /api/v1/extensions/:id/versions, POST /api/v1/extensions/:id/versions/:vid/publish , POST /api/v1/extensions/:id/lifecycle (draft/private).
  • extensions:install — install, configure, and manage installs. Required for POST /api/v1/extensions/:id/install, POST /api/v1/extensions/:id/uninstall, PATCH /api/v1/installations/:id/config, POST /api/v1/installations/:id/upgrade, POST /api/v1/installations/:id/launch-token, POST /api/v1/installations/:id/deliveries/:deliveryId/replay , POST /api/v1/installations/:id/test.
install does not imply write or read
The extensions:install scope is a custom action — it is independent of extensions:write and extensions:read. Granting only extensions:install to a key lets it manage installations without being able to author or list the catalog.

Team RBAC for extension management

Dashboard (Clerk) callers are additionally gated by RBAC permissions, not just scopes. The relevant RBAC keys are:

  • application:extensions:read — all app roles ( admin | developer | finance | viewer).
  • application:extensions:write — app admin and developer.
  • application:extensions:install — app admin and developer.
  • application:extensions:admin — required to promote an extension to public or to delete a catalog entry. Only admin role.

Workspace owners and workspace admins have implicit admin role on every application. See the Permissions reference for the full role-capability matrix.

Extension-allowed scope catalog

The following scopes may appear in an extension manifest. They are all extensionAllowed: true and sourced directly from the live scope registry — they update automatically when new scopes are added.

Applications

  • applications:read — View applications
  • applications:write — Manage applications

Carts

  • carts:read — View carts
  • carts:write — Manage carts
  • cart_items:read — View line items
  • cart_items:write — Manage line items
  • checkout_sessions:read — View checkout sessions
  • checkout_sessions:write — Manage checkout sessions

Connectors

  • connectors:read — View connectors
  • connectors:write — Manage connectors
  • connector_activations:write — Activate/deactivate connectors

Customers

  • customers:read — View customers
  • customers:write — Manage customers
  • customer_pii:read — View customer PII (sensitive)
  • customer_addresses:read — View addresses
  • customer_addresses:write — Manage addresses
  • customer_payment_methods:read — View stored cards (sensitive)
  • customer_payment_methods:write — Manage stored cards (sensitive)

Discounts

  • discounts:read — View discounts
  • discounts:write — Manage discounts

Fulfillments

  • fulfillments:read — View fulfillments
  • fulfillments:write — Manage fulfillments
  • fulfillment_shipments:write — Update shipments
  • fulfillment_digital:read — View digital delivery
  • fulfillment_digital:write — Manage digital delivery
  • fulfillment_access:write — Manage access credentials
  • fulfillment_services:write — Manage service fulfillment

Invoices / AR

  • invoices:read — View invoices & aging
  • invoice_payments:write — Mark invoices paid (sensitive)
  • invoice_dunning:write — Send dunning notices

Orders

  • orders:read — View orders
  • orders:write — Manage orders
  • order_cancellations:write — Cancel orders
  • order_returns:read — View returns
  • order_returns:write — Process returns

Payments

  • payments:read — View payments
  • payments:write — Create payments
  • payment_authorizations:write — Authorize payments
  • payment_captures:write — Capture payments
  • payment_refunds:read — View refunds (sensitive)
  • payment_refunds:write — Refund payments (sensitive)
  • payment_voids:write — Void payments (sensitive)
  • payment_disputes:read — View disputes (sensitive)
  • payment_disputes:write — Handle disputes (sensitive)
  • payment_methods:read — View payment methods (sensitive)
  • payment_methods:write — Tokenize payment methods (sensitive)

Quotes

  • quotes:read — View quotes
  • quotes:write — Manage quotes

Shipping & Tax

  • shipping_tax:read — View shipping/tax config
  • shipping_tax:write — Edit shipping/tax config
  • shipping_tax_publications:write — Publish shipping/tax config
  • shipping_quotes:write — Request shipping quotes
  • tax_calculations:write — Calculate tax
  • shipping_tax_quote_tokens:read — View quote tokens
  • shipping_tax_quote_tokens:write — Manage quote tokens
  • shipping_tax_snapshots:write — Accept external snapshots

Subscriptions

  • subscriptions:read — View subscriptions
  • subscriptions:write — Manage subscriptions
  • subscription_pauses:write — Pause/resume subscriptions
  • subscription_cancellations:write — Cancel subscriptions

Webhooks & Events

  • webhooks:read — View webhooks
  • webhooks:write — Manage webhooks
  • webhook_deliveries:read — View deliveries
  • webhook_deliveries:write — Retry deliveries
  • events:read — View events
  • audit_logs:read — View audit log

Workspace

  • merchant:read — View workspace settings
  • merchant:write — Edit workspace settings
  • embed_config:read — View embed config
  • embed_config:write — Edit embed config
  • branding:write — Upload branding assets
Full scope catalog
The complete scope catalog, including non-extension scopes, is at API key scopes and served live at GET /api/v1/scopes.