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 individual 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.
Every Environment has three Environment Roles that determine access to it:
- Contributor — Full read and write access to the Environment. Workspace Owners and Managers always have Contributor access.
- Viewer — Read-only access to resources in the Environment, including dashboards, logs, metrics, app and function configuration.
- No Access — No read or write access to the Environment.
Workspace Members default to Contributor, while service users default to No Access and must be granted a Role on each Environment they need. Setting an Environment as Restricted makes Members default to Viewer instead, and lets you switch specific Members between Viewer and Contributor.
Setting up restricted Environments
To set up a restricted Environment:
- Restrict the Environment: To create a new restricted Environment, use
modal environment create --restricted NAME. To restrict an existing unrestricted Environment, navigate to your Workspace’s Environment Management page in Settings, select the Environment, and click Make Restricted. - Roles apply: Once restricted, all Workspace Members default to Viewer, while Owners and Managers keep Contributor.
- Manage access: Use the Manage button next to the Environment to change specific Members between Viewer and Contributor.
Default access by actor
| Workspace Role | Unrestricted Environment Default | Restricted Environment Default |
|---|---|---|
| Workspace Owner | Contributor | Contributor |
| Workspace Manager | Contributor | Contributor |
| Workspace Member | Contributor | Viewer |
| Service user / service token | No Access | No Access |
Members can only be assigned an Environment Role in restricted Environments, but service users can be given a Role on any Environment — restricted or not — from their tokens settings or an Environment’s roles.
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 entirely 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 Environment | Human user or service user with Contributor access | Deploying requires Contributor access to the target Environment; grant the service user that Role on each Environment it deploys to |
This makes service users the recommended way to let automation deploy to a specific Environment without granting broad Workspace permissions.
Proxy tokens for Web Functions
Web Functions can be protected with proxy tokens, which authenticate inbound HTTP requests before they reach your function.
On workspaces with RBAC enabled, proxy tokens are scoped — each token is explicitly associated with one or more Environments, and will only be accepted for Web Functions deployed to those Environments. This prevents a token intended for a staging endpoint from being used to call a production one.
Creating a scoped proxy token
- Navigate to Settings → Proxy Tokens and click New Token.
- Copy the token ID and secret — the secret is only shown once.
- You will be prompted to select the Environments this token should be valid for.
- Use the Manage Environments button on any existing scoped token to update its Environment associations. Changes take effect immediately, so removing an Environment will instantly revoke access for any clients using that token to call endpoints in that Environment.
Scoped vs. workspace-wide tokens
| Token type | Who gets it | Valid for |
|---|---|---|
| Scoped | Workspaces with RBAC enabled | Only the Environments explicitly associated with the token |
| Workspace-wide | Workspaces without RBAC | Any Web Function in the workspace |
Existing workspace-wide tokens continue to work as-is. New tokens created on workspaces with RBAC enabled are scoped by default.
If RBAC is disabled on a workspace, scoped tokens fall back to workspace-wide access.
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 No Access by default and must be assigned Contributor to deploy |
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 |
| Scoped proxy token used on a Web Function in an associated Environment | Yes | Token must be explicitly associated with the target Environment |
| Scoped proxy token used on a Web Function in a non-associated Environment | No | Token is not valid for Environments it has not been associated with |
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. Service users default to No Access on every Environment, restricted or not, and cannot read or write to an Environment until you explicitly assign them the Viewer or Contributor Role. This lets automated systems and CI/CD pipelines 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.