Learn how to configure fine-grained access control for your chat applications using Pika's secure-by-default system that combines user types, roles, and entity-based restrictions.
What You'll Accomplish
Section titled “What You'll Accomplish”By the end of this guide, you will:
- Understand Pika's access control precedence rules
- Configure user type-based access (internal vs external)
- Implement role-based access control
- Set up entity-based restrictions for multi-tenancy
- Use admin overrides for special cases
- Debug and troubleshoot access issues
Prerequisites
Section titled “Prerequisites”- A running Pika installation
- Custom authentication provider configured
- Basic understanding of your user types and organizational structure
- Users with appropriate
userTypeandrolesassigned
Understanding Access Control
Section titled “Understanding Access Control”Pika uses a hierarchical, secure-by-default access control system with multiple layers.
Core Principles
Section titled “Core Principles”- Secure by Default: Features without explicit access rules deny access to all users
- Hierarchical Precedence: Rules evaluated in order with higher precedence overriding lower
- Granular Control: Combine user types, roles, and entities for fine-tuned access
- Admin Override: Site admins can override any chat app configuration
User Types
Section titled “User Types”internal-user: Company employees, administrators, internal staffexternal-user: Customers, partners, external users- Default: Users without
userTypeare treated asexternal-user
User Roles
Section titled “User Roles”- Pika Roles:
pika:content-admin,pika:site-admin(framework-defined) - Custom Roles: Any string you define (e.g.,
'support-manager','sales-rep') - Users can have multiple roles assigned
Access Control Precedence
Section titled “Access Control Precedence”Understanding precedence is critical for debugging access issues.
Level 1: Chat App Enabled/Disabled
Section titled “Level 1: Chat App Enabled/Disabled”if (!chatApp.enabled) { // Disabled apps deny ALL access return DENY_ACCESS;}Level 2: Override Rules (If Present)
Section titled “Level 2: Override Rules (If Present)”When a ChatAppOverride exists, it takes complete precedence over base settings.
2a. Override Enabled/Disabled
Section titled “2a. Override Enabled/Disabled”if (override.enabled === false) { // Override can disable an enabled app return DENY_ACCESS;}2b. Exclusive User ID Control (Highest Override)
Section titled “2b. Exclusive User ID Control (Highest Override)”if (override.exclusiveUserIdAccessControl?.length > 0) { return override.exclusiveUserIdAccessControl.includes(user.userId) ? ALLOW_ACCESS : DENY_ACCESS;}Example: Beta testing with specific users
const betaOverride = { enabled: true, exclusiveUserIdAccessControl: ['user_123', 'user_456', 'user_789'] // ONLY these 3 users can access - all other rules ignored};2c. Exclusive Entity Access Control (Second Priority)
Section titled “2c. Exclusive Entity Access Control (Second Priority)”const userType = user.userType ?? 'external-user';const accessList = userType === 'internal-user' ? override.exclusiveInternalAccessControl : override.exclusiveExternalAccessControl;
if (accessList?.length > 0) { const userEntity = extractEntityFromCustomData(user.customData); return accessList.includes(userEntity) ? ALLOW_ACCESS : DENY_ACCESS;}Example: Multi-tenant access
const enterpriseOverride = { enabled: true, exclusiveExternalAccessControl: ['account_001', 'account_002'], exclusiveInternalAccessControl: ['customer_success', 'enterprise_support'] // External: Only specified accounts // Internal: Only specified departments};Level 3: General Access Rules
Section titled “Level 3: General Access Rules”If no exclusive rules apply, check userTypes, userRoles, and applyRulesAs.
function checkGeneralAccessRules(user, rules) { const { enabled, userTypes, userRoles, applyRulesAs = 'and' } = rules;
// Feature must be enabled if (!enabled) return false;
// SECURE BY DEFAULT: No rules = no access if (!userTypes && !userRoles) return false;
// Check user type match const userTypeMatches = userTypes ? userTypes.includes(user.userType ?? 'external-user') : true;
// Check user role match const userRoleMatches = userRoles ? (user.roles ?? []).some(role => userRoles.includes(role)) : true;
// Apply combination logic return applyRulesAs === 'and' ? userTypeMatches && userRoleMatches : userTypeMatches || userRoleMatches;}Step 1: Configure User Type Access
Section titled “Step 1: Configure User Type Access”Control access based on whether users are internal or external.
Internal Users Only
Section titled “Internal Users Only”const internalApp: ChatApp = { chatAppId: 'employee-portal', title: 'Employee Portal', enabled: true, userTypes: ['internal-user']};External Users Only
Section titled “External Users Only”const customerApp: ChatApp = { chatAppId: 'customer-support', title: 'Customer Support', enabled: true, userTypes: ['external-user']};Both User Types
Section titled “Both User Types”const sharedApp: ChatApp = { chatAppId: 'general-chat', title: 'General Chat', enabled: true, userTypes: ['internal-user', 'external-user']};Step 2: Add Role-Based Access
Section titled “Step 2: Add Role-Based Access”Restrict access to users with specific roles.
Admin Users Only
Section titled “Admin Users Only”const adminApp: ChatApp = { chatAppId: 'admin-dashboard', title: 'Admin Dashboard', enabled: true, userRoles: ['pika:site-admin']};Multiple Roles
Section titled “Multiple Roles”const supportApp: ChatApp = { chatAppId: 'support-tools', title: 'Support Tools', enabled: true, userRoles: ['pika:content-admin', 'customer-support', 'technical-support']};Step 3: Combine Types and Roles
Section titled “Step 3: Combine Types and Roles”Create sophisticated access rules by combining user types and roles.
Internal Users with Specific Roles (AND Logic)
Section titled “Internal Users with Specific Roles (AND Logic)”const restrictedApp: ChatApp = { chatAppId: 'sensitive-data', title: 'Sensitive Data Access', enabled: true, userTypes: ['internal-user'], userRoles: ['data-analyst', 'manager'], applyRulesAs: 'and' // Must be internal AND have role};Flexible Access (OR Logic)
Section titled “Flexible Access (OR Logic)”const flexibleApp: ChatApp = { chatAppId: 'reporting', title: 'Reporting Dashboard', enabled: true, userTypes: ['internal-user'], userRoles: ['external-consultant'], applyRulesAs: 'or' // Internal user OR consultant role};Step 4: Configure Entity-Based Access
Section titled “Step 4: Configure Entity-Based Access”Restrict access to specific organizations, accounts, or departments.
Prerequisites
Section titled “Prerequisites”First, enable the entity feature in pika-config.ts:
export const pikaConfig: PikaConfig = { siteFeatures: { entity: { enabled: true, attributeName: 'accountId', // Field in user.customData displayNameSingular: 'Account', displayNamePlural: 'Accounts' } }};Multi-Tenant Access via Override
Section titled “Multi-Tenant Access via Override”// Create override through Site Admin interfaceconst multiTenantOverride = { enabled: true, exclusiveExternalAccessControl: [ 'account_enterprise_gold', 'account_premium_tier', 'account_beta_customer' ], exclusiveInternalAccessControl: [ 'customer_success_team', 'enterprise_support' ] // External users: Only specified accounts // Internal users: Only specified teams};Step 5: Use Admin Overrides
Section titled “Step 5: Use Admin Overrides”Site admins can create overrides that completely replace chat app settings.
Temporary Access for Beta Testing
Section titled “Temporary Access for Beta Testing”// Admin creates overrideconst betaOverride = { enabled: true, exclusiveUserIdAccessControl: [ 'product_manager_sarah', 'developer_mike', 'qa_engineer_alex' ] // Only these users during beta};Emergency Access Control Changes
Section titled “Emergency Access Control Changes”// Restrict access immediatelyconst emergencyOverride = { enabled: true, userTypes: ['internal-user'], userRoles: ['pika:content-admin'] // Emergency: Only content admins can access};Configuration Patterns
Section titled “Configuration Patterns”Pattern 1: Progressive Access
Section titled “Pattern 1: Progressive Access”Start permissive, become more restrictive:
// Public chat appconst publicApp: ChatApp = { chatAppId: 'general-inquiry', enabled: true, userTypes: ['external-user']};
// Premium feature (via override)const premiumOverride = { enabled: true, exclusiveExternalAccessControl: ['premium_customers']};Pattern 2: Department Isolation
Section titled “Pattern 2: Department Isolation”Separate internal departments:
// HR department chatconst hrApp: ChatApp = { chatAppId: 'hr-assistant', enabled: true, userTypes: ['internal-user'], userRoles: ['hr-team', 'hr-manager']};
// Finance department chatconst financeApp: ChatApp = { chatAppId: 'finance-tools', enabled: true, userTypes: ['internal-user'], userRoles: ['finance-team', 'accountant', 'cfo']};Pattern 3: Customer Tier Access
Section titled “Pattern 3: Customer Tier Access”Different access by customer tier:
// Basic tier - all external usersconst basicApp: ChatApp = { chatAppId: 'basic-support', enabled: true, userTypes: ['external-user']};
// Premium tier (via override)const premiumOverride = { enabled: true, exclusiveExternalAccessControl: ['premium_tier', 'enterprise_tier']};
// Enterprise only (via override)const enterpriseOverride = { enabled: true, exclusiveExternalAccessControl: ['enterprise_tier']};Testing Checklist
Section titled “Testing Checklist”Verify your access control configuration:
Troubleshooting
Section titled “Troubleshooting”"No access" Warning in UI
Section titled “"No access" Warning in UI”If you see "No access - No user types or roles selected":
- Add
userTypesto specify which user types can access - Add
userRolesto specify which roles can access - Check for admin overrides that might be blocking access
User Can't Access Chat App
Section titled “User Can't Access Chat App”- Check user type: Verify user has correct
userTypeassigned in auth provider - Check user roles: Verify user has required roles
- Check entity access: If using entity-based access, verify user's entity is allowed
- Check override precedence: Higher precedence rules might be blocking access
- Review logs: Check authentication logs for access denial reasons
Features Not Working
Section titled “Features Not Working”- Site-level enabled: Verify feature is enabled in
pika-config.ts - Feature access rules: Check if feature has its own access restrictions
- Chat app overrides: Verify chat app hasn't disabled the feature
Debug Access Rules
Section titled “Debug Access Rules”// Log access check detailsconsole.log('Chat App Config:', { enabled: chatApp.enabled, userTypes: chatApp.userTypes, userRoles: chatApp.userRoles, applyRulesAs: chatApp.applyRulesAs});
// Check for overridesconsole.log('Override Config:', chatApp.override);
// Check user dataconsole.log('User Data:', { userId: user.userId, userType: user.userType, roles: user.roles, customData: user.customData});Security Best Practices
Section titled “Security Best Practices”1. Principle of Least Privilege
Section titled “1. Principle of Least Privilege”- Start with minimal access
- Expand only as needed
- Regular audit who has access to what
2. Configuration Validation
Section titled “2. Configuration Validation”- Always specify
userTypesoruserRoles - Test access with different user types
- Document why specific rules were chosen
3. Override Management
Section titled “3. Override Management”- Only trusted users should have
pika:site-adminrole - Log when overrides are created or modified
- Regularly review active overrides
- Remove temporary overrides when no longer needed
Next Steps
Section titled “Next Steps”- Integrate Your Authentication System - Set up user types and roles
- Set Up User-to-Organization Mapping - Configure entity relationships
- Work with Entities - Enable entity-based access control
Related Documentation
Section titled “Related Documentation”- Access Control Concepts - Understanding the access control model
- User Types Reference - Complete user type documentation
- Entity Management - Multi-tenancy with entities