klaviyo-enterprise-rbac

Configure Klaviyo enterprise access control with API key scopes and OAuth. Use when implementing per-key scoping, configuring OAuth app authorization, or setting up organization-level access controls for Klaviyo. Trigger with phrases like "klaviyo scopes", "klaviyo RBAC", "klaviyo enterprise", "klaviyo permissions", "klaviyo OAuth", "klaviyo access control".

Allowed Tools

ReadWrite

Provided by Plugin

klaviyo-pack

Claude Code skill pack for Klaviyo (24 skills)

saas packs v1.7.0
View Plugin

Installation

This skill is included in the klaviyo-pack plugin:

/plugin install klaviyo-pack@claude-code-plugins-plus

Click to copy

Instructions

Klaviyo Enterprise RBAC

Overview

Enterprise access control for Klaviyo: API key scoping with granular read/write permissions, OAuth app authorization flows, and application-level RBAC built on top of Klaviyo's scope system. Klaviyo has no built-in roles, so you compose least-privilege access from scoped keys plus an application permission layer.

Prerequisites

  • Klaviyo account with API key management access
  • Understanding of OAuth 2.0 (for OAuth apps)
  • Application requiring per-user or per-role Klaviyo access

Klaviyo Access Control Model

Klaviyo uses scoped API keys and OAuth for access control. There are no built-in "roles" in Klaviyo's API -- you implement RBAC by creating multiple API keys with different scopes.

API Key Scopes

Scope Read Write What It Controls
accounts Account info N/A Organization name, timezone
campaigns List campaigns Create/send campaigns Email, SMS, push campaigns
catalogs Browse items CRUD catalog items Product catalog management
coupons List coupons Create coupons Coupon/discount codes
data-privacy N/A Delete profiles GDPR/CCPA deletion requests
events Query events Track events Server-side event tracking
flows List flows Create/update flows Flow automation
images List images Upload images Email template images
lists List lists CRUD lists/members List management
metrics Query metrics N/A Metric aggregations
profiles Read profiles Create/update profiles Profile management
segments Read segments N/A Segment queries
tags Read tags CRUD tags Resource tagging
templates Read templates Create/update templates Email templates
webhooks List webhooks CRUD webhooks Webhook subscriptions

Instructions

The full, copy-ready code for every step lives in

the implementation walkthrough. At a high level

the workflow is five steps:

  1. Create scoped API keys — one key per service/role in the Klaviyo

dashboard (Settings > API Keys), each granted only the scopes it needs.

A profile-sync service gets profiles: + lists:; a reporting dashboard

gets *:read only; the admin key gets everything and is used sparingly.

  1. Model application-level RBAC — map each app role (admin, marketer,

developer, viewer, service) to a permission set and to its scoped key, so the

app enforces intent and the key enforces the hard boundary.

  1. Add permission middleware — reject requests whose role lacks the required

permission before the handler runs (401 for no role, 403 for wrong role).

  1. Wire the OAuth app flow — for third-party/marketplace integrations,

request only the scopes the app uses, then exchange the code for tokens.

  1. Record an audit trail — log every access with role/action/resource and

alert the security team on destructive actions like profile deletion.

The essential skeleton — a least-privilege key plus the permission check — looks

like this:


// One scoped key per service — reporting is read-only
const reportingSession = new ApiKeySession(process.env.KLAVIYO_KEY_REPORTING!);

// App-level guard: refuse before the handler runs
app.post('/api/klaviyo/campaigns/send',
  requireKlaviyoPermission('canSendCampaigns'),
  campaignSendHandler
);

See the implementation walkthrough for the role

permission matrix, getSessionForRole, the middleware, the OAuth exchange, the

audit logger, and the full environment variable layout in

the implementation walkthrough.

Output

Applying this skill produces:

  • Multiple scoped API keys in Klaviyo, one per service/role, each holding

only the scopes that service needs (defence in depth beyond app-level checks).

  • An RBAC module (src/klaviyo/rbac.ts) exporting checkPermission and

getSessionForRole, mapping the five app roles to permissions and keys.

  • Permission middleware (src/middleware/klaviyo-auth.ts) that returns 401

when no role is assigned and 403 when a role lacks the requested permission.

  • An OAuth flow for marketplace apps requesting minimized scopes.
  • An audit log (src/klaviyo/audit.ts) that records access and alerts on

destructive actions.

A blocked request returns a structured 403, e.g.:


{ "error": "Forbidden", "message": "Role 'marketer' does not have permission: canDeleteProfiles" }

Examples

Grounded, end-to-end scenarios — least-privilege keys, route gating by

permission, resolving a session from a role, OAuth scope minimization, and

alerting on a destructive action — are collected in

the examples reference.

Quick illustration — a marketer is allowed to send campaigns but blocked from

deleting profiles, purely from the role permission set:


// canSendCampaigns: true  -> allowed
app.post('/api/klaviyo/campaigns/send', requireKlaviyoPermission('canSendCampaigns'), campaignSendHandler);

// canDeleteProfiles: false -> 403 Forbidden
app.delete('/api/klaviyo/profiles/:id', requireKlaviyoPermission('canDeleteProfiles'), profileDeleteHandler);

Error Handling

Error Status Cause Solution
permission_denied 403 API key missing required scope Create new key with correct scopes
OAuth code expired 400 User took too long to authorize Retry authorization flow
Token refresh failed 401 Refresh token revoked Re-authorize the app
Role not assigned 401 User missing klaviyoRole Assign role in your user management

Resources

Ready to use klaviyo-pack?