This quickstart shows you how to apply a constraint that enforces a domain restriction. You'll test that constraint and intentionally throw an error. Then you'll modify the constraint so that your domain passes.
Before you begin
- You need a Google Cloud project.
- You need the following Identity and Access Management (IAM) permissions for that project: - resourcemanager.projects.getIamPolicy– This permission can be granted with the Security Reviewer role for the organization.
- resourcemanager.projects.get– This permission can be granted with the Project Viewer role for the organization.
 
To get you started quickly, these instructions use a Cloud Shell that's pre-installed with Terraform, and with a cloned Policy Library repository. The instructions assume you already have a Google Cloud account.
Quickstart
- Go to the Cloud Shell and clone the policy library. 
- Copy the sample IAM domain restriction constraint into the - policies/constraintsdirectory.- cp samples/iam_service_accounts_only.yaml policies/constraints
- Examine the constraint you copied by printing it to the terminal. - cat policies/constraints/iam_service_accounts_only.yaml- The output looks like this: - # This constraint checks that all IAM policy members are in the # "gserviceaccount.com" domain. apiVersion: constraints.gatekeeper.sh/v1alpha1 kind: GCPIAMAllowedPolicyMemberDomainsConstraintV2 metadata: name: service_accounts_only annotations: description: Checks that members that have been granted IAM roles belong to allowlisted domains. spec: severity: high match: target: # {"$ref":"#/definitions/io.k8s.cli.setters.target"} - "organizations/**" parameters: domains: - gserviceaccount.com- Notice - gserviceaccount.comat the bottom. This specifies that only members from the- gserviceaccount.comdomain can be present in an IAM policy.
- To verify that the policy works as expected, create the following Terraform - main.tffile in the current directory. You can use nano, vim, or the Cloud Shell Editor to create- policy-library/main.tf.- terraform { required_providers { google = { source = "hashicorp/google" version = "~> 3.84" } } } resource "google_project_iam_binding" "sample_iam_binding" { project = "PROJECT_ID" role = "roles/viewer" members = [ "user:EMAIL_ADDRESS" ] }- Replace the following: - PROJECT_ID: your project ID.
- EMAIL_ADDRESS: a sample email address. This can be any valid email address. For example,- user@example.com.
 
- Initialize Terraform and generate a Terraform plan using the following: - terraform init
- Export the Terraform plan, if asked, click Authorize when prompted: - terraform plan -out=test.tfplan
- Convert the Terraform plan to JSON: - terraform show -json ./test.tfplan > ./tfplan.json
- Install the terraform-tools component: - sudo apt-get install google-cloud-sdk-terraform-tools
- Enter the following command to validate that your Terraform plan complies with your policies: - gcloud beta terraform vet tfplan.json --policy-library=. --format=json- Since the email address you provided in the IAM policy binding does not belong to a service account, the plan violates the constraint you set up. - [ { "constraint": "GCPIAMAllowedPolicyMemberDomainsConstraintV2.service_accounts_only", "constraint_config": { "api_version": "constraints.gatekeeper.sh/v1alpha1", "kind": "GCPIAMAllowedPolicyMemberDomainsConstraintV2", "metadata": { "annotations": { "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.", "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only", "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml" }, "name": "service-accounts-only" }, "spec": { "match": { "target": [ "organizations/**" ] }, "parameters": { "domains": [ "gserviceaccount.com" ] }, "severity": "high" } }, "message": "IAM policy for //cloudresourcemanager.googleapis.com/projects/PROJECT_ID contains member from unexpected domain: user:user@example.com", "metadata": { "ancestry_path": "organizations/ORG_ID/projects/PROJECT_ID", "constraint": { "annotations": { "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.", "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only", "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml" }, "labels": {}, "parameters": { "domains": [ "gserviceaccount.com" ] } }, "details": { "member": "user:user@example.com", "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID" } }, "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID", "severity": "high" } ] 
- To allow another domain (your email), edit - policy-library/policies/constraints/iam_service_accounts_only.yamland append your email domain to the domains allowlist. In the following example, we've added- example.com, but you'd enter the domain for your own email address:- apiVersion: constraints.gatekeeper.sh/v1alpha1 kind: GCPIAMAllowedPolicyMemberDomainsConstraintV1 metadata: name: service_accounts_only spec: severity: high match: target: ["organizations/**"] parameters: domains: - gserviceaccount.com - example.com
- Now validate your Terraform plan again, and this should result in no violations found: - gcloud beta terraform vet tfplan.json --policy-library=. --format=json- Expected output: - []
Troubleshooting
If you receive the following error, "Error 403: The caller does not have permission, forbidden", then you either didn't replace PROJECT_ID in policy-library/main.tf with the name of your project, or you don't have the necessary permissions on the project you specified.
After editing the project name and/or permissions (resourcemanager.projects.getIamPolicy and resourcemanager.projects.get), go back and export the Terraform plan again, and then convert the Terraform plan to JSON.