perplexity-enterprise-rbac
Implements API key scoping and organizational access control for Perplexity integrations.
Install
mkdir -p .claude/skills/perplexity-enterprise-rbac && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/9301" && unzip -o skill.zip -d .claude/skills/perplexity-enterprise-rbac && rm skill.zipInstalls to .claude/skills/perplexity-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.
Configure Perplexity API key scoping, per-team model access, cost controls,Key capabilities
- →Manage Perplexity API keys for individual teams or environments.
- →Enforce model access policies through a gateway.
- →Set budget caps for API keys via the Perplexity dashboard.
- →Apply domain restrictions to searches for compliance.
- →Track API usage and allocate costs per team.
- →Rotate API keys on a scheduled basis.
How it works
This skill uses separate API keys for each team and a custom gateway to enforce policies such as allowed models, token limits, and domain restrictions. It also tracks usage and costs per team.
Inputs & outputs
When to use perplexity-enterprise-rbac
- →Setting up enterprise API access
- →Configuring team-based API keys
- →Applying cost controls
- →Implementing model access policies
About this skill
Perplexity Enterprise RBAC
Overview
Control access to Perplexity Sonar API at the organizational level. Perplexity does not have built-in RBAC -- you implement access control through: separate API keys per team/environment, a gateway that enforces model and budget policies, and domain restrictions for compliance.
Access Control Strategy
| Layer | Mechanism | Perplexity Support |
|---|---|---|
| Authentication | API key per team | Yes (multiple keys) |
| Model restriction | Gateway enforcement | Build yourself |
| Budget cap | Per-key monthly limit | Via dashboard |
| Domain restriction | search_domain_filter | Yes (per-request) |
| Rate limiting | Gateway + key limits | Yes (per-key RPM) |
Prerequisites
- Perplexity API account with admin access
- Separate API keys per team/environment
- Gateway or middleware for policy enforcement
Instructions
Step 1: Create Per-Team API Keys
Generate separate keys at perplexity.ai/settings/api:
Key: pplx-support-bot-prod → Budget: $200/mo, sonar only
Key: pplx-research-team → Budget: $1000/mo, sonar + sonar-pro
Key: pplx-data-team → Budget: $500/mo, sonar only
Key: pplx-executive-reports → Budget: $300/mo, sonar-pro
Step 2: Gateway with Policy Enforcement
// perplexity-gateway.ts
import OpenAI from "openai";
interface TeamPolicy {
apiKey: string;
allowedModels: string[];
maxTokensPerRequest: number;
maxRequestsPerMinute: number;
requiredDomainFilter?: string[]; // Force search to specific domains
blockedDomainFilter?: string[]; // Block specific domains
}
const TEAM_POLICIES: Record<string, TeamPolicy> = {
support: {
apiKey: process.env.PPLX_KEY_SUPPORT!,
allowedModels: ["sonar"],
maxTokensPerRequest: 512,
maxRequestsPerMinute: 30,
},
research: {
apiKey: process.env.PPLX_KEY_RESEARCH!,
allowedModels: ["sonar", "sonar-pro", "sonar-reasoning-pro"],
maxTokensPerRequest: 4096,
maxRequestsPerMinute: 50,
},
compliance: {
apiKey: process.env.PPLX_KEY_COMPLIANCE!,
allowedModels: ["sonar", "sonar-pro"],
maxTokensPerRequest: 2048,
maxRequestsPerMinute: 20,
requiredDomainFilter: ["sec.gov", "edgar.sec.gov", "law.cornell.edu"],
},
marketing: {
apiKey: process.env.PPLX_KEY_MARKETING!,
allowedModels: ["sonar"],
maxTokensPerRequest: 1024,
maxRequestsPerMinute: 20,
blockedDomainFilter: ["-competitor1.com", "-competitor2.com"],
},
};
function enforcePolicy(
team: string,
requestedModel: string,
requestedTokens: number
): { client: OpenAI; model: string; maxTokens: number; domainFilter?: string[] } {
const policy = TEAM_POLICIES[team];
if (!policy) throw new Error(`Unknown team: ${team}`);
if (!policy.allowedModels.includes(requestedModel)) {
console.warn(`Team ${team} not allowed ${requestedModel}, using ${policy.allowedModels[0]}`);
}
const model = policy.allowedModels.includes(requestedModel)
? requestedModel
: policy.allowedModels[0];
const maxTokens = Math.min(requestedTokens, policy.maxTokensPerRequest);
return {
client: new OpenAI({ apiKey: policy.apiKey, baseURL: "https://api.perplexity.ai" }),
model,
maxTokens,
domainFilter: policy.requiredDomainFilter || policy.blockedDomainFilter,
};
}
Step 3: Enforced Search with Domain Restrictions
async function teamSearch(
team: string,
query: string,
requestedModel: string = "sonar"
) {
const { client, model, maxTokens, domainFilter } = enforcePolicy(
team, requestedModel, 2048
);
const response = await client.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
max_tokens: maxTokens,
...(domainFilter && { search_domain_filter: domainFilter }),
} as any);
return {
answer: response.choices[0].message.content,
citations: (response as any).citations || [],
model: response.model,
team,
tokens: response.usage?.total_tokens,
};
}
// Usage
const result = await teamSearch("compliance", "latest SEC filing for AAPL", "sonar-pro");
// -> Uses sonar-pro (allowed for compliance team)
// -> Searches only sec.gov, edgar.sec.gov, law.cornell.edu
const supportResult = await teamSearch("support", "How to reset password", "sonar-pro");
// -> Downgrades to sonar (support team only allowed sonar)
Step 4: Usage Tracking per Team
class TeamUsageTracker {
private usage: Map<string, Array<{ timestamp: number; tokens: number; model: string; cost: number }>> = new Map();
record(team: string, tokens: number, model: string) {
const entries = this.usage.get(team) || [];
const cost = model === "sonar-pro" ? tokens * 0.000009 : tokens * 0.000001;
entries.push({ timestamp: Date.now(), tokens, model, cost });
this.usage.set(team, entries);
}
getDailySummary(team: string) {
const today = new Date().toDateString();
const entries = (this.usage.get(team) || []).filter(
(e) => new Date(e.timestamp).toDateString() === today
);
return {
team,
queries: entries.length,
totalTokens: entries.reduce((s, e) => s + e.tokens, 0),
estimatedCost: entries.reduce((s, e) => s + e.cost, 0).toFixed(4),
modelBreakdown: {
sonar: entries.filter((e) => e.model === "sonar").length,
"sonar-pro": entries.filter((e) => e.model === "sonar-pro").length,
},
};
}
}
Step 5: Key Rotation Schedule
Rotate API keys every 90 days. Name keys with quarter (pplx-research-2026Q1) for tracking.
set -euo pipefail
# 1. Generate new key at perplexity.ai/settings/api
# 2. Deploy new key alongside old key (24-hour overlap)
# 3. Verify new key works
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $NEW_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"sonar","messages":[{"role":"user","content":"test"}],"max_tokens":5}' \
https://api.perplexity.ai/chat/completions
# 4. Remove old key from perplexity.ai/settings/api
Error Handling
| Issue | Cause | Solution |
|---|---|---|
401 for a team | Key expired or revoked | Regenerate key for that team |
| Model downgrade unexpected | Policy restricting access | Check team's allowedModels |
| Compliance citations from wrong domain | Domain filter not applied | Verify requiredDomainFilter in policy |
| Budget exceeded | Team over monthly cap | Alert team lead, increase cap or throttle |
Output
- Per-team API key management
- Gateway enforcing model and token policies
- Domain-restricted search for compliance teams
- Usage tracking and cost allocation per team
Resources
Next Steps
For migration planning, see perplexity-migration-deep-dive.
When not to use it
- →When Perplexity API access control is not needed at an organizational level.
- →When a gateway or middleware for policy enforcement is not available.
Prerequisites
Limitations
- →Perplexity does not have built-in role-based access control (RBAC).
- →Model restriction and policy enforcement require building a custom gateway.
- →Budget caps are per-key monthly limits set via the dashboard.
How it compares
This workflow implements granular access control and usage tracking for Perplexity API access, unlike direct API usage without such controls.
Compared to similar skills
perplexity-enterprise-rbac side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| perplexity-enterprise-rbac (this skill) | 0 | 27d | Caution | Advanced |
| api-security-best-practices | 15 | 6mo | Review | Intermediate |
| api-security-testing | 1 | 7mo | Review | Advanced |
| scanning-api-security | 2 | 27d | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
api-security-best-practices
davila7
Implement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities
api-security-testing
Ed1s0nZ
API安全测试的专业技能和方法论
scanning-api-security
jeremylongshore
Detect API security vulnerabilities including injection, broken auth, and data exposure. Use when scanning APIs for security vulnerabilities. Trigger with phrases like "scan API security", "check for vulnerabilities", or "audit API security".
openrouter-data-privacy
jeremylongshore
Implement data privacy controls for OpenRouter requests. Use when handling PII or meeting compliance requirements. Trigger with phrases like 'openrouter privacy', 'openrouter pii', 'openrouter gdpr', 'openrouter data protection'.
apollo-security-basics
jeremylongshore
Apply Apollo.io API security best practices. Use when securing Apollo integrations, managing API keys, or implementing secure data handling. Trigger with phrases like "apollo security", "secure apollo api", "apollo api key security", "apollo data protection".
webhook-security
dadbodgeoff
Implement secure webhook handling with signature verification, replay protection, and idempotency. Use when receiving webhooks from third-party services like Stripe, GitHub, Twilio, or building your own webhook system.