Permissions & Access Control
Manage user permissions, roles, and fine-grained access control in pxlpeak.
Overview
pxlpeak implements a Role-Based Access Control (RBAC) system with support for fine-grained permissions at multiple levels. This allows you to precisely control who can view, edit, or manage your analytics data.
Access Control Hierarchy
┌─────────────────────────────────────────────────────────────────────────────┐
│ Organization Level │
│ • Organization Owner (full control) │
│ • Organization Admin (manage all workspaces) │
└───────────────────────────────────┬─────────────────────────────────────────┘
│
┌───────────────────────────────────▼─────────────────────────────────────────┐
│ Workspace Level │
│ • Workspace Owner • Admin • Editor • Analyst • Viewer │
└───────────────────────────────────┬─────────────────────────────────────────┘
│
┌───────────────────────────────────▼─────────────────────────────────────────┐
│ Site Level │
│ • Site-specific role overrides │
│ • Data view restrictions │
└───────────────────────────────────┬─────────────────────────────────────────┘
│
┌───────────────────────────────────▼─────────────────────────────────────────┐
│ Resource Level │
│ • Report access • Dashboard sharing • Export permissions │
└─────────────────────────────────────────────────────────────────────────────┘Workspace Roles
Role Definitions
| Role | Description | Typical Users | |------|-------------|---------------| | Owner | Full workspace control including billing and deletion | Founders, account holders | | Admin | Manage team, sites, and settings (no billing) | Team leads, managers | | Editor | Create and modify goals, segments, and reports | Marketing managers, analysts | | Analyst | View all data and create personal reports | Data analysts, consultants | | Viewer | Read-only access to dashboards and shared reports | Stakeholders, executives |
Permission Matrix
┌────────────────────────────────┬───────┬───────┬────────┬─────────┬────────┐
│ Permission │ Owner │ Admin │ Editor │ Analyst │ Viewer │
├────────────────────────────────┼───────┼───────┼────────┼─────────┼────────┤
│ View dashboards │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
│ View reports │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
│ View real-time data │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├────────────────────────────────┼───────┼───────┼────────┼─────────┼────────┤
│ Create personal reports │ ✓ │ ✓ │ ✓ │ ✓ │ │
│ Export data (CSV/Excel) │ ✓ │ ✓ │ ✓ │ ✓ │ │
│ Use API (read) │ ✓ │ ✓ │ ✓ │ ✓ │ │
├────────────────────────────────┼───────┼───────┼────────┼─────────┼────────┤
│ Create/edit goals │ ✓ │ ✓ │ ✓ │ │ │
│ Create/edit segments │ ✓ │ ✓ │ ✓ │ │ │
│ Create/edit shared reports │ ✓ │ ✓ │ ✓ │ │ │
│ Create/edit dashboards │ ✓ │ ✓ │ ✓ │ │ │
│ Configure alerts │ ✓ │ ✓ │ ✓ │ │ │
│ Use API (write) │ ✓ │ ✓ │ ✓ │ │ │
├────────────────────────────────┼───────┼───────┼────────┼─────────┼────────┤
│ Add/remove sites │ ✓ │ ✓ │ │ │ │
│ Configure site settings │ ✓ │ ✓ │ │ │ │
│ Manage team members │ ✓ │ ✓ │ │ │ │
│ Create API keys │ ✓ │ ✓ │ │ │ │
│ Configure webhooks │ ✓ │ ✓ │ │ │ │
│ Workspace settings │ ✓ │ ✓ │ │ │ │
├────────────────────────────────┼───────┼───────┼────────┼─────────┼────────┤
│ Manage billing │ ✓ │ │ │ │ │
│ Delete workspace │ ✓ │ │ │ │ │
│ Transfer ownership │ ✓ │ │ │ │ │
└────────────────────────────────┴───────┴───────┴────────┴─────────┴────────┘Assigning Roles
Via Dashboard
- Navigate to Workspace Settings → Team
- Click Invite Member or select an existing member
- Choose the appropriate role from the dropdown
- Optionally configure site-level restrictions
Via API
// Invite new member with role
const invitation = await pxlpeak.workspaces.inviteMember({
workspaceId: 'ws_xxx',
email: 'newuser@example.com',
role: 'editor',
message: 'Join our analytics team!'
});
// Update existing member's role
await pxlpeak.workspaces.updateMember({
workspaceId: 'ws_xxx',
memberId: 'member_yyy',
role: 'admin'
});
// List all members and their roles
const members = await pxlpeak.workspaces.listMembers({
workspaceId: 'ws_xxx'
});
// Response
// {
// data: [
// { id: 'member_xxx', email: 'owner@example.com', role: 'owner', joinedAt: '...' },
// { id: 'member_yyy', email: 'analyst@example.com', role: 'analyst', joinedAt: '...' }
// ]
// }Site-Level Permissions
Restricting Site Access
By default, workspace members can access all sites. You can restrict access to specific sites:
// Invite member with limited site access
await pxlpeak.workspaces.inviteMember({
workspaceId: 'ws_xxx',
email: 'contractor@agency.com',
role: 'analyst',
siteAccess: ['site_123', 'site_456'] // Only these sites
});
// Update site access for existing member
await pxlpeak.workspaces.updateMember({
workspaceId: 'ws_xxx',
memberId: 'member_yyy',
siteAccess: ['site_123'] // Restrict to single site
});
// Grant access to all sites
await pxlpeak.workspaces.updateMember({
workspaceId: 'ws_xxx',
memberId: 'member_yyy',
siteAccess: 'all'
});Site Role Overrides
Override workspace role for specific sites:
// Member is Editor in workspace, but Viewer for sensitive site
await pxlpeak.sites.setMemberRole({
siteId: 'site_sensitive',
memberId: 'member_xxx',
role: 'viewer' // Override workspace Editor role
});
// Member is Analyst in workspace, but Admin for their own site
await pxlpeak.sites.setMemberRole({
siteId: 'site_personal',
memberId: 'member_yyy',
role: 'admin' // Elevate for this site only
});Data Views & Filters
Creating Restricted Views
Data views allow members to see only specific subsets of data:
// Create a filtered view
const view = await pxlpeak.views.create({
siteId: 'site_xxx',
name: 'US Marketing Traffic',
filters: [
{ field: 'country', operator: 'eq', value: 'US' },
{ field: 'source', operator: 'in', values: ['google', 'facebook', 'linkedin'] }
]
});
// Assign view to member (they can only see this filtered data)
await pxlpeak.views.assignMember({
viewId: view.id,
memberId: 'member_xxx',
accessType: 'restricted' // Can only see this view
});PII Masking
Protect personally identifiable information:
// Configure PII masking for role
await pxlpeak.workspaces.configurePIIMasking({
workspaceId: 'ws_xxx',
rules: [
{
role: 'viewer',
mask: ['email', 'ip_address', 'user_id']
},
{
role: 'analyst',
mask: ['ip_address']
}
]
});Masked Data Example:
// Viewer sees:
{
"user_id": "***masked***",
"email": "***masked***",
"country": "US",
"page_views": 15
}
// Analyst sees:
{
"user_id": "usr_123abc",
"email": "user@example.com",
"country": "US",
"page_views": 15
}API Key Permissions
Key Types
| Key Type | Prefix | Capabilities |
|----------|--------|--------------|
| Public | pk_ | Client-side tracking only |
| Secret | sk_ | Full API access (server-side) |
| Restricted | rk_ | Custom permission scopes |
Creating Restricted Keys
// Create API key with limited permissions
const apiKey = await pxlpeak.apiKeys.create({
workspaceId: 'ws_xxx',
name: 'Read-Only Analytics',
type: 'restricted',
scopes: [
'analytics:read',
'reports:read',
'segments:read'
],
siteIds: ['site_123'], // Limit to specific sites
ipAllowlist: ['192.168.1.0/24'], // Optional IP restriction
expiresAt: '2026-12-31T23:59:59Z' // Optional expiration
});Available Scopes
const scopes = {
// Analytics
'analytics:read': 'Read analytics data',
'analytics:export': 'Export analytics data',
// Events
'events:write': 'Send tracking events',
'events:read': 'Read raw event data',
// Reports
'reports:read': 'View reports',
'reports:write': 'Create/edit reports',
'reports:delete': 'Delete reports',
// Segments
'segments:read': 'View segments',
'segments:write': 'Create/edit segments',
'segments:delete': 'Delete segments',
// Goals
'goals:read': 'View conversion goals',
'goals:write': 'Create/edit goals',
'goals:delete': 'Delete goals',
// Sites
'sites:read': 'View site configuration',
'sites:write': 'Modify site settings',
'sites:delete': 'Delete sites',
// Users (admin)
'users:read': 'View team members',
'users:write': 'Manage team members',
// Webhooks
'webhooks:read': 'View webhooks',
'webhooks:write': 'Manage webhooks',
// Billing
'billing:read': 'View billing info',
'billing:write': 'Manage billing'
};Managing Keys
// List all API keys
const keys = await pxlpeak.apiKeys.list({
workspaceId: 'ws_xxx'
});
// Rotate key (invalidate old, create new)
const newKey = await pxlpeak.apiKeys.rotate({
keyId: 'key_xxx'
});
// Revoke key immediately
await pxlpeak.apiKeys.revoke({
keyId: 'key_xxx'
});
// View key usage
const usage = await pxlpeak.apiKeys.getUsage({
keyId: 'key_xxx',
period: '30d'
});Single Sign-On (SSO)
SAML Configuration
For Enterprise plans, configure SAML SSO:
// Configure SAML identity provider
await pxlpeak.sso.configureSAML({
workspaceId: 'ws_xxx',
provider: 'okta', // or 'azure_ad', 'onelogin', 'google_workspace', 'custom'
config: {
entityId: 'https://www.okta.com/exk...',
ssoUrl: 'https://company.okta.com/app/.../sso/saml',
certificate: '-----BEGIN CERTIFICATE-----\n...',
attributeMapping: {
email: 'user.email',
firstName: 'user.firstName',
lastName: 'user.lastName',
groups: 'user.groups'
}
}
});Automatic Role Mapping
Map IdP groups to pxlpeak roles:
await pxlpeak.sso.configureRoleMapping({
workspaceId: 'ws_xxx',
mappings: [
{ group: 'pxlpeak-admins', role: 'admin' },
{ group: 'pxlpeak-editors', role: 'editor' },
{ group: 'pxlpeak-analysts', role: 'analyst' },
{ group: 'pxlpeak-viewers', role: 'viewer' }
],
defaultRole: 'viewer', // For users without matching groups
autoProvision: true // Create users on first login
});Enforcing SSO
// Require SSO for all workspace members
await pxlpeak.sso.enforce({
workspaceId: 'ws_xxx',
requireSSO: true,
gracePeriodDays: 7, // Allow password login during transition
exemptEmails: ['admin@company.com'] // Backup admin access
});Two-Factor Authentication (2FA)
Enabling 2FA
// User enables 2FA for their account
await pxlpeak.auth.enable2FA({
method: 'totp' // or 'sms', 'security_key'
});
// Returns setup info
// {
// secret: 'JBSWY3DPEHPK3PXP',
// qrCode: 'data:image/png;base64,...',
// backupCodes: ['abc123', 'def456', ...]
// }Enforcing 2FA for Workspace
// Require 2FA for specific roles
await pxlpeak.workspaces.enforce2FA({
workspaceId: 'ws_xxx',
requiredForRoles: ['owner', 'admin', 'editor'],
gracePeriodDays: 14
});
// Require 2FA for all members
await pxlpeak.workspaces.enforce2FA({
workspaceId: 'ws_xxx',
requiredForRoles: 'all'
});Audit Logging
Viewing Audit Logs
All permission-related actions are logged:
// Query audit logs
const logs = await pxlpeak.audit.query({
workspaceId: 'ws_xxx',
filters: {
category: 'permissions', // or 'auth', 'data', 'settings'
startDate: '2026-01-01',
endDate: '2026-01-12'
},
pagination: {
limit: 100,
cursor: null
}
});Audit Log Entry:
{
"id": "audit_xxx",
"timestamp": "2026-01-12T10:30:00Z",
"actor": {
"id": "member_xxx",
"email": "admin@example.com",
"role": "admin"
},
"action": "member.role_changed",
"resource": {
"type": "member",
"id": "member_yyy"
},
"details": {
"previous_role": "viewer",
"new_role": "editor"
},
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0..."
}Logged Events
| Category | Events | |----------|--------| | Auth | login, logout, 2fa_enabled, password_changed, sso_login | | Permissions | member_invited, role_changed, member_removed, api_key_created | | Data | data_exported, segment_created, report_shared | | Settings | site_created, site_deleted, settings_changed |
Session Management
Active Sessions
// List user's active sessions
const sessions = await pxlpeak.auth.listSessions();
// Response
// {
// sessions: [
// {
// id: 'sess_xxx',
// device: 'Chrome on macOS',
// location: 'San Francisco, US',
// lastActive: '2026-01-12T10:00:00Z',
// current: true
// },
// {
// id: 'sess_yyy',
// device: 'Safari on iPhone',
// location: 'Los Angeles, US',
// lastActive: '2026-01-11T15:30:00Z',
// current: false
// }
// ]
// }
// Revoke specific session
await pxlpeak.auth.revokeSession('sess_yyy');
// Revoke all sessions except current
await pxlpeak.auth.revokeAllSessions({ exceptCurrent: true });Session Policies
// Configure session timeout
await pxlpeak.workspaces.setSessionPolicy({
workspaceId: 'ws_xxx',
maxSessionDuration: '8h', // Max active session
idleTimeout: '30m', // Logout after inactivity
requireReauth: ['billing', 'delete'], // Re-authenticate for sensitive actions
allowRememberMe: true,
maxConcurrentSessions: 5
});Best Practices
Principle of Least Privilege
- Start with Viewer - Assign minimum access initially
- Elevate as needed - Grant additional permissions when justified
- Regular audits - Review permissions quarterly
- Remove promptly - Revoke access when no longer needed
Secure API Key Management
// ✅ Good: Use restricted keys with minimal scopes
const key = await pxlpeak.apiKeys.create({
name: 'Production Tracking',
type: 'restricted',
scopes: ['events:write'],
ipAllowlist: ['10.0.0.0/8']
});
// ❌ Bad: Using secret key with full access everywhere
const key = process.env.PXLPEAK_SECRET_KEY; // Full access, no restrictionsEnvironment Separation
Production Workspace Staging Workspace
├── prod-site.com ├── staging-site.com
├── Admin: DevOps Team ├── Admin: Developers
├── Viewer: Marketing ├── Viewer: QA Team
└── Secret keys only └── Restricted keys OKChecklist
- [ ] All team members have appropriate roles assigned
- [ ] API keys are scoped to minimum required permissions
- [ ] SSO is configured for Enterprise workspaces
- [ ] 2FA is enforced for admin roles
- [ ] Audit logging is enabled and monitored
- [ ] Inactive members are removed within 30 days
- [ ] API keys are rotated every 90 days
- [ ] Session policies align with security requirements
Troubleshooting
Common Issues
"Permission denied" error
// Check your current permissions
const me = await pxlpeak.auth.me();
console.log('Role:', me.workspaces[0].role);
console.log('Scopes:', me.apiKey?.scopes);
// Verify required scope for the action
// POST /v1/segments requires 'segments:write' scopeUser can't access a site
// Check site-level access
const member = await pxlpeak.workspaces.getMember({
workspaceId: 'ws_xxx',
memberId: 'member_yyy'
});
console.log('Site access:', member.siteAccess);
// If 'all', check for site role overrides
// If array, verify the site is includedAPI key not working
// Verify key details
const key = await pxlpeak.apiKeys.get({ keyId: 'key_xxx' });
// Check:
// - Is it expired? (expiresAt)
// - Is the IP allowed? (ipAllowlist)
// - Does it have required scopes? (scopes)
// - Is it for the right workspace? (workspaceId)Next: See Billing & Subscriptions to manage your plan and payments.