| name | juicebox-enterprise-rbac |
| description | Configure Juicebox enterprise role-based access control.
Use when implementing team permissions, configuring access policies,
or setting up enterprise security controls.
Trigger with phrases like "juicebox RBAC", "juicebox permissions",
"juicebox access control", "juicebox enterprise security".
|
| allowed-tools | Read, Write, Edit, Bash(kubectl:*), Bash(curl:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Juicebox Enterprise RBAC
Overview
Implement enterprise-grade role-based access control for Juicebox integrations.
Prerequisites
- Enterprise Juicebox plan
- Identity provider (Okta, Auth0, Azure AD)
- Understanding of access control patterns
Role Hierarchy
Admin
├── Manager
│ ├── Senior Recruiter
│ │ └── Recruiter
│ └── Hiring Manager
├── Analyst (read-only)
└── API Service Account
Instructions
Step 1: Define Roles and Permissions
export enum Permission {
SEARCH_READ = 'search:read',
SEARCH_ADVANCED = 'search:advanced',
SEARCH_EXPORT = 'search:export',
PROFILE_READ = 'profile:read',
PROFILE_ENRICH = 'profile:enrich',
PROFILE_CONTACT = 'profile:contact',
PROFILE_NOTES = 'profile:notes',
TEAM_VIEW = 'team:view',
TEAM_MANAGE = 'team:manage',
ADMIN_SETTINGS = 'admin:settings',
ADMIN_BILLING = 'admin:billing',
ADMIN_AUDIT = 'admin:audit'
}
export enum Role {
ADMIN = 'admin',
MANAGER = 'manager',
SENIOR_RECRUITER = 'senior_recruiter',
RECRUITER = 'recruiter',
HIRING_MANAGER = 'hiring_manager',
ANALYST = 'analyst',
=
}
: <, []> = {
[.]: .(),
[.]: [
.,
.,
.,
.,
.,
.,
.,
.,
.
],
[.]: [
.,
.,
.,
.,
.,
.,
.,
.
],
[.]: [
.,
.,
.,
.
],
[.]: [
.,
.,
.,
.
],
[.]: [
.,
.,
.
],
[.]: [
.,
.,
.
]
};
Step 2: Implement Permission Checker
export class PermissionChecker {
constructor(private user: User) {}
hasPermission(permission: Permission): boolean {
const userPermissions = this.getUserPermissions();
return userPermissions.includes(permission);
}
hasAnyPermission(permissions: Permission[]): boolean {
return permissions.some(p => this.hasPermission(p));
}
hasAllPermissions(permissions: Permission[]): boolean {
return permissions.every(p => this.hasPermission(p));
}
private getUserPermissions(): Permission[] {
const role = this.user.role as Role;
const basePermissions = rolePermissions[role] || [];
customPermissions = .. || [];
[... ([...basePermissions, ...customPermissions])];
}
(: ): <> {
(!.(.)) {
;
}
(..?. > ) {
profile = db..({
: { : profileId },
: { : }
});
...(profile?.);
}
;
}
}
Step 3: Authorization Middleware
import { Permission } from '../lib/rbac/permissions';
import { PermissionChecker } from '../lib/rbac/permission-checker';
export function requirePermission(...permissions: Permission[]) {
return async (req: Request, res: Response, next: NextFunction) => {
const user = req.user;
if (!user) {
return res.status(401).json({ error: 'Authentication required' });
}
const checker = new PermissionChecker(user);
if (!checker.hasAllPermissions(permissions)) {
await logAccessDenied(user, permissions, req);
return res.status(403).json({
error: 'Insufficient permissions',
required: permissions
});
}
next();
};
}
export function () {
(: , : , : ) => {
user = req.;
(!user) {
res.().({ : });
}
checker = (user);
(!checker.(permissions)) {
(user, permissions, req);
res.().({
: ,
: permissions
});
}
();
};
}
app.(,
(.),
searchController.
);
app.(,
(., .),
profileController.
);
app.(,
(.),
profileController.
);
Step 4: Team-Based Access Control
export class TeamAccessControl {
constructor(private db: Database) {}
async canAccessTeamData(userId: string, teamId: string): Promise<boolean> {
const membership = await this.db.teamMemberships.findFirst({
where: {
userId,
teamId,
active: true
}
});
return !!membership;
}
async filterByTeamAccess<T extends { teamId: string }>(
userId: string,
items: T[]
): Promise<T[]> {
const userTeams = await this.getUserTeams(userId);
return items.filter(item => userTeams.includes(item.teamId));
}
async getUserTeams(userId: string): Promise<string[]> {
memberships = ...({
: { userId, : },
: { : }
});
memberships.( m.);
}
}
Step 5: Audit Trail
export class RBACauditLog {
async logAccess(event: {
userId: string;
action: string;
resource: string;
resourceId?: string;
granted: boolean;
permissions: Permission[];
}): Promise<void> {
await db.rbacAuditLog.create({
data: {
...event,
timestamp: new Date(),
ip: getCurrentIP(),
userAgent: getCurrentUserAgent()
}
});
if (!event.granted) {
await this.checkSuspiciousActivity(event.userId);
}
}
private async checkSuspiciousActivity(userId: string): Promise<void> {
const recentDenials = await db.rbacAuditLog.count({
: {
userId,
: ,
: { : (.() - ) }
}
});
(recentDenials > ) {
alertService.({
: ,
: ,
:
});
}
}
}
API Key Scopes
const serviceAccountKey = await juicebox.apiKeys.create({
name: 'integration-service',
scopes: [
'search:read',
'profiles:read',
'profiles:enrich'
],
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
ipAllowlist: ['10.0.0.0/8']
});
RBAC Checklist
## Enterprise RBAC Setup
### Role Definition
- [ ] Roles mapped to business functions
- [ ] Permissions granular and well-defined
- [ ] Role hierarchy documented
- [ ] Service account roles separate
### Implementation
- [ ] Permission checks on all endpoints
- [ ] Team-level access enforced
- [ ] Audit logging enabled
- [ ] Suspicious activity alerts
### Integration
- [ ] SSO/SAML configured
- [ ] Group sync from IdP
- [ ] JIT provisioning enabled
- [ ] Offboarding automation
Output
- Role and permission definitions
- Permission checker implementation
- Authorization middleware
- Team access control
- Audit logging
Resources
Next Steps
After RBAC setup, see juicebox-migration-deep-dive for advanced migrations.