Skip to content
Back to skills

Gamma Enterprise Rbac

ASecurity

'Implement enterprise role-based access control for Gamma integrations.

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 21, 2026
ai-agentstypescriptgoexpressapidatabase

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus --skill gamma-enterprise-rbac --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gamma Enterprise Rbac?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gamma Enterprise Rbac
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-gamma-enterprise-rbac-e3b25853/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-gamma-enterprise-rbac-e3b25853)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gamma-enterprise-rbac
description: 'Implement enterprise role-based access control for Gamma integrations.

  Use when configuring team permissions, multi-tenant access,

  or enterprise authorization patterns.

  Trigger with phrases like "gamma RBAC", "gamma permissions",

  "gamma access control", "gamma enterprise", "gamma roles".

  '
allowed-tools: Read, Write, Edit
version: 1.13.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
tags:
- saas
- gamma
- authentication
- rbac
compatibility: Designed for Claude Code
---
# Gamma Enterprise RBAC

## Output

Maintain an access receipt with role, approved operation class, policy version, review date, approver, and revocation result. Do not include credentials or presentation content.

## Examples

Grant a temporary test role view access to a fictional staging deck, attempt an unauthorized publish, confirm denial, then revoke the role and record only the opaque test outcome.

## Overview

Implement role-based access control for Gamma API integrations. Gamma's API uses a single API key per workspace -- granular permissions must be implemented in your application layer. The Teams and Business plans support workspace-level collaboration with shared themes and folders.

## Prerequisites

- Gamma Teams or Business subscription
- Application database for user/role storage
- Completed `gamma-install-auth` setup

## Gamma Access Model

```
Gamma Workspace (1 API key)
├── Themes (shared across workspace)
├── Folders (shared across workspace)
└── Generations (tied to API key, not individual users)

Your Application Layer (you implement this):
├── Organization
│   ├── Admin (manage API key, configure themes)
│   ├── Editor (generate presentations, use templates)
│   ├── Viewer (view generated presentations, download exports)
│   └── Guest (no generation access)
```

**Key point:** Gamma's API does not have per-user authentication. All API calls use the workspace API key. You must enforce per-user permissions in your application.

## Instructions

### Step 1: Define Role Hierarchy

```typescript
// src/auth/gamma-roles.ts
type GammaRole = "guest" | "viewer" | "editor" | "admin";

const PERMISSIONS: Record<GammaRole, string[]> = {
  guest: [],
  viewer: ["generation:view", "export:download"],
  editor: ["generation:view", "generation:create", "export:download", "template:use"],
  admin: [
    "generation:view", "generation:create", "export:download",
    "template:use", "template:manage", "theme:manage",
    "settings:manage", "member:manage",
  ],
};

function hasPermission(role: GammaRole, permission: string): boolean {
  return PERMISSIONS[role]?.includes(permission) ?? false;
}
```

### Step 2: Authorization Middleware

```typescript
// src/middleware/gamma-auth.ts
import { Request, Response, NextFunction } from "express";

function requireGammaPermission(permission: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const user = req.user; // Set by your auth middleware
    if (!user) return res.status(401).json({ error: "Unauthorized" });

    if (!hasPermission(user.gammaRole, permission)) {
      return res.status(403).json({
        error: "Forbidden",
        required: permission,
        userRole: user.gammaRole,
      });
    }
    next();
  };
}

// Usage
app.post("/api/presentations",
  requireGammaPermission("generation:create"),
  async (req, res) => {
    const gamma = createGammaClient({ apiKey: process.env.GAMMA_API_KEY! });
    const { generationId } = await gamma.generate(req.body);
    // Track ownership in your database
    await db.generations.create({
      data: { generationId, userId: req.user.id, teamId: req.user.teamId },
    });
    res.json({ generationId });
  }
);

app.get("/api/presentations/:id",
  requireGammaPermission("generation:view"),
  async (req, res) => {
    // Only return if user owns it or is in the same team
    const gen = await db.generations.findFirst({
      where: { generationId: req.params.id, teamId: req.user.teamId },
    });
    if (!gen) return res.status(404).json({ error: "Not found" });
    res.json(gen);
  }
);
```

### Step 3: Multi-Tenant Workspace Isolation

```typescript
// src/tenant/gamma-tenant.ts
// Each tenant can have their own Gamma workspace (API key)
// or share a workspace with resource-level isolation

interface Tenant {
  id: string;
  name: string;
  gammaApiKey: string; // Encrypted in database
}

class TenantGammaService {
  private clients = new Map<string, ReturnType<typeof createGammaClient>>();

  getClient(tenant: Tenant) {
    if (!this.clients.has(tenant.id)) {
      this.clients.set(
        tenant.id,
        createGammaClient({ apiKey: tenant.gammaApiKey })
      );
    }
    return this.clients.get(tenant.id)!;
  }

  async generate(tenant: Tenant, userId: string, content: string, options: any = {}) {
    const gamma = this.getClient(tenant);
    const { generationId } = await gamma.generate({
      content,
      ...options,
    });

    // Track with tenant isolation
    await db.generations.create({
      data: { generationId, tenantId: tenant.id, userId },
    });

    return { generationId };
  }
}
```

### Step 4: Credit Quota Per User/Team

```typescript
// src/quota/gamma-quotas.ts
interface Quota {
  maxGenerationsPerDay: number;
  maxCreditsPerMonth: number;
}

const ROLE_QUOTAS: Record<GammaRole, Quota> = {
  guest: { maxGenerationsPerDay: 0, maxCreditsPerMonth: 0 },
  viewer: { maxGenerationsPerDay: 0, maxCreditsPerMonth: 0 },
  editor: { maxGenerationsPerDay: 10, maxCreditsPerMonth: 500 },
  admin: { maxGenerationsPerDay: 50, maxCreditsPerMonth: 5000 },
};

async function checkQuota(userId: string, role: GammaRole): Promise<boolean> {
  const quota = ROLE_QUOTAS[role];
  if (quota.maxGenerationsPerDay === 0) return false;

  const todayCount = await db.generations.count({
    where: {
      userId,
      createdAt: { gte: new Date(new Date().toDateString()) },
    },
  });

  return todayCount < quota.maxGenerationsPerDay;
}
```

### Step 5: Audit Logging

```typescript
// src/audit/gamma-audit.ts
async function auditGammaAction(entry: {
  userId: string;
  teamId: string;
  action: string;
  resourceId?: string;
  metadata?: Record<string, any>;
}) {
  await db.auditLog.create({
    data: {
      ...entry,
      timestamp: new Date(),
      service: "gamma",
    },
  });
}

// Usage
await auditGammaAction({
  userId: req.user.id,
  teamId: req.user.teamId,
  action: "generation.create",
  resourceId: generationId,
  metadata: { outputFormat: "presentation", credits: result.creditsUsed },
});
```

## Permission Matrix

| Permission | Guest | Viewer | Editor | Admin |
|------------|-------|--------|--------|-------|
| View presentations | No | Yes | Yes | Yes |
| Download exports | No | Yes | Yes | Yes |
| Create generations | No | No | Yes | Yes |
| Use templates | No | No | Yes | Yes |
| Manage themes/folders | No | No | No | Yes |
| Manage team members | No | No | No | Yes |
| Configure API key | No | No | No | Yes |

## Error Handling

| Issue | Cause | Solution |
|-------|-------|----------|
| 403 Forbidden | Insufficient role | Check user's `gammaRole` assignment |
| Cross-tenant access | Wrong API key | Verify tenant isolation in `getClient()` |
| Quota exceeded | Too many generations | Show remaining quota, wait for reset |
| Privilege escalation | Missing role check | Verify middleware on all routes |

## Resources

- [Gamma Teams](https://gamma.app/pricing)
- [RBAC Best Practices](https://csrc.nist.gov/projects/role-based-access-control)
- [OWASP Access Control](https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html)

## Next Steps

Proceed to `gamma-migration-deep-dive` for platform migration.

Files in this skill

  • SKILL.md7.6 KB
  • references/implementation.md5.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.