How to easily create custom controls that can be enforced when provisioning resources in GCP?

Create tailored guardrails with custom organization policy constraints in GCP

Use custom organization policy constraint to perform your own defined preventive controls

Trinquier Vannick
Google Cloud - Community

--

Preventive controls with custom organization policy constraints

In today’s world, businesses are moving their operations to the cloud to get more flexibility, scale up or down as needed, and save money. But there are challenges with this change, especially when it comes to making sure your cloud setup follows all the rules.

Compliance controls are essential for organizations that want to use Google Cloud Platform in a secure, responsible manner. By implementing effective compliance controls, organizations can reduce their risk, protect their data, and meet their regulatory obligations.

There are different ways to make sure your cloud setup is compliant, but organization policies are a central and effective approach. Google Cloud Platform (GCP) has a wide range of organization policies that let businesses set and enforce compliance rules across their cloud infrastructure. But sometimes, the standard organization policies might not be enough to meet your specific compliance needs.

That’s where custom organization policy constraints come in. This is a new feature (still in pre-GA as of October 2023) that gives you more flexibility and control over how you define your compliance requirements. Custom constraints let you tailor your compliance policies to your unique needs and the specific controls that apply to your business.

In this article, we’ll talk about organization policies and custom constraints and how they can help you achieve compliance. We’ll also show you some real-world examples of how to use custom organization policies to implement essential compliance controls that are important for many businesses.

Organization Policy

Organization policies allow you to define constraints that govern the creation and modification of resources. These constraints can be tailored to meet the specific needs of your organization and ensure that they align with the organization’s overall goals and policies.

Imagine a scenario where you want to prevent engineers from creating Compute Engine VM instances with external IP addresses. This can be easily achieved using an existing organization policy, constraints/compute.vmExternalIpAccess. This policy provides a basic level of customization with allowed and denied lists, allowing specific VMs to be granted external IP access if necessary.

However, what if your organization has more granular requirements, such as enforcing a specific naming convention for some type of resources ?

Standard organization policies might not suffice in such cases. Custom organization policy constraints provide the flexibility to address these specific needs.

Custom Organization Policy Constraint

Organization Policy provides predefined constraints for many existing Google Cloud services. However, if you need better control and need to adapt the compliance rule to your organization, you can now create custom constraints and use them in your organization policies.

Custom Constraint has the notion of conditions where you are able to define your own logic using Common Expression Language (CEL).

CEL is a powerful tool for evaluating logical expressions and conditions in various contexts, including policy enforcement and data validation. It provides a concise and expressive way to define complex rules and constraints, making it well-suited for managing access control, resource allocation, and data integrity requirements.

Here are some example of CEL expressions that can be used:

  • resource.machineType.contains(‘/machineTypes/n2d’)
  • resource.sizeGb <= 250

Feel free to have a look here for more information on CEL and see all the possibility of the language.

Enforcing naming convention with custom constraint

Based on the discussion above, we will create a custom constraint to ensure that every firewall rule created is following a specific naming convention.

Let’s follow that sample pattern for our firewall rule name (allow|deny)-(ingress|egress)-<description>-(dev|uat|prd)

Examples:

  • allow-ingress-web-to-db-prd Allowed
  • allow-ingress-web-to-db Denied
  • allow-ssh-to-db Denied
  • allow-egress-web-to-internet-uat Allowed

The nice thing is now with custom organization policy, we can enforce naming of VPC Firewall rules using a regular expression as expressed above.

Testing Custom Organization Policy

Let’s have a look and check how we can create a custom organization policy to enforce the firewall rule naming convention above.

0. Setting environment variables for this test

ORGANIZATION_ID=11111111
PROJECT_ID=my-project
  1. Enabling organization policy API
gcloud services enable orgpolicy.googleapis.com --project $PROJECT_ID

2. Create a custom constraint organization policy to enforce firewall rule naming convention. In this example, we are using following regular expression for validation ^(allow|deny)-(ingress|egress)-[a-zA-Z0–9-]*-(dev|uat|prd)$

3. Create the custom constraint at the organization level

Creation of the file enforceFirewallRuleNaming.yaml

cat << EOL > enforceFirewallRuleNaming.yaml 
name: organizations/$ORGANIZATION_ID/customConstraints/custom.enforceFirewalLRuleNamingConvention
resource_types: compute.googleapis.com/Firewall
condition: resource.name.matches("^(allow|deny)-(ingress|egress)-[a-zA-Z0-9-]*-(dev|uat|prd)$") == false
action_type: DENY
method_types: CREATE
display_name: Enforce Firewall Rule naming Convention
description: "Enforce that every Firewall Rule created are named according to regular expression pattern: ^(allow|deny)-(ingress|egress)-[a-zA-Z0-9-]*-(dev|uat|prd)$"
EOL

Creation of the custom constraint

gcloud org-policies set-custom-constraint enforceFirewallRuleNaming.yaml

Output

Created custom constraint [organizations/11111111/customConstraints/custom.enforceFirewalLRuleNamingConvention].
actionType: DENY
condition: resource.name.matches("^(allow|deny)-(ingress|egress)-[a-zA-Z0-9-]*-(dev|uat|prd)$")
== false
description: 'Enforce that every Firewall Rule created are named according to regular
expression pattern: ^(allow|deny)-(ingress|egress)-[a-zA-Z0-9-]*-(dev|uat|prd)$'
displayName: Enforce Firewall Rule naming Convention
methodTypes:
- CREATE
name: organizations/11111111/customConstraints/custom.enforceFirewalLRuleNamingConvention
resourceTypes:
- compute.googleapis.com/Firewall
updateTime: '2023-11-13T06:23:24.248497Z'

4. Enforce this custom organization policy to a specific project

Creation of the file enforceFirewallRuleNaming-policy.yaml

cat << EOL > enforceFirewallRuleNaming-policy.yaml
name: projects/$PROJECT_ID/policies/custom.enforceFirewalLRuleNamingConvention
spec:
rules:
- enforce: true
EOL

Enforcing the policy

gcloud org-policies set-policy enforceFirewallRuleNaming-policy.yaml

Output

Created policy [projects/my-project/policies/custom.enforceFirewalLRuleNamingConvention].
name: projects/my-project/policies/custom.enforceFirewalLRuleNamingConvention
spec:
etag: CNKCx6oGEKDauu4B
rules:
- enforce: true
updateTime: '2023-11-13T06:25:22.500084Z'

5. Create a VPC firewall rule and checking whether the custom organization policy is applied

Let’s first try to create a firewall rule not following naming convention. As expected in the custom organization policy, the creation should be denied.

gcloud compute firewall-rules create allow-ssh \
--action=ALLOW --direction=INGRESS --network=default \
--priority=1000 --rules=tcp:22 --source-ranges=0.0.0.0/0 \
--project $PROJECT_ID

Output

Creating firewall…failed. 
ERROR: (gcloud.compute.firewall-rules.create) Could not fetch resource:
- Operation denied by custom org policy: [customConstraints/custom.enforceFirewalLRuleNamingConvention] : Enforce that every Firewall Rule created are named according to regular expression pattern: ^(allow|deny)-(ingress|egress)-[a-zA-Z0–9-]*-(dev|uat|prd)$

Indeed, the firewall rule cannot be created. We can see that the operation is denied and the description message is providing more information about the cause of the failure.

6. Create a second VPC firewall rule following expected naming convention

To do so, we are now using that specific firewall rule name allow-ingress-internet-to-ssh-prd which should be compliant with our policy.

gcloud compute firewall-rules create allow-ingress-internet-to-ssh-prd \
- action=ALLOW - direction=INGRESS - network=default \
- priority=1000 - rules=tcp:22 - source-ranges=0.0.0.0/0 - project $PROJECT_ID

Output

Creating firewall… Created [https://www.googleapis.com/compute/v1/projects/my-project/global/firewalls/allow-ingress-internet-to-ssh-prd]. 
Creating firewall…done.

As expected the firewall rule can be created successfully !

Conclusion

As you have seen, now with custom organization policy, we are able to easily create security and compliance controls when provisioning resources on our GCP infrastructure.

As per now, only limited services have been made available. And only few supported resources for each of these API are supported. However, it should continue to grow in the future and will certainly simplify a lot the work of security team in every organization to ensure resources provisioning keeps secure and compliant

References

Services available with custom organization policy constraint:

--

--