RBAC (Role-Based Access Control) Examples¶
Last Updated: 2025-11-23
Complete examples for managing roles, permissions, and access control in ocmonica.
Table of Contents¶
- List Roles
- Create Custom Role
- Get Role Details
- Update Role
- Delete Role
- Assign Role to User
- Remove Role from User
- Check User Permissions
- Permission Enforcement Examples
List Roles¶
Get all roles in an organization including built-in and custom roles.
REST API¶
Endpoint: GET /organizations/:orgId/roles
curl Example¶
JavaScript/TypeScript Example¶
async function listRoles(orgId: string) {
const response = await fetch(`http://localhost:8080/organizations/${orgId}/roles`, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
return await response.json();
}
// Usage
const roles = await listRoles('org-789');
roles.forEach(role => {
console.log(`Role: ${role.name}`);
console.log(`Permissions: ${role.permissions.join(', ')}`);
});
Python Example¶
import requests
def list_roles(org_id, access_token):
response = requests.get(
f'http://localhost:8080/organizations/{org_id}/roles',
headers={'Authorization': f'Bearer {access_token}'}
)
return response.json()
# Usage
roles = list_roles('org-789', access_token)
for role in roles:
print(f"Role: {role['name']}")
print(f"Permissions: {', '.join(role['permissions'])}")
Go Example¶
type Role struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permissions []string `json:"permissions"`
OrganizationID string `json:"organization_id"`
IsBuiltin bool `json:"is_builtin"`
}
func listRoles(orgID, accessToken string) ([]Role, error) {
req, _ := http.NewRequest("GET",
fmt.Sprintf("http://localhost:8080/organizations/%s/roles", orgID),
nil)
req.Header.Set("Authorization", "Bearer "+accessToken)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var roles []Role
json.NewDecoder(resp.Body).Decode(&roles)
return roles, nil
}
Response¶
[
{
"id": "role-admin",
"name": "admin",
"description": "Full access to all resources",
"permissions": ["file:*", "org:*", "user:*", "role:*", "group:*"],
"organization_id": "org-789",
"is_builtin": true
},
{
"id": "role-member",
"name": "member",
"description": "Limited access to files and organization",
"permissions": ["file:read", "file:write", "org:read"],
"organization_id": "org-789",
"is_builtin": true
}
]
Create Custom Role¶
Create a custom role with specific permissions.
REST API¶
Endpoint: POST /organizations/:orgId/roles
Requires: role:create permission (admin only)
curl Example¶
curl -X POST http://localhost:8080/organizations/org-789/roles \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "editor",
"description": "Can edit files but not delete",
"permissions": ["file:read", "file:write", "org:read"]
}'
JavaScript/TypeScript Example¶
interface CreateRoleRequest {
name: string;
description?: string;
permissions: string[];
}
async function createRole(
orgId: string,
name: string,
permissions: string[],
description?: string
) {
const response = await fetch(`http://localhost:8080/organizations/${orgId}/roles`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name,
description,
permissions
})
});
return await response.json();
}
// Usage
const editorRole = await createRole(
'org-789',
'editor',
['file:read', 'file:write', 'org:read'],
'Can edit files but not delete'
);
console.log(`Role created: ${editorRole.id}`);
Python Example¶
import requests
def create_role(org_id, name, permissions, access_token, description=None):
data = {
'name': name,
'permissions': permissions
}
if description:
data['description'] = description
response = requests.post(
f'http://localhost:8080/organizations/{org_id}/roles',
headers={'Authorization': f'Bearer {access_token}'},
json=data
)
return response.json()
# Usage
editor_role = create_role(
'org-789',
'editor',
['file:read', 'file:write', 'org:read'],
access_token,
description='Can edit files but not delete'
)
print(f"Role created: {editor_role['id']}")
Go Example¶
type CreateRoleRequest struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Permissions []string `json:"permissions"`
}
func createRole(orgID, name, description, accessToken string, permissions []string) (*Role, error) {
reqData := CreateRoleRequest{
Name: name,
Description: description,
Permissions: permissions,
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST",
fmt.Sprintf("http://localhost:8080/organizations/%s/roles", orgID),
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var role Role
json.NewDecoder(resp.Body).Decode(&role)
return &role, nil
}
Get Role Details¶
Get detailed information about a specific role.
REST API¶
Endpoint: GET /api/v1/roles/:id
curl Example¶
JavaScript/TypeScript Example¶
async function getRole(roleId: string) {
const response = await fetch(
`http://localhost:8080/api/v1/roles/${roleId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
return await response.json();
}
// Usage
const role = await getRole('role-editor');
console.log(`Role: ${role.name}`);
console.log(`Permissions: ${role.permissions.join(', ')}`);
Update Role¶
Update role name, description, or permissions.
REST API¶
Endpoint: PUT /api/v1/roles/:id
Requires: role:update permission (admin only)
Note: Cannot update built-in roles.
curl Example¶
curl -X PUT http://localhost:8080/api/v1/roles/role-editor \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "content_editor",
"description": "Can edit and delete files",
"permissions": ["file:read", "file:write", "file:delete", "org:read"]
}'
JavaScript/TypeScript Example¶
async function updateRole(
roleId: string,
updates: {
name?: string;
description?: string;
permissions?: string[];
}
) {
const response = await fetch(
`http://localhost:8080/api/v1/roles/${roleId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(updates)
}
);
return await response.json();
}
// Usage
const updated = await updateRole('role-editor', {
name: 'content_editor',
description: 'Can edit and delete files',
permissions: ['file:read', 'file:write', 'file:delete', 'org:read']
});
Python Example¶
import requests
def update_role(role_id, access_token, **updates):
response = requests.put(
f'http://localhost:8080/api/v1/roles/{role_id}',
headers={'Authorization': f'Bearer {access_token}'},
json=updates
)
return response.json()
# Usage
updated = update_role(
'role-editor',
access_token,
name='content_editor',
description='Can edit and delete files',
permissions=['file:read', 'file:write', 'file:delete', 'org:read']
)
Delete Role¶
Delete a custom role from the organization.
REST API¶
Endpoint: DELETE /api/v1/roles/:id
Requires: role:delete permission (admin only)
Note: Cannot delete built-in roles.
curl Example¶
curl -X DELETE \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
http://localhost:8080/api/v1/roles/role-editor
JavaScript/TypeScript Example¶
async function deleteRole(roleId: string) {
const response = await fetch(
`http://localhost:8080/api/v1/roles/${roleId}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (response.ok) {
console.log('Role deleted successfully');
}
}
// Usage with confirmation
if (confirm('Delete this role? Users will lose these permissions.')) {
await deleteRole('role-editor');
}
Warning: Users with this role will lose associated permissions. Reassign users before deleting.
Assign Role to User¶
Assign a role to a user in the organization.
Note: Role assignment is handled via the organization member role update endpoint. See organization member management for details.
REST API¶
Endpoint: PUT /organizations/:id/members/:userId/role
Requires: role:assign permission (admin only)
curl Example¶
curl -X PUT http://localhost:8080/organizations/org-789/members/user-456/role \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"role": "editor"
}'
JavaScript/TypeScript Example¶
async function assignRoleToUser(orgId: string, userId: string, role: string) {
const response = await fetch(
`http://localhost:8080/organizations/${orgId}/members/${userId}/role`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
role: role
})
}
);
return await response.json();
}
// Usage
await assignRoleToUser('org-789', 'user-456', 'editor');
console.log('Role assigned successfully');
Python Example¶
import requests
def assign_role_to_user(org_id, user_id, role, access_token):
response = requests.put(
f'http://localhost:8080/organizations/{org_id}/members/{user_id}/role',
headers={'Authorization': f'Bearer {access_token}'},
json={'role': role}
)
return response.json()
# Usage
assign_role_to_user('org-789', 'user-456', 'editor', access_token)
print('Role assigned successfully')
Go Example¶
type AssignRoleRequest struct {
Role string `json:"role"`
}
func assignRoleToUser(orgID, userID, role, accessToken string) error {
reqData := AssignRoleRequest{Role: role}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("PUT",
fmt.Sprintf("http://localhost:8080/organizations/%s/members/%s/role", orgID, userID),
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
Remove Role from User¶
Remove a role assignment from a user by assigning them a different role (e.g., default 'member' role).
Check User Permissions¶
Verify if the current user has specific permissions.
REST API¶
Endpoint: GET /auth/permissions
curl Example¶
# Get all permissions
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
http://localhost:8080/auth/permissions
# Check specific permission
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"http://localhost:8080/auth/permissions?check=file:delete"
JavaScript/TypeScript Example¶
async function getUserPermissions() {
const response = await fetch(
'http://localhost:8080/auth/permissions',
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
return await response.json();
}
async function hasPermission(permission: string): Promise<boolean> {
const response = await fetch(
`http://localhost:8080/auth/permissions?check=${permission}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const result = await response.json();
return result.has_permission;
}
// Usage
const permissions = await getUserPermissions();
console.log('User permissions:', permissions);
if (await hasPermission('file:delete')) {
console.log('User can delete files');
}
Python Example¶
import requests
def get_user_permissions(access_token):
response = requests.get(
'http://localhost:8080/auth/permissions',
headers={'Authorization': f'Bearer {access_token}'}
)
return response.json()
def has_permission(permission, access_token):
response = requests.get(
f'http://localhost:8080/auth/permissions?check={permission}',
headers={'Authorization': f'Bearer {access_token}'}
)
result = response.json()
return result.get('has_permission', False)
# Usage
permissions = get_user_permissions(access_token)
print(f"User permissions: {permissions}")
if has_permission('file:delete', access_token):
print('User can delete files')
Permission Enforcement Examples¶
Client-Side Permission Checks¶
// Conditionally render UI elements based on permissions
function FileActions({ file }: { file: File }) {
const [canDelete, setCanDelete] = useState(false);
const [canEdit, setCanEdit] = useState(false);
useEffect(() => {
Promise.all([
hasPermission('file:delete'),
hasPermission('file:write')
]).then(([deletePermission, writePermission]) => {
setCanDelete(deletePermission);
setCanEdit(writePermission);
});
}, []);
return (
<div>
{canEdit && <button onClick={() => editFile(file.id)}>Edit</button>}
{canDelete && <button onClick={() => deleteFile(file.id)}>Delete</button>}
</div>
);
}
Server-Side Permission Enforcement¶
The server enforces permissions at multiple levels:
- Middleware/Interceptor: First line of defense
- Service Layer: Business logic checks
- Repository: Organization scoping
// Example API call that will be checked server-side
async function deleteFile(fileId: string) {
try {
const response = await fetch(
`http://localhost:8080/api/v1/files/${fileId}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (response.status === 403) {
throw new Error('Permission denied: You do not have permission to delete files');
}
if (!response.ok) {
throw new Error('Failed to delete file');
}
} catch (error) {
console.error('Delete failed:', error);
throw error;
}
}
Permission Format¶
Permission Structure¶
Format: resource:action
Resources:
- file - File operations
- org - Organization management
- user - User management
- role - Role management
- group - Group management
Actions:
- read - Read/view resources
- write - Create/update resources
- delete - Delete resources
- * - All actions (wildcard)
Common Permissions¶
const COMMON_PERMISSIONS = {
// File permissions
FILE_READ: 'file:read',
FILE_WRITE: 'file:write',
FILE_DELETE: 'file:delete',
FILE_ALL: 'file:*',
// Organization permissions
ORG_READ: 'org:read',
ORG_ADMIN: 'org:admin',
ORG_ALL: 'org:*',
// User management
USER_READ: 'user:read',
USER_MANAGE: 'user:manage',
USER_ALL: 'user:*',
// Role management
ROLE_READ: 'role:read',
ROLE_CREATE: 'role:create',
ROLE_UPDATE: 'role:update',
ROLE_DELETE: 'role:delete',
ROLE_ASSIGN: 'role:assign',
ROLE_ALL: 'role:*',
};
Built-in Role Definitions¶
const BUILTIN_ROLES = {
admin: {
name: 'admin',
description: 'Full access to all resources',
permissions: ['file:*', 'org:*', 'user:*', 'role:*', 'group:*']
},
member: {
name: 'member',
description: 'Limited access to files and organization',
permissions: ['file:read', 'file:write', 'org:read']
}
};
See Also¶
- Authentication Guide
- REST API Reference
- Organization Management Examples
- See
SECURITY.mdin the project root for security documentation