diff --git a/mmv1/products/networksecurity/AuthzPolicy.yaml b/mmv1/products/networksecurity/AuthzPolicy.yaml index 5a9343f5c58e..d29cf5299684 100644 --- a/mmv1/products/networksecurity/AuthzPolicy.yaml +++ b/mmv1/products/networksecurity/AuthzPolicy.yaml @@ -75,6 +75,18 @@ examples: skip_test: true # temporary b/484137930 vars: policy_name: 'my-mcp-policy' + - name: 'network_security_authz_policy_with_network_rules' + primary_resource_id: 'default' + min_version: beta + vars: + resource_name: 'authz-policy' + gateway_name: 'swp-gateway' + network_name: 'lb-network' + subnet_name: 'backend-subnet' + proxy_subnet_name: 'proxy-only-subnet' + swp_policy: 'swp-policy' + test_env_vars: + project: 'PROJECT_NAME' parameters: - name: 'name' type: String @@ -814,6 +826,400 @@ properties: type: String description: | CEL expression that describes the conditions to be satisfied for the action. The result of the CEL expression is ANDed with the from and to. Refer to the CEL language reference for a list of available attributes. + - name: 'networkRules' + type: Array + description: | + A list of authorization HTTP rules to match against the incoming request.A policy match occurs when at least one HTTP rule matches the request or when no HTTP rules are specified in the policy. At least one HTTP Rule is required for Allow or Deny Action. + Limited to 5 rules. + item_type: + type: NestedObject + properties: + - name: 'from' + type: NestedObject + description: | + Describes properties of one or more sources of a request. + properties: + - name: 'sources' + type: Array + description: | + Describes the properties of a request's sources. At least one of sources or notSources must be specified. Limited to 1 source. A match occurs when ANY source (in sources or notSources) matches the request. Within a single source, the match follows AND semantics across fields and OR semantics within a single field, i.e. a match occurs when ANY principal matches AND ANY ipBlocks match. + item_type: + type: NestedObject + properties: + - name: 'ipBlocks' + type: Array + description: | + A list of IP addresses or IP address ranges to match against the source IP address of the request. Limited to 10 ipBlocks per Authorization Policy + item_type: + type: NestedObject + properties: + - name: 'prefix' + type: String + description: The address prefix. + required: true + - name: 'length' + type: Integer + description: The length of the address range. + required: true + - name: 'principals' + type: Array + description: | + A list of identities derived from the client's certificate. This field will not match on a request unless mutual TLS is enabled for the Forwarding rule or Gateway. Each identity is a string whose value is matched against the URI SAN, or DNS SAN or the subject field in the client's certificate. The match can be exact, prefix, suffix or a substring match. One of exact, prefix, suffix or contains must be specified. + Limited to 5 principals. + item_type: + type: NestedObject + properties: + - name: 'principalSelector' + type: Enum + description: | + An enum to decide what principal value the principal rule will match against. If not specified, the PrincipalSelector is CLIENT_CERT_URI_SAN. + default_value: "CLIENT_CERT_URI_SAN" + enum_values: + - 'PRINCIPAL_SELECTOR_UNSPECIFIED' + - 'CLIENT_CERT_URI_SAN' + - 'CLIENT_CERT_DNS_NAME_SAN' + - 'CLIENT_CERT_COMMON_NAME' + - name: 'principal' + type: NestedObject + description: | + Required. A non-empty string whose value is matched against the principal value based on the principalSelector. + Only exact match can be applied for CLIENT_CERT_URI_SAN, CLIENT_CERT_DNS_NAME_SAN, CLIENT_CERT_COMMON_NAME selectors. + properties: + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + deprecation_message: '`principals.ignore_case` is deprecated and will be removed in a future major release. Use `principals.principal.ignore_case` instead.' + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + deprecation_message: '`principals.exact` is deprecated and will be removed in a future major release. Use `principals.principal.exact` instead.' + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + deprecation_message: '`principals.prefix` is deprecated and will be removed in a future major release. Use `principals.principal.prefix` instead.' + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + deprecation_message: '`principals.suffix` is deprecated and will be removed in a future major release. Use `principals.principal.suffix` instead.' + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + deprecation_message: '`principals.contains` is deprecated and will be removed in a future major release. Use `principals.principal.contains` instead.' + - name: 'resources' + type: Array + description: | + A list of resources to match against the resource of the source VM of a request. + Limited to 5 resources. + item_type: + type: NestedObject + properties: + - name: 'tagValueIdSet' + type: NestedObject + description: | + A list of resource tag value permanent IDs to match against the resource manager tags value associated with the source VM of a request. + properties: + - name: 'ids' + type: Array + description: | + A list of resource tag value permanent IDs to match against the resource manager tags value associated with the source VM of a request. The match follows AND semantics which means all the ids must match. + Limited to 5 matches. + item_type: + type: String + - name: 'iamServiceAccount' + type: NestedObject + description: | + An IAM service account to match against the source service account of the VM sending the request. + properties: + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + - name: 'notSources' + type: Array + description: | + Describes the negated properties of request sources. Matches requests from sources that do not match the criteria specified in this field. At least one of sources or notSources must be specified. Limited to 1 not_source. + item_type: + type: NestedObject + properties: + - name: 'ipBlocks' + type: Array + description: | + A list of IP addresses or IP address ranges to match against the source IP address of the request. Limited to 10 ipBlocks per Authorization Policy + item_type: + type: NestedObject + properties: + - name: 'prefix' + type: String + description: The address prefix. + required: true + - name: 'length' + type: Integer + description: The length of the address range. + required: true + - name: 'principals' + type: Array + description: | + A list of identities derived from the client's certificate. This field will not match on a request unless mutual TLS is enabled for the Forwarding rule or Gateway. Each identity is a string whose value is matched against the URI SAN, or DNS SAN or the subject field in the client's certificate. The match can be exact, prefix, suffix or a substring match. One of exact, prefix, suffix or contains must be specified. + Limited to 5 principals. + item_type: + type: NestedObject + properties: + - name: 'principalSelector' + type: Enum + description: | + An enum to decide what principal value the principal rule will match against. If not specified, the PrincipalSelector is CLIENT_CERT_URI_SAN. + default_value: "CLIENT_CERT_URI_SAN" + enum_values: + - 'PRINCIPAL_SELECTOR_UNSPECIFIED' + - 'CLIENT_CERT_URI_SAN' + - 'CLIENT_CERT_DNS_NAME_SAN' + - 'CLIENT_CERT_COMMON_NAME' + - name: 'principal' + type: NestedObject + description: | + Required. A non-empty string whose value is matched against the principal value based on the principalSelector. + Only exact match can be applied for CLIENT_CERT_URI_SAN, CLIENT_CERT_DNS_NAME_SAN, CLIENT_CERT_COMMON_NAME selectors. + properties: + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + deprecation_message: '`principals.ignore_case` is deprecated and will be removed in a future major release. Use `principals.principal.ignore_case` instead.' + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + deprecation_message: '`principals.exact` is deprecated and will be removed in a future major release. Use `principals.principal.exact` instead.' + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + deprecation_message: '`principals.prefix` is deprecated and will be removed in a future major release. Use `principals.principal.prefix` instead.' + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + deprecation_message: '`principals.suffix` is deprecated and will be removed in a future major release. Use `principals.principal.suffix` instead.' + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + deprecation_message: '`principals.contains` is deprecated and will be removed in a future major release. Use `principals.principal.contains` instead.' + - name: 'resources' + type: Array + description: | + A list of resources to match against the resource of the source VM of a request. + Limited to 5 resources. + item_type: + type: NestedObject + properties: + - name: 'tagValueIdSet' + type: NestedObject + description: | + A list of resource tag value permanent IDs to match against the resource manager tags value associated with the source VM of a request. + properties: + - name: 'ids' + type: Array + description: | + A list of resource tag value permanent IDs to match against the resource manager tags value associated with the source VM of a request. The match follows AND semantics which means all the ids must match. + Limited to 5 matches. + item_type: + type: String + - name: 'iamServiceAccount' + type: NestedObject + description: | + An IAM service account to match against the source service account of the VM sending the request. + properties: + - name: 'ignoreCase' + type: Boolean + description: | + If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. For example, the matcher data will match both input string Data and data if set to true. + - name: 'exact' + type: String + description: | + The input string must match exactly the string specified here. + Examples: + * abc only matches the value abc. + - name: 'prefix' + type: String + description: | + The input string must have the prefix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value abc.xyz + - name: 'suffix' + type: String + description: | + The input string must have the suffix specified here. Note: empty prefix is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc + - name: 'contains' + type: String + description: | + The input string must have the substring specified here. Note: empty contains match is not allowed, please use regex instead. + Examples: + * abc matches the value xyz.abc.def + - name: 'to' + type: NestedObject + description: | + Describes properties of one or more targets of a request + properties: + - name: 'operations' + type: Array + description: | + Describes properties of one or more targets of a request. At least one of operations or notOperations must be specified. Limited to 1 operation. + item_type: + type: NestedObject + properties: + - name: 'ports' + type: Array + description: | + A list of destination ports to match against. + item_type: + type: String + - name: 'snis' + type: Array + item_type: + type: NestedObject + properties: + - name: 'exact' + type: String + - name: 'prefix' + type: String + - name: 'suffix' + type: String + - name: 'contains' + type: String + - name: 'ignoreCase' + type: Boolean + - name: 'notOperations' + type: Array + item_type: + type: NestedObject + properties: + - name: 'ports' + type: Array + item_type: + type: String + - name: 'snis' + type: Array + item_type: + type: NestedObject + properties: + - name: 'exact' + type: String + - name: 'prefix' + type: String + - name: 'suffix' + type: String + - name: 'contains' + type: String + - name: 'ignoreCase' + type: Boolean + - name: 'when' + type: String + description: | + CEL expression that describes the conditions to be satisfied for the action. The result of the CEL expression is ANDed with the from and to. Refer to the CEL language reference for a list of available attributes. - name: 'action' type: Enum description: | diff --git a/mmv1/templates/terraform/examples/network_security_authz_policy_with_network_rules.tf.tmpl b/mmv1/templates/terraform/examples/network_security_authz_policy_with_network_rules.tf.tmpl new file mode 100644 index 000000000000..8694ee669769 --- /dev/null +++ b/mmv1/templates/terraform/examples/network_security_authz_policy_with_network_rules.tf.tmpl @@ -0,0 +1,123 @@ +resource "google_compute_network" "default" { + provider = google-beta + name = "{{index $.Vars "network_name"}}" + project = "{{index $.TestEnvVars "project"}}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "default" { + provider = google-beta + name = "{{index $.Vars "subnet_name"}}" + project = "{{index $.TestEnvVars "project"}}" + region = "us-east4" + ip_cidr_range = "10.1.2.0/24" + network = google_compute_network.default.id +} + +resource "google_compute_subnetwork" "proxy_only" { + provider = google-beta + name = "{{index $.Vars "proxy_subnet_name"}}" + project = "{{index $.TestEnvVars "project"}}" + region = "us-east4" + ip_cidr_range = "10.129.0.0/23" + + purpose = "REGIONAL_MANAGED_PROXY" + role = "ACTIVE" + + network = google_compute_network.default.id +} + +resource "google_network_security_gateway_security_policy" "default" { + provider = google-beta + name = "{{index $.Vars "swp_policy"}}" + project = "{{index $.TestEnvVars "project"}}" + location = "us-east4" +} + +resource "google_compute_address" "swp_ip" { + provider = google-beta + name = "{{index $.Vars "gateway_name"}}" + project = "{{index $.TestEnvVars "project"}}" + region = "us-east4" + + subnetwork = google_compute_subnetwork.default.id + address_type = "INTERNAL" +} + +resource "google_network_services_gateway" "swp_gateway" { + provider = google-beta + name = "{{index $.Vars "gateway_name"}}" + project = "{{index $.TestEnvVars "project"}}" + location = "us-east4" + + type = "SECURE_WEB_GATEWAY" + + addresses = [google_compute_address.swp_ip.address] + ports = [443] + delete_swg_autogen_router_on_destroy = true + scope = "swp-scope" + network = google_compute_network.default.id + subnetwork = google_compute_subnetwork.default.id + + gateway_security_policy = google_network_security_gateway_security_policy.default.id + + depends_on = [ + google_compute_subnetwork.proxy_only + ] +} + +resource "google_network_security_authz_policy" "{{$.PrimaryResourceId}}" { + provider = google-beta + name = "{{index $.Vars "resource_name"}}" + project = "{{index $.TestEnvVars "project"}}" + location = "us-east4" + + description = "SWP authorization policy" + policy_profile = "REQUEST_AUTHZ" + + target { + load_balancing_scheme = "INTERNAL_MANAGED" + + resources = [ + google_network_services_gateway.swp_gateway.id + ] + } + + action = "ALLOW" + + network_rules { + from { + not_sources { + ip_blocks { + prefix = "10.1.5.0" + length = 24 + } + + principals { + principal_selector = "CLIENT_CERT_URI_SAN" + + principal { + exact = "spiffe://example/ns/default/sa/example" + } + } + } + } + + to { + operations { + snis { + exact = "example.com" + } + } + } + } + + labels = { + environment = "test" + managed_by = "terraform" + } + + lifecycle { + create_before_destroy = false + } +} \ No newline at end of file