Policies and Permission Resolution

All authorization in Monte Carlo is based on permissions. A permission represents an action in the system that is controlled by authorization. These permissions are asserted on entry points into the system through APIs and also in the application UI to, for example, hide, show, disable certain features based on a user's effective permissions.

Permissions are organized hierarchically under resources, which loosely map to features and feature areas in Monte Carlo. You can review the full list of IAM resources and permissions here.

Permissions are granted or denied via roles, which are assigned to authorization groups. Users are assigned to these groups. A user's effective permissions are the combination of all permissions granted/denied by the roles in their groups, following the rules laid out in specificity and policy resolution below. Additionally, authorization groups may be scoped to specific domains, further limiting access to particular subsets of assets surfaced in Monte Carlo from customer systems.

See the authorization overview for a broader introduction.

graph LR
    U[User] -->|member of| G[Authorization Group]
    G -->|assigned| R1[Role A]
    G -->|assigned| R2[Role B]
    R1 -->|policy statement| P1["dashboard/*: allow"]
    R1 -->|policy statement| P2["dashboard/edit: deny"]
    R2 -->|policy statement| P3["monitors/*: allow"]
    G -.->|optionally scoped to| D[Domain]

This topic covers how permissions are granted, denied, and resolved.

Policy statements

A role in Monte Carlo is a named set of policy statements. Each policy statement specifies a permission path and an effect — the path identifies which permission(s) the policy applies to, and the effect specifies whether those permissions are allowed or denied. Example: dashboard/edit: allow would allow editing/modifying dashboards. See Managing roles for details on built-in and custom account roles.

Permission effects

We support two permission effects: allow and deny.

Note: Monte Carlo uses a secure-by-default model. Omitting a permission from a role implicitly denies it — unless another role in one of the user's authorization groups grants it.

Permission types

Permissions have types that characterize the kind of action involved.

  • read - used for non-modifying/read-only operations like viewing data, downloading reports, etc.
  • write - used for operations that modify state/data in Monte Carlo, such as creating, updating, deleting, etc.

The next section covers how to use these in policy statements.

Convention: Most IAM resources in Monte Carlo will have an access permission, which is of read-type, and an edit permission, which is of write-type. These are used for most operations in Monte Carlo. If there are more discrete operations that we know are useful to control separately, we will have other such permissions defined and assigned the applicable type, so they all may be controlled using the type wildcards. If you find yourself wanting to discretely authorize particular operations that are not represented by a specific permission, please reach out to support and let us know.

Using permission paths

When you specify a policy statement in a role definition, you use a permission path. The path reflects the IAM resource hierarchy. This is useful because you can use wildcards (either * for all or read/write for specific types of actions) to apply the effect to multiple permissions at once for the given resource, without having to list each permission individually, making for more readable and maintainable role definitions.

For example, the dashboard/* path will apply to all dashboard-related permissions, and the dashboard/write path will apply to all write-type dashboard permissions.

You also have the option to control a specific permission, such as dashboard/edit-their-own, which would only apply to that one permission (in this case, the ability to edit one's own dashboards).

Important: Permission paths determine specificity, which drives resolution when a user has multiple roles. The more specific the path, the higher its precedence — a direct permission (dashboard/edit-their-own) takes precedence over a wildcard (dashboard/* or dashboard/write). See specificity and policy resolution for details.

Policy resolution rules

These are the operating principles in Monte Carlo policy resolution:

  1. secure by default - omitting a permission equates to denying it--for a given role
  2. most specific wins - if a wildcard policy is specified at a higher level, a more specific policy will override it
  3. deny beats allow - if two policy statements are specified at the same specificity level, deny will win

There are two ways that policies can compete with each other:

  1. within the same role: you may define a general policy at a higher level (ex: monitors/*), and then you may override that for specific sub-resources and/or permissions (ex: monitors/data-sampling/*)
  2. across roles or authorization groups: if more than one role is assigned a group, or a user is in multiple groups, we must reconcile their individual policies according to the rules above

In all cases, the same rules are applied.

Policy statement specificity

Policy statement specificity is tied to the resource hierarchy.

Example:

iam-role:
  name: some-role
  permissions:
    settings/*: allow
    # Except:
    settings/users/write: deny
    settings/domains/write: deny

Here, all settings actions are allowed except write-type actions on users and domains. The * wildcard applies to all action types, while write and read limit the effect to that specific action type within the resource.

The inverse approach also works:

iam-role:
  name: some-role
  permissions:
    settings/*: deny
    # Except:
    settings/domains/read: allow

Here, the only thing allowed under settings are read-type domains actions, because the allow is more specific than the top-level deny.

Multiple roles

The examples above show resolution within a single role. When a group has multiple roles, the same rules apply with one addition: allow grants are cumulative across roles. A deny that is not overridden by a more-specific allow always wins--so you can accidentally deny things you don't intend to if there are not more specific allows. (Use explicit denies sparingly due to their overriding force.)

Multiple groups

Users can belong to multiple groups. Resolution works hierarchically:

  1. For each group, its roles are resolved and combined into a group policy
  2. For each user, all their group policies are combined into a user policy

At every level, the same rules apply: secure by default (accumulated across roles/groups), most specific wins, and deny beats allow.

Debugging Authorization

Check out our Debugging Authorization topic for info on how to use our built-in tools to help solve problems with your authorization configurations.