--- name: langfuse-enterprise-rbac description: '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". ' allowed-tools: Read, Write, Edit version: 1.0.0 license: MIT author: Jeremy Longshore tags: - saas - langfuse - rbac compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw --- # Langfuse Enterprise RBAC ## Overview 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. ## Prerequisites - Langfuse Cloud (Team/Enterprise plan) or self-hosted instance - Organization admin access - SSO provider (optional, for SAML/OIDC integration) ## Langfuse Built-In Roles 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 | ## Instructions ### Step 1: Organization and Project Structure ``` 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. ### Step 2: Scoped API Keys 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"); } ``` ### Step 3: Self-Hosted Access Control ```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} ``` ### Step 4: SSO Integration **SAML Setup (Okta, Azure AD, OneLogin):** 1. In your IdP, create a new SAML application for Langfuse 2. Configure the SSO callback URL: `https://langfuse.your-domain.com/api/auth/callback/saml` 3. Set the entity ID: `https://langfuse.your-domain.com` 4. Map IdP groups to Langfuse roles: ```yaml # 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 ``` ### Step 5: Audit Logging 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; } const auditLog: AuditEvent[] = []; function logAuditEvent(event: Omit) { 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; } ``` ## Access Control Checklist | 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 | ## Error Handling | 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 | ## Resources - [Langfuse Access Control](https://langfuse.com/docs/rbac) - [Self-Hosting Configuration](https://langfuse.com/self-hosting/configuration) - [Headless Initialization](https://langfuse.com/self-hosting/administration/headless-initialization)