Overview of IAM Conditions

This page describes the Conditions feature of Identity and Access Management (IAM). You can use IAM Conditions to define and enforce conditional, attribute-based access control for Google Cloud resources.

With IAM Conditions, you can choose to grant access to principals only if specified conditions are met. For example, you could grant temporary access to users so they can resolve a production issue, or you could grant access only to employees making requests from your corporate office.

Conditions are specified in the role bindings of a resource's allow policy. When a condition exists, the access request is granted only if the condition expression evaluates to true. Each condition expression is a set of logic statements that specify one or more attributes to check.

Allow policies with conditions

Allow policies contain one or more role bindings, which have the following structure:

"bindings": [
  {
    "role": ...,
    "members": ...,
    "condition": ...
  },
  ...
]

The condition object is optional, and each role binding can contain zero or one condition. If a role binding does not have a condition object, the principals in that role binding always have the specified role on the resource.

Only some resource types accept conditions in role bindings. However, you can grant conditional access to other resource types by granting roles at the organization or project level.

The condition object has the following structure:

"condition": {
    "title": ...,
    "description": ...,
    "expression": ...
}

The condition's title is required, but the description is optional. Both the title and description are purely informational fields to help you identify and describe the condition.

The expression field is required. It defines an attribute-based logic expression using a subset of the Common Expression Language (CEL). The condition expression can contain multiple statements; each statement evaluates one attribute. Statements are combined using logical operators, following the CEL language specification.

To learn how to add, modify, and remove conditional role bindings, see Managing conditional role bindings.

CEL for conditions

Common Expression Language, or CEL, is the expression language used to specify an expression in IAM Condition. It is tailored to express attribute-based logic expressions. For more information, see the CEL spec and its language definition.

In IAM Conditions, a subset of CEL is used to make boolean authorization decisions based on attribute data. In general, a condition expression consists of one or more statements that are joined by up to 12 logical operators (&&, ||, or !). Each statement expresses an attribute-based control rule that applies to the role binding, and ultimately determines whether access is allowed.

IAM Conditions use the following CEL features:

  • Variables: Conditions use variables to express a given attribute, such as request.time (of type Timestamp) or resource.name (of type String). These variables are populated with value based on the context at runtime.
  • Operators: Every data type, such as Timestamp or String, supports a set of operators that can be used to create a logic expression. Most commonly, operators are used to compare the value contained in a variable with a literal value, such as resource.service == "compute.googleapis.com". In this example, if the input value of resource.service is compute.googleapis.com, then the expression evaluates to true.
  • Functions: A function is a "compound" operator for data types that support more complex operations. In condition expressions, there are predefined functions that can be used with a given data type. For example, request.path.startsWith("/finance") uses a String prefix match function, and evaluates to true if the value of request.path contains a matching prefix, such as "/finance".
  • Logical operators: Conditions supports three logical operators that can be used to build complex logic expressions from simple expression statements: &&, ||, and !. These logical operators make it possible to use multiple input variables in a condition expression. For example: request.time.getFullYear() < 2020 && resource.service == "compute.googleapis.com" joins two simple statements, and requires both statements to be met in order to produce a true overall evaluation result.

For more information about supported variables, operators, and functions, see the attribute reference.

Condition attributes

Condition attributes are based on the requested resource—for example, its type or name—or on details about the request—for example, its timestamp or destination IP address.

Resource attributes

You can use resource attributes to write conditions that evaluate the resource in the access request. The attributes that you can evaluate include the following:

  • The resource type
  • The resource name
  • The Google Cloud service being used
  • The tags attached to the resource

For a complete list of resource attributes, see the resource attributes reference.

To learn how to use resource attributes to configure resource-based access, see Configuring resource-based access.

Example expressions

Allow access to Compute Engine VM instances, but no other type of resource:

resource.type == "compute.googleapis.com/Instance"

Allow access to Cloud Storage resources, but no other service's resources:

resource.service == "storage.googleapis.com"

Allow access only to Cloud Storage objects inside a specific bucket:

resource.type == "storage.googleapis.com/Object" &&
resource.name.startsWith("projects/_/buckets/exampleco-site-assets/")

Allow access to Google Cloud resources that have the tag env: prod:

resource.matchTag('123456789012/env', 'prod')

Request attributes

You can use request attributes to write conditions that evaluate details about the request, such as the following:

  • The access level
  • The date and time
  • The destination IP address and port (for IAP TCP tunneling)
  • The expected URL host/path (for IAP)

Example access level expression (for IAP only)

In the following example, the organization defines an access level, CorpNet, that limits access to the range of IP addresses where traffic enters and exits a corporate network. Access is allowed only if the request meets the CorpNet access level:

"accessPolicies/199923665455/accessLevels/CorpNet" in
request.auth.access_levels

Your organization defines access levels based on attributes of the request, such as origin IP address, device attributes, the time of day, and more. For more details, see the Access Context Manager documentation.

Example API attribute expression

Allow a user to grant and revoke only the Billing Account Administrator (roles/billing.admin) role:

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', [])
                 .hasOnly(['roles/billing.admin'])

To learn more about using API attributes to limit role granting, see Setting limits on granting roles.

Example date/time expressions

Allow access temporarily until a specified expiration date/time:

request.time < timestamp("2021-01-01T00:00:00Z")

Allow access only during specified working hours, based on the time zone for Berlin, Germany:

request.time.getHours("Europe/Berlin") >= 9 &&
request.time.getHours("Europe/Berlin") <= 17 &&
// Days of the week range from 0 to 6, where 0 == Sunday and 6 == Saturday.
request.time.getDayOfWeek("Europe/Berlin") >= 1 &&
request.time.getDayOfWeek("Europe/Berlin") <= 5

Allow access only for a specified month and year, based on the time zone for Berlin, Germany:

request.time.getFullYear("Europe/Berlin") == 2020
request.time.getMonth("Europe/Berlin") < 6

To specify a timestamp, use RFC 3339 format. To specify a time zone, use the identifiers in the IANA Time Zone Database.

For more details about date/time expressions, see the CEL specification.

To learn how to use date/time expressions to configure temporary access, see Configuring temporary access.

Example destination IP/port expressions (for IAP TCP tunneling)

Allow access to an internal destination IP address or port number:

destination.ip == "14.0.0.1"
destination.ip != "127.0.0.1"
destination.port == 22
destination.port > 21 && destination.port <= 23

Example forwarding rule expressions

Allow access for a principal if the request is not creating a forwarding rule, or if the request is creating a forwarding rule for an internal Google Cloud load balancer:

!compute.isForwardingRuleCreationOperation() || (
  compute.isForwardingRuleCreationOperation() &&
  compute.matchLoadBalancingSchemes([
    'INTERNAL', 'INTERNAL_MANAGED', 'INTERNAL_SELF_MANAGED'
  ])
)

Example URL host/path expressions (for IAP)

Allow access only for certain subdomains or URL paths in the request:

request.host == "hr.example.com"
request.host.endsWith(".example.com")
request.path == "/admin/payroll.js"
request.path.startsWith("/admin")

For details about load-balancing schemes, see Using IAM Conditions on Google Cloud load balancers.

Example expression with different types of attributes

Allow access if the request is made during a specific time, matching a resource name prefix, with the desired access level, and for a specific resource type:

request.time > timestamp("2018-08-03T16:00:00-07:00") &&
request.time < timestamp("2018-08-03T16:05:00-07:00") &&
((resource.name.startsWith("projects/project-123/zones/us-east1-b/instances/dev") ||
 (resource.name.startsWith("projects/project-123/zones/us-east1-b/instances/prod") &&
  "accessPolicies/34569256/accessLevels/CorpNet" in request.auth.access_levels)) ||
 resource.type != "compute.googleapis.com/Instance")

What's next