Overview
A well-designed role hierarchy makes permission management straightforward. A poorly designed one creates confusion, security gaps, and administrative overhead. This guide walks through designing a role structure that matches your organization's actual access needs, and then wiring it up using Mango by Radix IoT's role inheritance so the structure is enforced rather than merely documented.
Prerequisites
- Mango 4.x or 5.x with admin access to create and edit roles
- A list of the people and systems that will use Mango, and what each needs to do
- Test user accounts you can log in as, or the ability to switch user from an admin account
- Familiarity with object-level read/edit/set permissions — see How to Set Object-Level Permissions on Dashboards and Data Points
Step 1: Identify User Groups
Before creating roles, list the types of people who will use Mango and what they need to do:
| User Group | What They Need |
|---|---|
| System administrators | Full access to all configuration, users, modules |
| Site engineers | Configure data sources, points, and event detectors for their site |
| Operators | View dashboards, acknowledge alarms, set points, export data |
| Executives/viewers | View dashboards and reports only — no configuration changes |
| External contractors | Limited view access to specific devices during a project |
Step 2: Map Access Requirements
For each user group, determine what Mango objects they need access to:
| User Group | Data Points | Dashboards | Config Pages | Reports | Events |
|---|---|---|---|---|---|
| System admin | Read + Set (all) | Read + Edit (all) | All | All | All |
| Site engineer | Read + Set (their site) | Read + Edit (their site) | Data sources, points | Their site | Their site |
| Operator | Read + Set (their site) | Read only | None | View only | Acknowledge |
| Viewer | Read only | Read only | None | View only | View only |
| Contractor | Read only (specific devices) | Specific dashboards | None | None | None |
Step 3: Define Roles
Mango has exactly three built-in roles — superadmin, user and anonymous. There is no built-in administrator role beyond superadmin, so an admin role is only ever one you create yourself. Every authenticated account also holds user, so a permission naming user is open to everyone who can log in.
Create roles that match the access patterns identified above. Common patterns:
Pattern A: Flat Hierarchy (Small Team)
Roles:
- superadmin (built in -- do not create your own "admin")
- operator (view + set all points, view dashboards)
- viewer (view dashboards only)
Best for: Single-site, small team, simple access needs.
Pattern B: Site-Based Hierarchy
Roles:
- superadmin (built in)
- engineer (create data sources; edit the ones granted to them)
- site-a-operator (view + set Site A points)
- site-b-operator (view + set Site B points)
- global-viewer (view all dashboards, no set)
Best for: Multi-site deployments where operators are site-specific.
Pattern C: Multi-Tenant
Roles:
- system-admin (manages the Mango instance)
- tenant-a-admin (manages Tenant A's config)
- tenant-a-operator (operates Tenant A's equipment)
- tenant-a-viewer (views Tenant A's dashboards)
- tenant-b-admin, tenant-b-operator, tenant-b-viewer (same for Tenant B)
Best for: Managed services where one Mango instance serves multiple customers.
Warning
A tenant “admin” role cannot administer Mango itself. At 4.x and 5.x every page under Administration is superadmin-only and cannot be delegated, so a tenant admin is a role that owns its tenant’s objects — points, dashboards, watch lists, reports — while instance configuration stays with superadmin. Plan the boundary that way or the pattern will not hold.
Step 4: Configure Role Inheritance
Mango roles are not a flat list. Each role carries a set of inherited roles, stored as role-to-role links rather than on any user record. Mango walks those links recursively when it checks a permission, so the chain is resolved at check time while the structure lives on the roles.
Which Way Inheritance Runs
This is the part that trips people up, so state it precisely:
Note
A role inherits the roles listed on it. Anyone holding that role is treated as holding the inherited roles too, and therefore receives everything granted to them.
Permissions flow upward, from the inherited role to the role that inherits it. If engineer inherits operator, then every engineer automatically gets everything granted to operators. The reverse is not true: operators gain nothing from the engineer role.
Put the broad, low-privilege role at the bottom and have the more privileged roles inherit it. Grant object permissions to the lowest role that should have them, and let the roles above pick them up.
viewer <- granted read on dashboards
^ inherited by
operator <- adds set permission on points
^ inherited by
engineer <- adds data source configuration
An engineer holds: engineer + operator + viewer
An operator holds: operator + viewer
A viewer holds: viewer
Single and Multiple Inheritance
The inherited set is a set, not a single parent, so a role can inherit several roles at once. A site-a-supervisor role can inherit both site-a-operator and global-viewer and hold the union of what both grant. Inheritance also chains: if engineer inherits operator and operator inherits viewer, an engineer holds all three.
How to Configure It
- Create the lower-privilege roles first, so they exist to be inherited
- Open the role that should sit higher in the hierarchy
- Add the lower roles to its inherited roles
- Save, and repeat up the chain
Assign users only the single role that matches their function. Because the hierarchy resolves the rest, you do not need to stack viewer, operator, and engineer onto one user by hand.
Effective Permissions
When Mango evaluates whether a user may do something, it resolves the user's roles together with every role reachable through inheritance, and checks that whole set against the object's permission. So a permission naming only viewer is satisfied by any user whose role inherits viewer, even though viewer was never assigned to them directly.
Warning
Inheritance broadens access quietly. Granting a new permission to a low-level role hands it to every role above, and adding an inherited role to an existing role instantly widens access for everyone already holding it. Neither change touches a single user record, so nothing in the user list signals what happened. Re-test after any inheritance change.
Step 5: Assign Roles to Objects
Once roles are defined, assign them to Mango objects:
- Data points: set the read and set permissions to the appropriate roles. To do it in bulk, use Data integration > Bulk data point edit — note that page is superadmin only, so an engineer role cannot do its own bulk re-permissioning
- Dashboards: Set Read and Edit permissions per dashboard
- Watch lists: Set Read and Edit permissions
- Reports: Set Read and Edit permissions
- System permissions: grant named capabilities — creating data sources, viewing users, editing the UI menu and so on — at Access management > System permissions. They are not a way to hand out administration pages: see the caution below
Step 6: Test the Hierarchy
Test the inheritance chain explicitly, not just the roles in isolation. The failure mode you are hunting for is a user who has more access than intended because a role somewhere below them was granted something new.
- Create a test user for each role, holding only that one role
- Log in as each test user, or use Switch to user from the user's More options menu — a superadmin-only action, and you cannot use it on yourself
- Verify they can see what they should see
- Verify they cannot see what they shouldn't see
- Verify inheritance flows the intended direction: a user holding only the higher role should reach objects granted to the lower role, and a user holding only the lower role should not reach objects granted to the higher one
- Grant a throwaway permission to your lowest role, confirm every role above it picks the permission up, then remove it — this proves the chain is wired as you drew it
- Document the results
Verification
- ☐ Every role's inherited set matches the hierarchy diagram you designed
- ☐ Users are assigned a single functional role, not a manual stack of every level
- ☐ A user with only the top role reaches everything granted to the roles beneath it
- ☐ A user with only a bottom role reaches nothing granted to the roles above it
- ☐ Any role using multiple inheritance grants the union of its inherited roles, and nothing beyond it
- ☐ Object permissions are granted to the lowest appropriate role rather than repeated at every level
- ☐ The hierarchy, including the inherited sets, is written down somewhere the next administrator will find it
Common Mistakes
| Mistake | Impact | Fix |
|---|---|---|
| Too many roles | Confusion about which role to assign; maintenance burden | Consolidate roles with similar access patterns |
| Too few roles | Users get more access than needed | Split roles when access requirements clearly diverge |
| Per-user roles | Doesn't scale; creates orphaned roles when users leave | Create roles for functions, and use inheritance to compose them |
| Inheritance pointed the wrong way | Privileged users lose access, or low-privilege users gain it | The high-privilege role inherits the low-privilege one, never the reverse |
| Granting the same permission at every level | Duplicated grants drift apart and inheritance stops meaning anything | Grant at the lowest role that should have it and let higher roles inherit |
| Not re-testing after an inheritance change | Access widens silently, with nothing in the user records to show it | Re-run the role tests whenever an inherited set or a low-level grant changes |
| Missing a permission layer | Users get blank dashboards despite holding the right role | Check every object in the path — the dashboard, any watch list or data source it depends on, and the underlying data points all carry their own permissions |
| No documentation | New admins don't know what each role is for | Maintain a role reference table that includes the inherited sets |
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| A user holding a high-level role cannot reach objects granted to a lower role | The inheritance is missing, or was configured on the wrong role | Open the high-level role and confirm the lower role is in its inherited set. Remember the higher role inherits the lower one, never the reverse |
| Users suddenly have more access than intended | A permission was granted to a low-level role, or a role was added to an inherited set. Both propagate upward instantly | Review recent changes to low-level roles and to inherited sets, then re-run the role tests |
| Removing a role from a user changes nothing | The user still reaches the permission through another role that inherits it | Trace the full inherited set for each of the user's remaining roles, not just the role you removed |
| A permission granted to a role has no effect | The permission was set on the object but the user's roles do not reach that role by inheritance | Check the object's permission against the user's resolved role set, including inherited roles |
| Role cannot be renamed or its XID changed | Role names and XIDs are fixed once created | Create a correctly named role, move the permissions and inheritance across, then retire the old one |
| The hierarchy behaves inconsistently between users | Users have been assigned stacked roles by hand in addition to the hierarchy | Assign one functional role per user and let inheritance supply the rest |
Role Naming Conventions
Pick both carefully, because neither can be changed afterwards — Mango rejects a rename outright, so a badly named role has to be replaced. Mango's own XID prefix for roles is ROLE_.
- Use lowercase with hyphens:
site-a-operator - Include the scope:
global-viewervssite-a-viewer - Include the function:
operator,engineer,admin,viewer - Be consistent: if one site is
site-a-operator, don't name anothersiteb_ops
Summary
Design your role hierarchy by first listing user groups and their access needs, then creating the minimum set of roles to serve those needs. Turn that design into a real hierarchy using inherited roles: put the broad, low-privilege role at the bottom, grant object permissions there, and have each more privileged role inherit the one below it so permissions flow upward. Assign users the single role that matches their function and let inheritance do the rest. Start simple — you can always add roles later. Test every role by logging in as a user holding only that role, check the inheritance direction in both directions, and re-test whenever an inherited set changes. Document the hierarchy, inherited sets included, so future administrators understand the structure.