Access Control
Managing subsidiary and project access in Alpha
Access Control
Alpha uses a layered access control system that combines role-based permissions with resource-level access controls. This allows fine-grained control over what users can see and do within the system.
Access Control Layers
Alpha's access control system has three layers:
| Layer | Description |
|---|---|
| Roles | Define what actions a user can perform (permissions) |
| Full Access | Bypasses all resource-level restrictions |
| Resource Access | Controls which subsidiaries and projects a user can access |
Roles control what a user can do. Resource access controls where they can do it.
Full Access
Users with Full Access can access all subsidiaries and projects without explicit assignment.
What Full Access Means
Full Access is granted in any of three ways. The backend treats all three as equivalent for resource-scoping checks (see AccessControlService.hasFullAccess()):
| Source | Description |
|---|---|
| Super Admin | System-level role; bypasses every check |
| Tenant Admin permission | Granted via a role that includes TENANT_ADMIN |
| Full Access flag | Per-user boolean on the tenant membership (hasFullAccess) |
Any of these grants:
- Access to all subsidiaries (bypasses
canAccessSubsidiary) - Access to all projects (bypasses
canAccessProject)
Full Access vs Tenant Admin
The Full Access flag and the Tenant Admin permission are functionally equivalent in the backend for resource-scoping checks. They are kept separate so that:
- A user can be granted broad resource access (Full Access flag) without being given administrative permissions like managing other users or roles
- Administrative roles (Tenant Admin) automatically get full resource access without needing the flag toggled separately
Some UI permission gates check only the explicit Tenant Admin permission and do not honor the Full Access flag. If a user with Full Access sees a button greyed out that they should be able to use, this is the cause — see Troubleshooting below.
When Full Access Applies
- Users with the Tenant Admin permission automatically have full access
- Administrators can grant full access independently via the user's access settings (this sets the
hasFullAccessflag without granting administrative permissions)
Managing Full Access
- Go to Administration > Users
- Open the user
- Click Manage Access
- Toggle Full Access on or off
Use Full Access sparingly. It's best reserved for system administrators who genuinely need access to all resources.
Subsidiary Access
Subsidiary access controls which business entities a user can work with.
How Subsidiary Access Works
Users without full access must be explicitly granted access to subsidiaries. Subsidiary access has an important characteristic: hierarchical inheritance.
Access Inheritance
Subsidiaries can be organized in a parent-child hierarchy. When a user has access to a parent subsidiary, they automatically gain access to all its children.
Parent Company (access granted)
├── Division A (inherited access)
│ ├── Branch 1 (inherited access)
│ └── Branch 2 (inherited access)
└── Division B (inherited access)
└── Branch 3 (inherited access)In this example, granting access to "Parent Company" gives the user access to all six entities.
Direct vs Inherited Access
| Access Type | Description |
|---|---|
| Direct | User was explicitly granted access to this subsidiary |
| Inherited | User has access because they have access to a parent subsidiary |
When viewing users with subsidiary access, inherited access is indicated with a badge showing which parent it was inherited from.
Granting Subsidiary Access
From the User
- Go to Administration > Users
- Open the user
- Click Manage Access
- Go to the Subsidiary Access tab
- Select subsidiaries from the tree view
- Save
From the Subsidiary
- Go to Administration > Subsidiaries
- Open the subsidiary
- Click Manage Users
- Add or remove users
- Save
Access Inheritance Behavior
When you grant access to a parent:
- Child subsidiaries become accessible automatically
- Child subsidiaries appear disabled in the selection (cannot be individually toggled)
- Removing parent access removes access to all children (unless directly assigned)
To give a user access only to a specific child subsidiary, grant access to that child directly rather than the parent.
Subsidiary Access Examples
Example 1: Regional Manager
A regional manager needs access to all branches in their region:
- Grant access to the regional parent subsidiary
- All branches inherit access automatically
- New branches under that region automatically accessible
Example 2: Branch-Specific User
A warehouse user only works at one location:
- Grant access only to their specific branch
- They cannot see other branches or the parent
Project Access
Project access controls which construction projects a user can view and work with.
How Project Access Works
Unlike subsidiaries, projects do not have hierarchical inheritance. Each project must be explicitly assigned to users who need access.
Projects have no inheritance. Every project access must be explicitly granted.
Granting Project Access
From the User
- Go to Administration > Users
- Open the user
- Click Manage Access
- Go to the Project Access tab
- Select projects from the list
- Save
From the Project
- Open the project
- Click Manage Access
- Add or remove users
- Save
Project Access Examples
Example 1: Project Manager
A project manager oversees three specific projects:
- Grant access to each of the three projects individually
- They can only see and manage those projects
Example 2: Company-Wide Viewer
A finance user needs to see all projects for reporting:
- Grant Full Access instead
- Or grant access to each project as needed
Access Control Best Practices
Design Principles
| Principle | Implementation |
|---|---|
| Least Privilege | Grant minimum access needed for the job |
| Explicit Assignment | Prefer explicit grants over broad access |
| Regular Review | Audit access quarterly |
| Hierarchy Use | Use subsidiary hierarchies to simplify management |
Common Patterns
Department-Based Access
Company
├── Sales Division (Sales team access)
├── Operations Division (Operations team access)
└── Finance Division (Finance team access)Region-Based Access
Company
├── North Region (Regional staff access)
├── South Region (Regional staff access)
└── Central Region (Regional staff access)Project-Based Teams
For project teams:
- Create a role with appropriate permissions
- Assign the role to team members
- Grant project access to each team member
Access Auditing
Regular access reviews should verify:
- Users have appropriate access for their current role
- Former employees are deactivated
- Project access is removed when projects complete
- Subsidiary access matches current responsibilities
Combining Roles and Access
Access is determined by the combination of roles and resource access:
| Has Permission? | Has Resource Access? | Result |
|---|---|---|
| Yes | Yes | Can perform action |
| Yes | No | Cannot see resource |
| No | Yes | Can see but not act |
| No | No | Cannot see or act |
Example:
A user with:
READ_PRODUCTSpermission- Access to Subsidiary A only
Can:
- View products in Subsidiary A
Cannot:
- View products in Subsidiary B (no access)
- Create products anywhere (no permission)
Troubleshooting Access Issues
User Can't See a Subsidiary
- Check if user has subsidiary access (direct or inherited)
- Check if user has full access
- Verify user status is Active
User Can't See a Project
- Check if user has project access
- Check if user has full access
- Verify user has appropriate role permissions
User Can See But Can't Edit
- Check role permissions
- User may have access but lack edit permissions
User Has Full Access But Button Is Disabled
A user with the Full Access flag may still see specific action buttons greyed out. This happens when a UI permission gate checks for the explicit Tenant Admin permission rather than calling the backend's hasFullAccess() helper.
Known examples:
- Approve stock transfer — gated on
TENANT_ADMINin the UI, even though the backend only requiresUPDATE_INVENTORY. A user with Full Access plusUPDATE_INVENTORYwould be allowed by the API but cannot trigger it from the UI.
Workarounds:
- Assign the user a role that includes the Tenant Admin permission (e.g.
BK_ADMINfor Burger King), or - Have a user that already holds Tenant Admin perform the action
If you encounter this on a screen not listed above, report it — the UI gate should be aligned with the backend check.