Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure Langfuse enterprise organization management and access control. Use when implementing team access controls, configuring organization settings, or setting up role-based permissions for Langfuse projects. Trigger with phrases like "langfuse RBAC", "langfuse teams", "langfuse organization", "langfuse access control", "langfuse permissions".
.claude/skills/jeremylongshore-langfuse-enterprise-rbac/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -4% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 21% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 34% | 0% |
Configure enterprise access control for Langfuse: built-in roles and permissions, scoped API keys per service, SSO integration, project-level isolation, and audit logging for compliance.
Langfuse provides these roles at the project level:
| Role | View Traces | Create Traces | Manage Prompts | Manage Members | Manage Billing | |------|------------|---------------|----------------|----------------|---------------| | Owner | Yes | Yes | Yes | Yes | Yes | | Admin | Yes | Yes | Yes | Yes | No | | Member | Yes | Yes | Yes | No | No | | Viewer | Yes | No | No | No | No |
Organization: Acme Corp
├── Project: production-chatbot
│ ├── Owner: engineering-lead@acme.com
│ ├── Admin: senior-dev@acme.com
│ ├── Member: developer@acme.com
│ └── API Key: sk-lf-prod-chatbot-...
│
├── Project: staging-chatbot
│ ├── Admin: senior-dev@acme.com
│ ├── Member: developer@acme.com
│ └── API Key: sk-lf-staging-chatbot-...
│
└── Project: analytics-readonly
├── Admin: data-lead@acme.com
├── Viewer: analyst@acme.com
└── API Key: sk-lf-analytics-...Best practice: Separate projects for production, staging, and analytics. Never share API keys across environments.
Create API keys with specific purposes and rotate regularly:
typescript// In Langfuse UI: Settings > API Keys > Create // Each key pair (public + secret) is scoped to one project // Service-specific keys // Backend API: pk-lf-prod-api-... / sk-lf-prod-api-... // CI/CD pipeline: pk-lf-ci-... / sk-lf-ci-... // Analytics: pk-lf-analytics-... / sk-lf-analytics-... // Validate key scope at startup function validateApiKeyScope(expectedProject: string) { const pk = process.env.LANGFUSE_PUBLIC_KEY || ""; if (!pk.includes(expectedProject)) { console.warn( `WARNING: API key may not match expected project: ${expectedProject}` ); } } // Key rotation script async function rotateApiKeys() { // 1. Create new key pair in Langfuse UI // 2. Deploy new keys to secret manager // 3. Wait for all instances to pick up new keys // 4. Revoke old key pair in Langfuse UI console.log("Key rotation checklist:"); console.log("1. [ ] New key pair created in Langfuse"); console.log("2. [ ] New keys deployed to secret manager"); console.log("3. [ ] All services restarted with new keys"); console.log("4. [ ] Old key pair revoked in Langfuse"); console.log("5. [ ] Verified traces flowing with new keys"); }
yaml# docker-compose.yml -- enterprise hardening services: langfuse: image: langfuse/langfuse:latest environment: # Disable public registration - AUTH_DISABLE_SIGNUP=true # SSO enforcement for your domain - AUTH_DOMAINS_WITH_SSO_ENFORCEMENT=acme.com # Default role for new project members - LANGFUSE_DEFAULT_PROJECT_ROLE=VIEWER # Encrypt data at rest - ENCRYPTION_KEY=${ENCRYPTION_KEY} # Session security - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
SAML Setup (Okta, Azure AD, OneLogin):
https://langfuse.your-domain.com/api/auth/callback/samlhttps://langfuse.your-domain.comyaml# Self-hosted SSO configuration services: langfuse: environment: - AUTH_CUSTOM_CLIENT_ID=${SAML_CLIENT_ID} - AUTH_CUSTOM_CLIENT_SECRET=${SAML_CLIENT_SECRET} - AUTH_CUSTOM_ISSUER=https://your-idp.com/saml - AUTH_DOMAINS_WITH_SSO_ENFORCEMENT=acme.com
Track access and permission changes for compliance:
typescript// Application-level audit logging for Langfuse operations import { LangfuseClient } from "@langfuse/client"; interface AuditEvent { timestamp: string; actor: string; action: string; resource: string; details: Record<string, any>; } const auditLog: AuditEvent[] = []; function logAuditEvent(event: Omit<AuditEvent, "timestamp">) { const entry: AuditEvent = { ...event, timestamp: new Date().toISOString(), }; auditLog.push(entry); console.log(`[AUDIT] ${entry.action}: ${entry.resource} by ${entry.actor}`); // In production: send to your SIEM or audit log service // await sendToSIEM(entry); } // Audit Langfuse API key usage function auditedLangfuseClient(actor: string): LangfuseClient { const client = new LangfuseClient(); // Log score creation const originalScoreCreate = client.score.create.bind(client.score); client.score.create = async (params) => { logAuditEvent({ actor, action: "score.create", resource: `trace:${params.traceId}`, details: { scoreName: params.name }, }); return originalScoreCreate(params); }; return client; }
| Category | Requirement | Implementation | |----------|------------|----------------| | Authentication | SSO enforced for org domain | AUTH_DOMAINS_WITH_SSO_ENFORCEMENT | | Registration | Public signup disabled | AUTH_DISABLE_SIGNUP=true | | Default role | Least privilege | LANGFUSE_DEFAULT_PROJECT_ROLE=VIEWER | | API keys | Per-service, per-environment | Separate keys in secret manager | | Key rotation | Quarterly or on compromise | Documented rotation procedure | | Data encryption | At-rest encryption | ENCRYPTION_KEY configured | | Audit trail | All access logged | Application-level audit logging |
| Issue | Cause | Solution | |-------|-------|----------| | Permission denied | Insufficient role | Request role upgrade from project owner | | SSO login fails | Wrong callback URL | Verify SAML callback URL matches | | API key rejected | Wrong project or revoked | Create new key pair for correct project | | New user gets no access | Not added to project | Admin must invite to specific project |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 22,618 | 12,841 | -43% | 1 | 1 | 0% | 3,594 | 3,450 | -4% | 0 | 0 | — |
case-02 | fail→pass | 24,482 | 25,109 | +3% | 1 | 1 | 0% | 3,931 | 5,946 | +51% | 0 | 0 | — |
case-03 | fail→fail | 24,468 | 20,997 | -14% | 1 | 1 | 0% | 3,923 | 5,193 | +32% | 0 | 0 | — |
case-04 | fail→pass | 16,825 | 11,408 | -32% | 1 | 1 | 0% | 2,366 | 2,983 | +26% | 0 | 0 | — |
case-05 | fail→pass | 18,420 | 11,191 | -39% | 1 | 1 | 0% | 2,434 | 2,955 | +21% | 0 | 0 | — |
case-06 | pass→pass | 12,097 | 8,101 | -33% | 1 | 1 | 0% | 1,245 | 2,363 | +90% | 0 | 0 | — |
case-07 | pass→pass | 10,438 | 8,673 | -17% | 1 | 1 | 0% | 929 | 2,517 | +171% | 0 | 0 | — |
case-08 | pass→pass | 11,627 | 10,046 | -14% | 1 | 1 | 0% | 891 | 2,476 | +178% | 0 | 0 | — |
case-09 | pass→pass | 15,000 | 10,318 | -31% | 1 | 1 | 0% | 1,799 | 2,518 | +40% | 0 | 0 | — |
case-10 | pass→pass | 8,969 | 10,715 | +19% | 1 | 1 | 0% | 1,582 | 2,835 | +79% | 0 | 0 | — |
case-11 | pass→pass | 20,954 | 16,753 | -20% | 1 | 1 | 0% | 2,203 | 4,212 | +91% | 0 | 0 | — |
case-12 | pass→pass | 14,997 | 10,867 | -28% | 1 | 1 | 0% | 1,305 | 2,620 | +101% | 0 | 0 | — |
case-13 | pass→pass | 23,075 | 25,516 | +11% | 1 | 1 | 0% | 3,336 | 5,076 | +52% | 0 | 0 | — |
case-14 | fail→pass | 30,393 | 4,111 | -86% | 1 | 1 | 0% | 1,807 | 2,424 | +34% | 0 | 0 | — |
case-15 | pass→pass | 12,434 | 7,846 | -37% | 1 | 1 | 0% | 1,783 | 2,884 | +62% | 0 | 0 | — |
case-16 | pass→pass | 17,104 | 6,125 | -64% | 1 | 1 | 0% | 1,664 | 2,686 | +61% | 0 | 0 | — |
case-17 | pass→pass | 10,141 | 14,028 | +38% | 1 | 1 | 0% | 1,765 | 3,262 | +85% | 0 | 0 | — |
case-18 | pass→pass | 5,212 | 4,016 | -23% | 1 | 1 | 0% | 911 | 2,354 | +158% | 0 | 0 | — |
case-19 | pass→pass | 3,116 | 9,158 | +194% | 1 | 1 | 0% | 475 | 2,306 | +385% | 0 | 0 | — |
case-20 | pass→pass | 9,668 | 14,569 | +51% | 1 | 1 | 0% | 907 | 3,125 | +245% | 0 | 0 | — |
case-21 | pass→pass | 17,882 | 10,456 | -42% | 1 | 1 | 0% | 2,440 | 3,875 | +59% | 0 | 0 | — |
case-22 | pass→pass | 24,049 | 18,796 | -22% | 1 | 1 | 0% | 3,737 | 5,599 | +50% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.