RBAC

Manage roles, groups, grants and test effective rights
Test rights
Selected: {{ test.user.email }}
Org: {{ orgs[0].name }}
{{ testStatus }}
{{ testResult.allowed ? 'ALLOWED' : 'DENIED' }}
Reason: {{ testResult.reason }}
Decision layer: {{ testResult.decisionLayer }}
Context
Groups: {{ (testResult.context.groups || []).map(g => g.id).join(', ') || '-' }}
Roles: {{ (testResult.context.roles || []).map(r => r.roleId + (r.source==='group' ? '@' + r.groupId : '')).join(', ') || '-' }}
Matched grants
{{ e.effect }} {{ e.right }}
{{ e.source }} | {{ e.scopeType }} {{ e.scopeId || '' }}
Create grant
Selected: {{ grant.subjectId }}
{{ grantStatus }}
Group members
Org-scoped group: user search is limited to members of {{ selectedGroup.orgId }}
Selected users to add ({{ memberAdd.selectedUsers.length }})
{{ u.email }}
{{ u.id }}
{{ memberAdd.status }}
Current members
{{ memberRemove.status }}
No members.
Grants
{{ g.effect }} {{ g.right }}
subject: {{ g.subjectType }} {{ g.subjectId }} | scope: {{ g.scopeType }} {{ g.scopeId || '' }}
No grants yet.
Create group
{{ groupStatus }}
Group roles
{{ gr.key }} ({{ gr.isGlobal ? 'global' : 'org' }})
roleId: {{ gr.roleId }}
No roles assigned.
Group members
Org-scoped group: user search is limited to members of {{ selectedGroup.orgId }}
Selected users to add ({{ memberAdd.selectedUsers.length }})
{{ u.email }}
{{ u.id }}
{{ memberAdd.status }}
Current members
{{ memberRemove.status }}
No members.
Groups
{{ g.name }}
{{ g.isGlobal ? 'global' : ('org ' + (g.orgId || '')) }}
{{ g.description || '-' }}
id: {{ g.id }}
No groups yet.
Create role
{{ roleStatus }}
Roles
{{ r.key }}
{{ r.isGlobal ? 'global' : ('org ' + (r.orgId || '')) }}
{{ r.name }}
{{ r.description || '-' }}
id: {{ r.id }}
No roles yet.

Programmatic Rights Checking (Middleware Mode)

Use the RBAC service directly in your code when running SuperBackend in middleware mode.

Accessing the Service

const rbac = globalThis.superbackend.services.rbac;

Basic Rights Check

const result = await rbac.checkRight(userId, orgId, 'backoffice:dashboard:access');

if (result.allowed) {
  // User has permission - proceed
  console.log('Access granted');
} else {
  // Permission denied
  console.log('Access denied by:', result.decisionLayer);
  // result.decisionLayer can be: 'user', 'role', 'group', 'org', or 'global'
}

Express Middleware Example

const requireRight = (right) => async (req, res, next) => {
  const rbac = globalThis.superbackend.services.rbac;
  const result = await rbac.checkRight(req.user.id, req.org.id, right);
  
  if (result.allowed) return next();
  res.status(403).json({ error: 'Insufficient permissions' });
};

// Usage
app.get('/admin/dashboard', 
  authenticate, // your auth middleware
  requireRight('backoffice:dashboard:access'),
  dashboardHandler
);

HTTP API Rights Checking

Check rights via REST API from external services or frontend applications.

Endpoint

POST /api/rbac/check
Content-Type: application/json
Authorization: Bearer <JWT> or Basic Auth

Request Body

{
  "userId": "507f1f77bcf86cd799439011",
  "orgId": "507f1f77bcf86cd799439012",
  "right": "backoffice:dashboard:access"
}

Response

{
  "allowed": true,
  "decisionLayer": "role",
  "context": {
    "userRoles": ["admin", "editor"],
    "groupRoles": ["viewer"],
    "userGrants": [],
    "roleGrants": [
      { "right": "backoffice:dashboard:access", "effect": "allow" }
    ],
    "groupGrants": [],
    "orgGrants": [],
    "globalGrants": []
  }
}

curl Example

curl -X POST http://localhost:3000/api/rbac/check \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "507f1f77bcf86cd799439011",
    "orgId": "507f1f77bcf86cd799439012",
    "right": "backoffice:dashboard:access"
  }'

JavaScript Fetch Example

const response = await fetch('/api/rbac/check', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    userId: '507f1f77bcf86cd799439011',
    orgId: '507f1f77bcf86cd799439012',
    right: 'backoffice:dashboard:access'
  })
});

const result = await response.json();
if (result.allowed) {
  // Proceed with action
}

Common Integration Patterns

Wildcard Rights

// Check for wildcard rights
const result = await rbac.checkRight(userId, orgId, 'backoffice:*');
// Matches: backoffice:dashboard:access, backoffice:users:read, etc.

Multiple Rights Check

// Check multiple rights (AND logic)
const rights = ['backoffice:dashboard:access', 'backoffice:users:read'];
const results = await Promise.all(
  rights.map(right => rbac.checkRight(userId, orgId, right))
);

const hasAll = results.every(r => r.allowed);
const hasAny = results.some(r => r.allowed);

Global vs Org-Scoped Rights

// Global rights (orgId can be null/undefined)
await rbac.checkRight(userId, null, 'system:admin');

// Org-specific rights
await rbac.checkRight(userId, orgId, 'org:settings:edit');

Troubleshooting & Best Practices

Common Errors

  • Invalid userId: Ensure the user exists in your database
  • Invalid orgId: For org-scoped rights, orgId must be valid
  • Malformed right: Rights should follow the pattern domain:action:resource
  • Authentication: API calls require valid JWT or Basic Auth

Performance Tips

  • Cache results for frequently checked rights
  • Use wildcard rights to reduce grant count
  • Batch multiple rights checks when possible
  • Consider decisionLayer for audit logging

Tip: Use the decisionLayer property to understand why access was granted/denied. This is useful for audit trails and debugging.