Configure GCP Cloud Armor Security Policy Rules

The gcp:compute/securityPolicyRule:SecurityPolicyRule resource, part of the Pulumi GCP provider, defines individual rules within a Cloud Armor security policy: their match conditions, actions, and priority ordering. This guide focuses on three capabilities: IP-based traffic filtering, priority-based rule evaluation, and allow/deny actions.

Security policy rules belong to a Cloud Armor security policy that must exist separately. The examples are intentionally small. Combine them with your own security policies and backend services.

Allow traffic from specific IP ranges

Cloud Armor protects applications by filtering traffic based on IP addresses, geographic location, or request patterns. Most deployments start with simple IP-based rules.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.SecurityPolicy("default", {
    name: "policyruletest",
    description: "basic global security policy",
    type: "CLOUD_ARMOR",
});
const policyRule = new gcp.compute.SecurityPolicyRule("policy_rule", {
    securityPolicy: _default.name,
    description: "new rule",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.SecurityPolicy("default",
    name="policyruletest",
    description="basic global security policy",
    type="CLOUD_ARMOR")
policy_rule = gcp.compute.SecurityPolicyRule("policy_rule",
    security_policy=default.name,
    description="new rule",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewSecurityPolicy(ctx, "default", &compute.SecurityPolicyArgs{
			Name:        pulumi.String("policyruletest"),
			Description: pulumi.String("basic global security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewSecurityPolicyRule(ctx, "policy_rule", &compute.SecurityPolicyRuleArgs{
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Priority:       pulumi.Int(100),
			Match: &compute.SecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.SecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.SecurityPolicy("default", new()
    {
        Name = "policyruletest",
        Description = "basic global security policy",
        Type = "CLOUD_ARMOR",
    });

    var policyRule = new Gcp.Compute.SecurityPolicyRule("policy_rule", new()
    {
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.SecurityPolicy;
import com.pulumi.gcp.compute.SecurityPolicyArgs;
import com.pulumi.gcp.compute.SecurityPolicyRule;
import com.pulumi.gcp.compute.SecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new SecurityPolicy("default", SecurityPolicyArgs.builder()
            .name("policyruletest")
            .description("basic global security policy")
            .type("CLOUD_ARMOR")
            .build());

        var policyRule = new SecurityPolicyRule("policyRule", SecurityPolicyRuleArgs.builder()
            .securityPolicy(default_.name())
            .description("new rule")
            .priority(100)
            .match(SecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(SecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:SecurityPolicy
    properties:
      name: policyruletest
      description: basic global security policy
      type: CLOUD_ARMOR
  policyRule:
    type: gcp:compute:SecurityPolicyRule
    name: policy_rule
    properties:
      securityPolicy: ${default.name}
      description: new rule
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true

When incoming traffic matches the srcIpRanges in the match configuration, Cloud Armor applies the specified action. The priority determines evaluation order: lower numbers are evaluated first. The preview property lets you test rules without enforcing them. The versionedExpr field specifies the match expression format; SRC_IPS_V1 indicates IP-based matching.

Configure a default deny rule with exceptions

Security policies often follow a deny-by-default approach where all traffic is blocked unless explicitly allowed.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.SecurityPolicy("default", {
    name: "policyruletest",
    description: "basic global security policy",
    type: "CLOUD_ARMOR",
});
const defaultRule = new gcp.compute.SecurityPolicyRule("default_rule", {
    securityPolicy: _default.name,
    description: "default rule",
    action: "deny",
    priority: 2147483647,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["*"],
        },
    },
});
const policyRule = new gcp.compute.SecurityPolicyRule("policy_rule", {
    securityPolicy: _default.name,
    description: "new rule",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.SecurityPolicy("default",
    name="policyruletest",
    description="basic global security policy",
    type="CLOUD_ARMOR")
default_rule = gcp.compute.SecurityPolicyRule("default_rule",
    security_policy=default.name,
    description="default rule",
    action="deny",
    priority=2147483647,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["*"],
        },
    })
policy_rule = gcp.compute.SecurityPolicyRule("policy_rule",
    security_policy=default.name,
    description="new rule",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewSecurityPolicy(ctx, "default", &compute.SecurityPolicyArgs{
			Name:        pulumi.String("policyruletest"),
			Description: pulumi.String("basic global security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewSecurityPolicyRule(ctx, "default_rule", &compute.SecurityPolicyRuleArgs{
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("default rule"),
			Action:         pulumi.String("deny"),
			Priority:       pulumi.Int(2147483647),
			Match: &compute.SecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.SecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("*"),
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewSecurityPolicyRule(ctx, "policy_rule", &compute.SecurityPolicyRuleArgs{
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Priority:       pulumi.Int(100),
			Match: &compute.SecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.SecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.SecurityPolicy("default", new()
    {
        Name = "policyruletest",
        Description = "basic global security policy",
        Type = "CLOUD_ARMOR",
    });

    var defaultRule = new Gcp.Compute.SecurityPolicyRule("default_rule", new()
    {
        SecurityPolicy = @default.Name,
        Description = "default rule",
        Action = "deny",
        Priority = 2147483647,
        Match = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "*",
                },
            },
        },
    });

    var policyRule = new Gcp.Compute.SecurityPolicyRule("policy_rule", new()
    {
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.SecurityPolicy;
import com.pulumi.gcp.compute.SecurityPolicyArgs;
import com.pulumi.gcp.compute.SecurityPolicyRule;
import com.pulumi.gcp.compute.SecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new SecurityPolicy("default", SecurityPolicyArgs.builder()
            .name("policyruletest")
            .description("basic global security policy")
            .type("CLOUD_ARMOR")
            .build());

        var defaultRule = new SecurityPolicyRule("defaultRule", SecurityPolicyRuleArgs.builder()
            .securityPolicy(default_.name())
            .description("default rule")
            .action("deny")
            .priority(2147483647)
            .match(SecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(SecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("*")
                    .build())
                .build())
            .build());

        var policyRule = new SecurityPolicyRule("policyRule", SecurityPolicyRuleArgs.builder()
            .securityPolicy(default_.name())
            .description("new rule")
            .priority(100)
            .match(SecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(SecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:SecurityPolicy
    properties:
      name: policyruletest
      description: basic global security policy
      type: CLOUD_ARMOR
  defaultRule:
    type: gcp:compute:SecurityPolicyRule
    name: default_rule
    properties:
      securityPolicy: ${default.name}
      description: default rule
      action: deny
      priority: '2147483647'
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - '*'
  policyRule:
    type: gcp:compute:SecurityPolicyRule
    name: policy_rule
    properties:
      securityPolicy: ${default.name}
      description: new rule
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true

The default rule uses priority 2147483647 (the lowest possible value) to catch any traffic not matched by higher-priority rules. The srcIpRanges value “*” matches all traffic. This configuration creates a layered policy: the priority 100 rule allows traffic from 10.10.0.0/16, while the default rule denies everything else.

Layer multiple rules with priority ordering

Complex security policies require multiple rules evaluated in priority order.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.SecurityPolicy("default", {
    name: "policywithmultiplerules",
    description: "basic global security policy",
    type: "CLOUD_ARMOR",
});
const policyRuleOne = new gcp.compute.SecurityPolicyRule("policy_rule_one", {
    securityPolicy: _default.name,
    description: "new rule one",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
const policyRuleTwo = new gcp.compute.SecurityPolicyRule("policy_rule_two", {
    securityPolicy: _default.name,
    description: "new rule two",
    priority: 101,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: [
                "192.168.0.0/16",
                "10.0.0.0/8",
            ],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.SecurityPolicy("default",
    name="policywithmultiplerules",
    description="basic global security policy",
    type="CLOUD_ARMOR")
policy_rule_one = gcp.compute.SecurityPolicyRule("policy_rule_one",
    security_policy=default.name,
    description="new rule one",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
policy_rule_two = gcp.compute.SecurityPolicyRule("policy_rule_two",
    security_policy=default.name,
    description="new rule two",
    priority=101,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": [
                "192.168.0.0/16",
                "10.0.0.0/8",
            ],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewSecurityPolicy(ctx, "default", &compute.SecurityPolicyArgs{
			Name:        pulumi.String("policywithmultiplerules"),
			Description: pulumi.String("basic global security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewSecurityPolicyRule(ctx, "policy_rule_one", &compute.SecurityPolicyRuleArgs{
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule one"),
			Priority:       pulumi.Int(100),
			Match: &compute.SecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.SecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewSecurityPolicyRule(ctx, "policy_rule_two", &compute.SecurityPolicyRuleArgs{
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule two"),
			Priority:       pulumi.Int(101),
			Match: &compute.SecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.SecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("192.168.0.0/16"),
						pulumi.String("10.0.0.0/8"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.SecurityPolicy("default", new()
    {
        Name = "policywithmultiplerules",
        Description = "basic global security policy",
        Type = "CLOUD_ARMOR",
    });

    var policyRuleOne = new Gcp.Compute.SecurityPolicyRule("policy_rule_one", new()
    {
        SecurityPolicy = @default.Name,
        Description = "new rule one",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

    var policyRuleTwo = new Gcp.Compute.SecurityPolicyRule("policy_rule_two", new()
    {
        SecurityPolicy = @default.Name,
        Description = "new rule two",
        Priority = 101,
        Match = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.SecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "192.168.0.0/16",
                    "10.0.0.0/8",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.SecurityPolicy;
import com.pulumi.gcp.compute.SecurityPolicyArgs;
import com.pulumi.gcp.compute.SecurityPolicyRule;
import com.pulumi.gcp.compute.SecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.SecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new SecurityPolicy("default", SecurityPolicyArgs.builder()
            .name("policywithmultiplerules")
            .description("basic global security policy")
            .type("CLOUD_ARMOR")
            .build());

        var policyRuleOne = new SecurityPolicyRule("policyRuleOne", SecurityPolicyRuleArgs.builder()
            .securityPolicy(default_.name())
            .description("new rule one")
            .priority(100)
            .match(SecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(SecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

        var policyRuleTwo = new SecurityPolicyRule("policyRuleTwo", SecurityPolicyRuleArgs.builder()
            .securityPolicy(default_.name())
            .description("new rule two")
            .priority(101)
            .match(SecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(SecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges(                    
                        "192.168.0.0/16",
                        "10.0.0.0/8")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:SecurityPolicy
    properties:
      name: policywithmultiplerules
      description: basic global security policy
      type: CLOUD_ARMOR
  policyRuleOne:
    type: gcp:compute:SecurityPolicyRule
    name: policy_rule_one
    properties:
      securityPolicy: ${default.name}
      description: new rule one
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true
  policyRuleTwo:
    type: gcp:compute:SecurityPolicyRule
    name: policy_rule_two
    properties:
      securityPolicy: ${default.name}
      description: new rule two
      priority: 101
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 192.168.0.0/16
            - 10.0.0.0/8
      action: allow
      preview: true

Rules are evaluated from lowest to highest priority number. In this configuration, priority 100 is evaluated before priority 101. Each rule can specify multiple srcIpRanges in its match configuration. This allows you to build granular access control by combining multiple allow rules with different IP ranges.

Beyond these examples

These snippets focus on specific security policy rule features: IP-based traffic filtering, priority-based rule evaluation, and allow and deny actions. They’re intentionally minimal rather than full security configurations.

The examples reference pre-existing infrastructure such as Cloud Armor security policies (gcp.compute.SecurityPolicy). They focus on configuring individual rules rather than provisioning the entire security policy.

To keep things focused, common rule patterns are omitted, including:

  • Rate limiting and ban actions (rateLimitOptions)
  • reCAPTCHA and redirect actions (redirectOptions)
  • Header manipulation (headerAction)
  • Preconfigured WAF rules (preconfiguredWafConfig)

These omissions are intentional: the goal is to illustrate how each rule feature is wired, not provide drop-in security modules. See the SecurityPolicyRule resource reference for all available configuration options.

Let's configure GCP Cloud Armor Security Policy Rules

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Rule Configuration & Priority
How does rule priority work in security policies?
Priority must be between 0 and 2147483647, where 0 is the highest priority and 2147483647 is the lowest. Rules are evaluated from highest to lowest priority, so a rule with priority 100 is evaluated before priority 101.
What properties can't be changed after creating a rule?
The priority, securityPolicy, and project properties are immutable. To change these values, you must delete and recreate the rule.
Can I have multiple rules in one security policy?
Yes, create multiple SecurityPolicyRule resources with different priorities that reference the same securityPolicy name.
How do I create a default deny-all rule?
Set priority to 2147483647 (lowest priority), action to "deny", and configure match.config.srcIpRanges to ["*"] to match all traffic.
Actions & Enforcement
What actions are available for security policy rules?
You can use allow, deny(STATUS) with HTTP codes 403/404/502, rate_based_ban, redirect, or throttle. The rate_based_ban and throttle actions require rateLimitOptions, while redirect requires redirectOptions.
Why isn't my rate_based_ban or throttle action working?
These actions require rateLimitOptions to be configured. Make sure you’ve specified rateLimitOptions when using rate_based_ban or throttle as your action.
What does preview mode do?
When preview is set to true, the rule is evaluated but the specified action is not enforced. This lets you test rules without affecting traffic.
Policy Type Restrictions
What features require a CLOUD_ARMOR policy type?
The headerAction and redirectOptions features only work with Global Security Policies of type CLOUD_ARMOR. Standard security policies don’t support these features.
Can I use the redirect action with any security policy?
No, the redirect action is only supported in Global Security Policies of type CLOUD_ARMOR. It can perform internal reCAPTCHA redirects or external URL-based redirects via 302 responses.

Using a different cloud?

Explore security guides for other cloud providers: