Role-Based Access Control (RBAC)
Role-Based Access Control (RBAC) gives Workspace administrators more granular control over who can access and modify resources.
This is especially useful for protecting production while allowing broader access to development and staging.
Modal’s RBAC system operates at two levels:
- Workspace Roles control overall Workspace permissions.
- Environment Roles control access to specific RBAC restricted Environments.
Workspace Roles
Modal Workspaces organize Modal Apps and other resources for a group of users. These roles control access at the level of the entire Workspace.
All Workspace Members have one of three Roles that determine their overall permissions:
- Owner — Full read-write access to everything in the Workspace, including billing, Workspace management, and all Environments. Can assign any Role to other members.
- Manager — Same as Owner, but cannot modify the Owner Role.
- Member — Can deploy and manage Apps, but cannot access billing, Workspace management, or other Workspace settings.
Environment Roles
Modal Environments isolate Modal Apps and other resources from one another within a Workspace.
Environments can be set as restricted to enable RBAC at the Environment level. Restricted Environments introduce two specific Roles for more granular control:
- Viewer — Read-only access to resources in the Environment, including dashboards, logs, metrics, app and function configuration.
- Contributor — Full read and write access to the Environment. Workspace Owners and Managers automatically have Contributor access to all restricted Environments.
Setting up restricted Environments
To enable RBAC for specific Environments:
Enable RBAC: This requires an Enterprise plan. See our pricing page for more information.
Create a restricted Environment: Navigate to your Workspace’s Environment Management page and click Add Environment.
Configure Environment Roles: Once an Environment is restricted:
- All Workspace Members automatically get Viewer access.
- Workspace Owners and Managers automatically get Contributor access.
- You can assign specific users or service users Contributor access.
Manage access: Use the Manage button next to any restricted Environment to:
- Add users or service users with specific Roles
- Change existing Roles
- Remove access
Default access by actor
| Workspace Role | Unrestricted Environment Default | Restricted Environment Default |
|---|---|---|
| Workspace Owner | Contributor | Contributor |
| Workspace Manager | Contributor | Contributor |
| Workspace Member | Contributor | Viewer by default, or Contributor if explicitly assigned |
| Service user / service token | Contributor | Viewer by default, or Contributor if explicitly assigned |
In restricted Environments, you can grant specific users or service users Contributor access for deployment and management workflows.
Service users and service tokens
Service users are programmatic identities authenticated with API tokens. They are useful for CI/CD pipelines, deployment bots, and other machine-to-machine communication needs.
Unlike human users, service users do not have a Workspace-level role. Their access is controlled through Environment Roles.
| Use case | Recommended identity | How access works |
|---|---|---|
| Interactive development or manual management | Human user | Access is based on the user’s Workspace Role, plus any Environment Role for restricted Environments |
| Automation in CI/CD or deployment workflows | Service user authenticated with a service token | Access is based only on the service user’s Environment Role |
| Deploying to an unrestricted Environment | Human user or service user | Both have Contributor access |
| Deploying to a restricted Environment | Human user or service user with explicit Contributor access | Viewer by default; must be granted Contributor to deploy or manage resources |
This makes service users the recommended way to let automation deploy to a restricted Environment without granting broad Workspace permissions.
Cross-Environment access
Restricted Environments prevent app and task identities in other Environments from accessing resources inside the restricted Environment. For more detail, see Cross-Environment Lookups.
In practice, this means a task can access objects in its own Environment and other unrestricted Environments, but code running in another Environment cannot use APIs such as modal.App.lookup(), Secret.from_name(), or Volume.lookup() to reach into a restricted Environment.
This prevents privilege escalation from a less trusted Environment into a more sensitive one.
Cross-Environment behavior for app and task identities
Access checks are evaluated against the target Environment. That means workloads running inside a restricted Environment can still access objects in an unrestricted Environment, but workloads running outside a restricted Environment cannot reach into it.
| Source Environment | Target Environment | Cross-Environment access |
|---|---|---|
| Unrestricted | Unrestricted | Allowed |
| Unrestricted | Restricted | Denied |
| Restricted | Unrestricted | Allowed |
| Restricted | Restricted | Denied |
Same-Environment access is unaffected by these cross-Environment rules.
Example: inbound vs. outbound access
Suppose you have two Environments:
prod— restrictedtest— unrestricted
A task running in test cannot look up secrets, volumes, or Apps in prod.
A task running in prod can still access objects in test, because test is not restricted.
If both prod and test are restricted, then tasks in one cannot access objects in the other.
Protecting production secrets with restricted Environments
A common RBAC setup is to place production secrets in a restricted production Environment and grant Contributor access only to the human users and service users that should be allowed to deploy or manage production.
| Scenario | Result |
|---|---|
Developer in dev tries to edit a secret in restricted prod | Denied |
CI service user with Contributor access to restricted prod deploys to prod | Allowed |
Task running in prod reads a secret in prod | Allowed |
Task running in prod accesses objects in unrestricted test | Allowed |
This setup lets you keep development and testing more open while protecting production resources, including secrets, from accidental or unauthorized access.
Common access patterns
| Pattern | Allowed? | Notes |
|---|---|---|
| Workspace Member views logs in a restricted Environment | Yes | Workspace Members have Viewer access by default in restricted Environments |
| Workspace Member deploys to a restricted Environment | No | Contributor access is required to deploy or modify resources |
| Workspace Owner or Manager deploys to a restricted Environment | Yes | Owners and Managers automatically have Contributor access |
| Service user deploys to a restricted Environment | Yes, if explicitly granted Contributor | Service users have Viewer access by default in restricted Environments |
Task running in dev reads a secret in restricted prod | No | Cross-Environment access into a restricted Environment is denied |
Task running in restricted prod accesses objects in unrestricted test | Yes | Cross-Environment access is allowed when the target Environment is unrestricted |
| User views dashboards or app details in a restricted Environment | Yes | Viewer access includes read-only views such as dashboards, logs, metrics, and configuration |
| Task accesses resources in its own Environment | Yes | Same-Environment access is unaffected by cross-Environment restrictions |
FAQ
Can I make Environments completely private?
No. Workspace Members will always have at least Viewer access to restricted Environments. Fully private Environments are planned for the future.
How do service tokens work with restricted Environments?
Service tokens authenticate service users. In restricted Environments, service users have Viewer access by default unless you explicitly assign them Contributor access. This allows automated systems and CI/CD pipelines to deploy and manage production without granting broad Workspace permissions.
Can I use modal.App.lookup() across different restricted Environments?
No. Apps cannot look up, read from, or write to objects in a different restricted Environment.
Can code running in a restricted Environment access other Environments?
Yes, but only when the target Environment is not restricted. A restricted Environment blocks access into it from other Environments.