agentsclimarketplace

Klaviyo enterprise rbac

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/klaviyo-pack/skills/klaviyo-enterprise-rbac

425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill klaviyo-enterprise-rbac

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

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".

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.8 KB, as published. Nobody here has run it

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

ScopeReadWriteWhat It Controls
accountsAccount infoN/AOrganization name, timezone
campaignsList campaignsCreate/send campaignsEmail, SMS, push campaigns
catalogsBrowse itemsCRUD catalog itemsProduct catalog management
couponsList couponsCreate couponsCoupon/discount codes
data-privacyN/ADelete profilesGDPR/CCPA deletion requests
eventsQuery eventsTrack eventsServer-side event tracking
flowsList flowsCreate/update flowsFlow automation
imagesList imagesUpload imagesEmail template images
listsList listsCRUD lists/membersList management
metricsQuery metricsN/AMetric aggregations
profilesRead profilesCreate/update profilesProfile management
segmentsRead segmentsN/ASegment queries
tagsRead tagsCRUD tagsResource tagging
templatesRead templatesCreate/update templatesEmail templates
webhooksList webhooksCRUD webhooksWebhook 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.
  2. 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.
  3. Add permission middleware — reject requests whose role lacks the required permission before the handler runs (401 for no role, 403 for wrong role).
  4. Wire the OAuth app flow — for third-party/marketplace integrations, request only the scopes the app uses, then exchange the code for tokens.
  5. 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

ErrorStatusCauseSolution
permission_denied403API key missing required scopeCreate new key with correct scopes
OAuth code expired400User took too long to authorizeRetry authorization flow
Token refresh failed401Refresh token revokedRe-authorize the app
Role not assigned401User missing klaviyoRoleAssign role in your user management

Resources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.