Step 12: Advanced Access Control & Auditing
Master fine-grained permissions, understand the authorization model, and track who changed what.
In the previous step, you learned how to manage users and assign roles. This step goes deeper into ControlBird's permission system: how to create fine-grained access rules, understand the authorization model, assign areas of responsibility, and audit every change in your system.
Understanding the Authorization Model
ControlBird uses a hybrid RBAC + ABAC model. This combines the simplicity of role-based access control with the flexibility of attribute-based conditions.
Subjects vs Resources
Every permission rule has two sides: a subject (who is requesting access) and a resource (what they're trying to access).
Subject
- A user account
- Has one or more assigned roles
- Has feature permissions
- Has areas of responsibility
- Has attributes such as whether the account is active
Resource
- Any item in your system
- Targeted by type or by a specific item
- Access can be limited to individual fields
- Scoped: Read Only or Read and Write
Two Permission Layers
ControlBird separates data access from feature visibility. This allows you to control both what data users can see and which UI features they can use.
Permission Resolution
Data permissions apply to every read and write. Add permission rules to define exactly which users can see and change which parts of your system.
Creating Conditional Permissions
A permission can include an optional condition that narrows when it applies. Conditions are evaluated against the requesting user's attributes, so the same rule can behave differently depending on who is asking.
Example Conditions
Role Hierarchy
Roles can inherit from other roles. This creates a hierarchy where a parent role automatically includes all permissions from the roles beneath it.
Permissions flow down the role hierarchy. If you assign a user the Administrator role, they automatically receive all permissions from the Engineer, Operator, and Viewer roles.
Duties: Areas of Responsibility
Responsibilities define the domains, zones, or functional areas a user is accountable for. Unlike permissions, which control access, responsibilities indicate what a user is accountable for.
Example Responsibilities
Responsibilities are assigned through roles, or directly to a user for session-specific duties. A user's effective responsibilities combine both their role-based and session-selected responsibilities.
Comprehensive Auditing
ControlBird provides multiple audit mechanisms to track who did what, when, and where. This is essential for compliance, troubleshooting, and security investigations.
Change History
Every change is recorded with full context:
Alarm History
Alarm events capture operator actions for compliance:
Historian
Time-series history with configurable retention:
User Access Tracking
Login activity and account security:
Viewing Audit Data
You can inspect audit data with the cb-cli command-line tool, or by reading fields directly in the Database Browser.
# Read a field with metadata (shows the last writer and timestamp)
cb-cli read "/Devices/Thermostat" "Temperature" --metadata
# Output includes:
# Value: 72.5
# Timestamp: 2024-01-15T14:32:01Z
# WriterId: User:adminReal-Time Notifications Include Writer ID
When you subscribe to field changes, each notification also carries the identity of whoever made the change. Your UI or scripts can use this to show who modified a value in real time.
Best Practices
Create a base "Viewer" role and build up from it. Changes to the base propagate automatically.
Use data permissions to control access to your system's data, and feature permissions to control app features. Don't conflate the two.
Responsibilities should reflect actual job functions, not just copy permissions.
Set how much change history is kept to match your compliance requirements.
Troubleshooting
Permission is denied but the user has the right role
Check these in order:
- Session refresh: the user may need to log out and back in after role changes
- Condition: if the permission has a condition, confirm the user's attributes satisfy it
- Field coverage: verify the permission covers the specific field, not just the type
- Target match: a permission can target a type of item or a specific item, so make sure it matches what the user is accessing
How do I see who made a specific change?
Use cb-cli read with the --metadata flag to see who last changed a field, or read the field in the Database Browser. For alarm actions, the alarm itself records who acknowledged or shelved it.
Responsibilities aren't showing for a user
- Verify the role includes the responsibility
- Check that the user has selected that role as their active role
- Confirm the user's effective responsibilities, which combine their role-based and session-selected responsibilities
A condition never grants access
- Attribute names and text values are case-sensitive, so match them exactly
- Use
cb-clito check the user's actual attribute values - Test with an empty condition first to confirm the base permission works