ID

ideogram-enterprise-rbac

Enforces RBAC and multi-tenancy for Ideogram enterprise users. Provides templates for managing multiple teams and budgets.

Install

mkdir -p .claude/skills/ideogram-enterprise-rbac && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7087" && unzip -o skill.zip -d .claude/skills/ideogram-enterprise-rbac && rm skill.zip

Installs to .claude/skills/ideogram-enterprise-rbac

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Implement team-based access control and credit management for Ideogram.
71 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Implement team-based API key isolation
  • Enforce daily budget limits per team
  • Apply content filtering policies
  • Track usage and generate reports
  • Manage style and model permissions

How it works

It implements an application-layer proxy that validates team-specific budgets, content policies, and model permissions before forwarding requests to the Ideogram API.

Inputs & outputs

You give it
Team ID and generation prompt
You get back
Generated image URL

When to use ideogram-enterprise-rbac

  • Implement per-team API key management
  • Enforce budget limits per team
  • Implement content filtering for AI generation
  • Manage enterprise team access patterns

About this skill

Ideogram Enterprise RBAC

Overview

Implement team-based access control for Ideogram's API. Since Ideogram uses a single API key per account with no built-in roles or scopes, enterprise access control must be implemented at the application layer: separate API keys per team, proxy-based content filtering, per-team budget limits, and usage tracking.

Architecture

┌──────────────────────────────────────────┐
│  Application Proxy Layer                  │
│  ┌──────────┐  ┌──────────┐  ┌────────┐ │
│  │ Marketing│  │ Product  │  │ Social │ │
│  │ API Key  │  │ API Key  │  │API Key │ │
│  └────┬─────┘  └────┬─────┘  └───┬────┘ │
│       └──────────────┼────────────┘      │
│                      ▼                   │
│  ┌────────────────────────────────────┐  │
│  │ Content Filter + Budget Enforcer   │  │
│  └──────────────────┬─────────────────┘  │
└─────────────────────┼────────────────────┘
                      ▼
          Ideogram API (api.ideogram.ai)

Instructions

Step 1: Team Configuration

interface TeamConfig {
  name: string;
  apiKey: string;             // Separate Ideogram API key per team
  dailyBudgetUSD: number;
  allowedStyles: string[];
  allowedModels: string[];
  maxConcurrency: number;
  contentPolicy: "strict" | "moderate" | "permissive";
}

const TEAM_CONFIGS: Record<string, TeamConfig> = {
  marketing: {
    name: "Marketing",
    apiKey: process.env.IDEOGRAM_KEY_MARKETING!,
    dailyBudgetUSD: 20,
    allowedStyles: ["DESIGN", "REALISTIC"],
    allowedModels: ["V_2", "V_2_TURBO"],
    maxConcurrency: 5,
    contentPolicy: "strict",
  },
  product: {
    name: "Product Design",
    apiKey: process.env.IDEOGRAM_KEY_PRODUCT!,
    dailyBudgetUSD: 50,
    allowedStyles: ["DESIGN", "REALISTIC", "RENDER_3D", "GENERAL"],
    allowedModels: ["V_2", "V_2_TURBO"],
    maxConcurrency: 8,
    contentPolicy: "moderate",
  },
  social: {
    name: "Social Media",
    apiKey: process.env.IDEOGRAM_KEY_SOCIAL!,
    dailyBudgetUSD: 10,
    allowedStyles: ["DESIGN", "ANIME", "GENERAL"],
    allowedModels: ["V_2_TURBO"],
    maxConcurrency: 3,
    contentPolicy: "strict",
  },
};

Step 2: Content Policy Enforcement

interface ContentCheck {
  allowed: boolean;
  reason?: string;
}

const BLOCKED_TERMS: Record<string, RegExp[]> = {
  strict: [
    /\b(competitor|trademark|brand)\b/i,
    /\b(violent|weapon|blood|gore)\b/i,
    /\b(nsfw|nude|explicit)\b/i,
  ],
  moderate: [
    /\b(nsfw|nude|explicit)\b/i,
  ],
  permissive: [],
};

function checkContentPolicy(prompt: string, policy: "strict" | "moderate" | "permissive"): ContentCheck {
  const patterns = BLOCKED_TERMS[policy] ?? [];
  for (const pattern of patterns) {
    if (pattern.test(prompt)) {
      return { allowed: false, reason: `Blocked by ${policy} policy: ${pattern.source}` };
    }
  }
  if (prompt.length > 10000) {
    return { allowed: false, reason: "Prompt exceeds 10,000 character limit" };
  }
  return { allowed: true };
}

Step 3: Budget Enforcer

const dailySpend = new Map<string, number>();

function trackSpend(teamId: string, model: string, numImages: number = 1) {
  const costPerImage: Record<string, number> = {
    V_2_TURBO: 0.05, V_2: 0.08, V_2A_TURBO: 0.025, V_2A: 0.04,
  };

  const cost = (costPerImage[model] ?? 0.08) * numImages;
  const current = dailySpend.get(teamId) ?? 0;
  dailySpend.set(teamId, current + cost);

  return current + cost;
}

function checkBudget(teamId: string): { allowed: boolean; remaining: number } {
  const config = TEAM_CONFIGS[teamId];
  if (!config) return { allowed: false, remaining: 0 };

  const spent = dailySpend.get(teamId) ?? 0;
  const remaining = config.dailyBudgetUSD - spent;

  return { allowed: remaining > 0, remaining };
}

// Reset daily at midnight
setInterval(() => {
  dailySpend.clear();
  console.log("Daily budget counters reset");
}, 86400000);

Step 4: Team-Scoped Proxy

async function teamGenerate(
  teamId: string,
  prompt: string,
  options: { style_type?: string; model?: string; aspect_ratio?: string } = {}
) {
  const config = TEAM_CONFIGS[teamId];
  if (!config) throw new Error(`Unknown team: ${teamId}`);

  // Check content policy
  const contentCheck = checkContentPolicy(prompt, config.contentPolicy);
  if (!contentCheck.allowed) {
    throw new Error(`Content blocked: ${contentCheck.reason}`);
  }

  // Check style permission
  const style = options.style_type ?? "AUTO";
  if (style !== "AUTO" && !config.allowedStyles.includes(style)) {
    throw new Error(`Style ${style} not allowed for team ${config.name}`);
  }

  // Check model permission
  const model = options.model ?? config.allowedModels[0];
  if (!config.allowedModels.includes(model)) {
    throw new Error(`Model ${model} not allowed for team ${config.name}`);
  }

  // Check budget
  const budget = checkBudget(teamId);
  if (!budget.allowed) {
    throw new Error(`Daily budget exceeded for team ${config.name}. Remaining: $${budget.remaining.toFixed(2)}`);
  }

  // Generate using team's API key
  const response = await fetch("https://api.ideogram.ai/generate", {
    method: "POST",
    headers: {
      "Api-Key": config.apiKey,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      image_request: {
        prompt,
        model,
        style_type: style,
        aspect_ratio: options.aspect_ratio ?? "ASPECT_1_1",
        magic_prompt_option: "AUTO",
      },
    }),
  });

  if (!response.ok) throw new Error(`Ideogram API error: ${response.status}`);

  // Track spending
  trackSpend(teamId, model);

  return response.json();
}

Step 5: Usage Dashboard Data

function teamUsageReport() {
  const report = [];
  for (const [teamId, config] of Object.entries(TEAM_CONFIGS)) {
    const spent = dailySpend.get(teamId) ?? 0;
    report.push({
      team: config.name,
      dailyBudget: config.dailyBudgetUSD,
      spent: spent.toFixed(2),
      remaining: (config.dailyBudgetUSD - spent).toFixed(2),
      utilization: `${((spent / config.dailyBudgetUSD) * 100).toFixed(0)}%`,
    });
  }
  console.table(report);
  return report;
}

Step 6: Key Rotation Schedule

Quarterly key rotation process:
1. Create new API key in Ideogram dashboard for each team
2. Update secrets in your secret manager
3. Deploy with new keys to staging, verify
4. Deploy to production
5. Monitor for 48 hours
6. Delete old keys from Ideogram dashboard

Error Handling

IssueCauseSolution
Budget exceededDaily limit hitWait for reset or increase limit
Style not allowedTeam policy restrictionUse an allowed style type
Content blockedPrompt failed policyRephrase to comply with team policy
Key not setMissing env variableCheck team-specific key config

Output

  • Per-team API key isolation
  • Content policy enforcement (strict/moderate/permissive)
  • Daily budget tracking with automatic enforcement
  • Team-scoped generation proxy
  • Usage dashboard data for reporting

Resources

Next Steps

For migration strategies, see ideogram-migration-deep-dive.

When not to use it

  • Using a single API key for all enterprise teams
  • Bypassing content policy checks for permissive teams
  • Ignoring daily budget resets

Prerequisites

Ideogram API keys for each teamSecret manager for key storage

Limitations

  • Ideogram API uses a single API key per account
  • Prompt exceeds 10,000 character limit
  • Daily budget counters reset at midnight

How it compares

This workflow provides multi-tenant controls and budget enforcement that are not natively available in the Ideogram API.

Compared to similar skills

ideogram-enterprise-rbac side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
ideogram-enterprise-rbac (this skill)127dReviewIntermediate
fix-dependabot-alerts186moReviewIntermediate
security-audit36moReviewIntermediate
security-best-practices76moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

fix-dependabot-alerts

microsoft

Fix Dependabot security alerts by updating vulnerable npm dependencies. Use when the user mentions "dependabot", "security alerts", "vulnerability", "CVE", or wants to update packages with security issues.

1872

security-audit

ruvnet

Comprehensive security scanning and vulnerability detection. Includes input validation, path traversal prevention, CVE detection, and secure coding pattern enforcement. Use when: authentication implementation, authorization logic, payment processing, user data handling, API endpoint creation, file upload handling, database queries, external API integration. Skip when: read-only operations on public data, internal development tooling, static documentation, styling changes.

337

security-best-practices

openai

Perform language and framework specific security best-practice reviews and suggest improvements. Trigger only when the user explicitly requests security best practices guidance, a security review/report, or secure-by-default coding help. Trigger only for supported languages (python, javascript/typescript, go). Do not trigger for general code review, debugging, or non-security tasks.

732

epic-permissions

epicweb-dev

Guide on RBAC system and permissions for Epic Stack

317

epic-security

epicweb-dev

Guide on security practices including CSP, rate limiting, and session security for Epic Stack

611

damage-control

disler

Install, configure, and manage the Claude Code Damage Control security hooks system. Use when user mentions damage control, security hooks, protected paths, blocked commands, install security, or modify protection settings.

27

Search skills

Search the agent skills registry