Google Cloud: IAM Conditions
Tags: googlecloud, security, gcp, iam
Published: 2021-03-15 23:32:55

We can use IAM to control who has access to what within our project and who can do what to things like storage buckets, but what if we wanted to restrict *when* someone could do something or to *what* object in a bucket. That's where IAM Conditions come in to play.

## What are IAM Conditions ?

IAM conditions are one or more rules written in "CEL" or Common Expression Language. Each rule must evaluate as true before the defined access role associated with it is permitted.
These rules can specify the type of resource we want to control, time, date's and some string operations.

Here is a simple example:

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

Here we are expecting the resource type we're trying to use to be an instance ( which are part of the compute API ). If the resource we are trying to use is something else this condition will fail and our request will be denied.

There's more information about CEL and its specifications [here](https://github.com/google/cel-spec/blob/master/doc/langdef.md)

## Can you give some examples ?

Sure, here's one which will restrict access to a specific time period and between certain days:

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

When combined with `roles/compute.admin` it would restrict the user and/or group to only be granted the role during office hours ( Monday to Friday between 9am and 5pm ). 


Here's another that can be used to restrict what objects in a storage bucket can be manipulated:

```
resource.type == "storage.googleapis.com/Bucket" &&
resource.name.startsWith("projects/_/buckets/inputbucket-001/objects/example-folder")
```

When combined with the role `roles/storage.objectCreator` it would restrict the user and/or group so that its only able to create new objects in our bucket named `inputbucket-001` in the folder `example-folder`. Uploading to the root of the bucket or any other root level folder would be denied.



## Are there any limitations to using IAM conditions ?

Yes, there are some:

* They cannot be used with basic roles ( formally "primitive" ), `allUsers` or `allAuthenticatedUsers`

* They only work with certain services at the moment. Check the [documentation here](https://cloud.google.com/iam/docs/conditions-overview#resources) for more information.

* There is a maximum number of 12 logical operators in one condition expression

* There is a maximum of 20 role bindings for same role and same member

* There is a maximum of 100 conditional role bindings

Attempting to exceed these limits will return a fail message when you apply your change.

Also, conditional role bindings will not override role bindings with no conditions. If a user and/or group is bound to a role which does not have a condition, then the member always has that role. Adding the member to a conditional binding for the same role will have no effect


## Can this be applied via terraform ?

Yes! Here's an example directly from the [terraform documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member):

```hcl
resource "google_project_iam_member" "project" {
  project = "your-project-id"
  role    = "roles/firebase.admin"
  member  = "user:jane@example.com"

  condition {
    title       = "expires_after_2019_12_31"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
  }
}
```

As you can see from the `description` field any requests made after `2019-12-31` by `jane@example.com` will be denied.




:tada: