In Application Load Balancers, authorization policies are called after evaluating route extensions, network security policies (evaluated by Google Cloud Armor), cross-origin resource sharing (CORS) policies, and Identity-Aware Proxy (IAP), but before running traffic management actions.
This page shows you how to set up authorization policies for Application Load Balancers.
Before you begin
- Make yourself familiar with the Authorization policy overview.
-
- Network Security API
- Network Services API
Set up the load balancer
If you haven't created a load balancer, see the following pages to set up your preferred Application Load Balancer:
To create a global external Application Load Balancer, see Set up a global external Application Load Balancer with VM instance group backends.
To create a regional external Application Load Balancer, see Set up a regional external Application Load Balancer with VM instance group backends.
To create a regional internal Application Load Balancer, see Set up a regional internal Application Load Balancer with VM instance group backends.
To create a cross-region internal Application Load Balancer, see Set up a cross-region internal Application Load Balancer with VM instance group backends.
Create and configure secure tags or service accounts
With internal Application Load Balancers, you can optionally apply authorization policies based on the secure tags and service accounts attached to the client VMs. If you plan to apply tag-based authorization policies, use Resource Manager to create tags.
If you're using external Application Load Balancers, you don't need to create and configure secure tags.
For more information, see Use Tags for firewalls and Service accounts.
Attach service accounts to client VMs
For step-by-step information about attaching a service account to a VM instance, see the following documents:
- To set up a service account during VM creation, see Create a VM that uses a user-managed service account.
- To set up a service account on an existing VM, see Change the attached service account.
Create the secure tag keys and values
Before associating secure tags with the instance group template, create the
secure tag keys and values, and designate them to the GCE_FIREWALL
purpose.
This is necessary for Google Cloud networking features, including Secure Web Proxy
and authorization policies.
To create secure tags, you need the Tag Administrator role (roles/resourcemanager.tagAdmin
).
Console
In the Google Cloud console, go to the Tags page.
Click
Create.In the Tag key description field, enter a description.
Select the For use with network firewall checkbox.
In the Project list, select the Google Cloud project where you want to create the tag.
In the Network field, select
LB_NETWORK
.Click
Add value.In the Tag value field, enter
TAG_VALUE
. The value must be a numeric value.In the Tag value description field, enter a description.
When you have finished adding tag values, click Create tag key.
gcloud
Create the secure tag key.
gcloud resource-manager tags keys create TAG_KEY \ --parent=organizations/ORG_ID \ --purpose=GCE_FIREWALL \ --purpose-data=network=LB_NETWORK
Replace the following:
TAG_KEY
: the name of your secure tag key.ORG_ID
: the ID of your organization.LB_NETWORK
: the name of your VPC network.
Add the secure tag value to the numeric tag key.
gcloud resource-manager tags values create TAG_VALUE \ --parent=ORG_ID/TAG_KEY
Replace
TAG_VALUE
with a numeric tag value.
Bind the secure tag to the instance group template
Tag administrators can bind secure tags to individual VM instances or the instance group template and attach the tag's value to the VMs or template's backends.
To bind secure tags, you need the Tag User
role
(roles/resourcemanager.tagUser
).
Define the full name prefix for your project and zone:
FULL_NAME_PREFIX=//compute.googleapis.com/projects/PROJECT_ID/zones/ZONE/instances/
Replace the following:
PROJECT_ID
: the ID of your project.ZONE
: the zone that the managed instance group is located in.
Get the instance group template ID:
TEMPLATE_ID=$(gcloud compute instance-templates describe TEMPLATE_NAME --region=LOCATION --format='value(id)')
Replace the following:
TEMPLATE_NAME
: the name of your instance group template.LOCATION
: your Google Cloud region.
Concatenate the values of
FULL_NAME_PREFIX
andTEMPLATE_ID
:PARENT="$FULL_NAME_PREFIX$TEMPLATE_ID" echo $PARENT
Create the bindings.
gcloud resource-manager tags bindings create \ --location LOCATION \ --tag-value ORG_ID/TAG_KEY/TAG_VALUE \ --parent PARENT
Replace the following:
ORG_ID
: the ID of your organization.LOCATION
: your Google Cloud region.TAG_KEY
: the name of your secure tag key.TAG_VALUE
: the numeric tag value.
Create the authorization policy
To create an authorization policy, you create a YAML file defining the target
and the rules, and then import the file using the gcloud beta network-security
authz-policies
command.
Authorization policy to deny requests
Global and Cross-region
If you're using a global external Application Load Balancer or a cross-region internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to deny certain requests.
The following example creates an
authz-policy-deny.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in theglobal
location. The policy denies clients from*.hello.com
to access the/api/payments
URL path.$ cat >authz-policy-deny.yaml <<EOF name: my-authz-policy-deny target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules/LB_FORWARDING_RULE" httpRules: - from: sources: - principals: - suffix: ".hello.com" to: operations: - paths: - prefix: "/api/payments" action: DENY EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. For global external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. For cross-region internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies:
gcloud beta network-security authz-policies import my-authz-policy-deny \ --source=authz-policy-deny.yaml \ --location=global
Regional
If you're using a regional external Application Load Balancer or a regional internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to allow certain requests.
The following example creates an
authz-policy-deny.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in a Google Cloud region. The policy denies clients with identities matching*.hello.com
to access the/api/payments
URL path. The policy also denies access to any client VMs with the service accountmy-sa-123@PROJECT_ID.iam.gserviceaccount.com
to the/api/payments
URL.$ cat >authz-policy-deny.yaml <<EOF name: my-authz-policy-deny target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/LOCATION/forwardingRules/LB_FORWARDING_RULE" httpRules: - from: sources: - principals: - suffix: ".hello.com" to: operations: - paths: - prefix: "/api/payments" - from: sources: - resources: - iamServiceAccount: exact: "my-sa-123@PROJECT_ID.iam.gserviceaccount.com" to: operations: - paths: - prefix: "/api/payments" action: DENY EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. For regional external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. For regional internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LOCATION
: your Google Cloud region.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies in the
LOCATION
region:gcloud beta network-security authz-policies import my-authz-policy-deny \ --source=authz-policy-deny.yaml \ --location=LOCATION
Authorization policy to allow requests
Global and Cross-region
If you're using a global external Application Load Balancer or a cross-region internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to allow certain requests.
The following example creates an
authz-policy-allow.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in theglobal
location. The policy allows only clients from*.example.com
to access the/api/payments
URL path.$ cat >authz-policy-allow.yaml <<EOF name: my-authz-policy-allow target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules/LB_FORWARDING_RULE" httpRules: - from: sources: - principals: - suffix: ".example.com" to: operations: - paths: - exact: "/api/payments" action: ALLOW EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. For global external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. For cross-region internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies:
gcloud beta network-security authz-policies import my-authz-policy-allow \ --source=authz-policy-allow.yaml \ --location=global
Regional
If you're using a regional external Application Load Balancer or a regional internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to allow certain requests.
The following example creates an
authz-policy-allow.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in a Google Cloud region of a regional internal Application Load Balancer. The policy allows only clients from*.example.com
to access the/api/payments
URL path when the request originates from a VM with the resource tagTAG_VALUE
.$ cat >authz-policy-allow.yaml <<EOF name: my-authz-policy-allow target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/LOCATION/forwardingRules/LB_FORWARDING_RULE" httpRules: - from: sources: - principals: - suffix: ".example.com" resources: - tagValueIdSet: - ids: "TAG_VALUE" to: operations: - paths: - exact: "/api/payments" action: ALLOW EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. If you're using regional external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. If you're using regional internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LOCATION
: your Google Cloud region.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies in the
LOCATION
region:gcloud beta network-security authz-policies import my-authz-policy-allow \ --source=authz-policy-allow.yaml \ --location=LOCATION
Authorization policy to delegate to a service extension
Before you begin, set up an external authorization engine. For more information about service extensions, see Cloud Load Balancing callouts overview.
Global and Cross-region
If you're using a global external Application Load Balancer or a cross-region internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to delegate certain requests to an external service.
The following example creates an
authz-policy-custom.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in theglobal
location. The policy calls theAUTHZ_EXTENSION
extension for all traffic to the/api/payments
URL path when the request contains a non-emptyAuthorization
header.$ cat >authz-policy-custom.yaml <<EOF name: my-authz-policy-custom target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules/LB_FORWARDING_RULE" httpRules: - to: operations: - paths: - exact: "/api/payments" when: 'request.headers["Authorization"] != ""' action: CUSTOM customProvider: authzExtension: resources: - "https://networkservices.googleapis.com/v1/projects/PROJECT_ID/locations/global/authzExtensions/AUTHZ_EXTENSION" EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. For global external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. For cross-region internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.AUTHZ_EXTENSION
: the name of the authorization extension.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies:
gcloud beta network-security authz-policies import my-authz-policy-custom \ --source=authz-policy-custom.yaml \ --location=global
Regional
If you're using a regional external Application Load Balancer or a regional internal Application Load Balancer, follow these steps to create and import the authorization policy:
Create the authorization policy file to delegate certain requests to an external service.
The following example creates an
authz-policy-custom.yaml
file for the forwarding ruleLB_FORWARDING_RULE
in a Google Cloud region of a regional internal Application Load Balancer. The policy calls theAUTHZ_EXTENSION
extension for all traffic to the/api/payments
URL path when the request contains a non-emptyAuthorization
header.$ cat >authz-policy-custom.yaml <<EOF name: my-authz-policy-custom target: loadBalancingScheme: LB_SCHEME resources: - "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/LOCATION/forwardingRules/LB_FORWARDING_RULE" httpRules: - to: operations: - paths: - exact: "/api/payments" when: 'request.headers["Authorization"] != ""' action: CUSTOM customProvider: authzExtension: resources: - "https://networkservices.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/authzExtensions/AUTHZ_EXTENSION" EOF
Replace the following:
LB_SCHEME
: your load balancing scheme. For regional external Application Load Balancer, set the scheme toEXTERNAL_MANAGED
. For regional internal Application Load Balancer, set the scheme toINTERNAL_MANAGED
.PROJECT_ID
: the ID of your Google Cloud project.LOCATION
: your Google Cloud region.LB_FORWARDING_RULE
: the name of the load balancer's forwarding rule.AUTHZ_EXTENSION
: the name of the authorization extension.
Create the authorization policy and import the YAML file.
The following example command imports the previously created policy file and creates the authorization policies in the
LOCATION
region:gcloud beta network-security authz-policies import my-authz-policy-custom \ --source=authz-policy-custom.yaml \ --location=LOCATION
Test the authorization policies
To test the authorization policies, send some traffic to the load balancer. For more information, see the following pages:
If you're using a global external Application Load Balancer, see Test traffic sent to your instances.
If you're using a regional external Application Load Balancer, see Test the load balancer.
If you're using a regional internal Application Load Balancer, see Test the load balancer.
If you're using a cross-region internal Application Load Balancer, see Test the load balancer.
Understand authorization policy logs in Cloud Logging
To understand how the authorization policies are logged when a request is allowed or denied, see the following:
When a request matches neither the
ALLOW
norDENY
policies, theDENY
policy allows it and logs it asallowed_as_no_allow_policies_matched_request
. However, theALLOW
policy denies it and logs it asdenied_as_no_allow_policies_matched_request
. Because one of the policies denies the request, it is denied.If you're using a global external Application Load Balancer,
statusDetails
is set todenied_by_authz_policy
in the log. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "allowed_as_no_deny_policies_matched_request" result: "ALLOWED" } 1: { details: "denied_as_no_allow_policies_matched_request" result: "DENIED" } ] result: "DENIED" } backendTargetProjectNumber: "projects/12345567" remoteIp: "00.100.11.104" proxyStatus: "error=\"http_request_error\"; details=\"denied_by_authz_policy\"" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }
If you're using a regional internal Application Load Balancer, regional external Application Load Balancer, or cross-region internal Application Load Balancer,
proxyStatus
is set toerror=\"http_request_error\"; details=\"denied_by_authz_policy\"
in the log. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "allowed_as_no_deny_policies_matched_request" result: "ALLOWED" } 1: { details: "denied_as_no_allow_policies_matched_request" result: "DENIED" } ] result: "DENIED" } backendTargetProjectNumber: "projects/12345567" remoteIp: "00.100.11.104" proxyStatus: "error=\"http_request_error\"; details=\"denied_by_authz_policy\"" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }
When a request matches the
DENY
policy, it is denied and the policy that denied the request is logged.If you're using a global external Application Load Balancer,
statusDetails
is set todenied_by_authz_policy
in the log and the name of the policy that denied the request is logged inpolicies
. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "name: "projects/12345567/locations/global/authzPolicies/deny-authz-policy-test"" result: "DENIED" } ] result: "DENIED" } backendTargetProjectNumber: "projects/12345567" cacheDecision: [2] remoteIp: "00.100.11.104" statusDetails: "denied_by_authz_policy" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }
If you're using a regional internal Application Load Balancer, regional external Application Load Balancer, or cross-region internal Application Load Balancer,
proxyStatus
is set toerror=\"http_request_error\"; details=\"denied_by_authz_policy\"
and the name of the policy is logged inpolicies
. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "name: "projects/12345567/locations/$REGION/authzPolicies/deny-authz-policy-test"" result: "DENIED" } ] result: "DENIED" } backendTargetProjectNumber: "projects/12345567" remoteIp: "00.100.11.104" proxyStatus: "error=\"http_request_error\"; details=\"denied_by_authz_policy\"" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }
When a request doesn't match the
DENY
policy, but matches with theALLOW
policy, the request is allowed. In the log, this action is logged asallowed_as_no_deny_policies_matched_request
for theDENY
policy. The policy that allowed the request is also logged.If you're using a global external Application Load Balancer, there is no
statusDetails
in the log. The policy that allowed the request is also logged inpolicies
. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "allowed_as_no_deny_policies_matched_request" result: "ALLOWED" } 1: { details: "name: "projects/12345567/locations/global/authzPolicies/allow-authz-policy-test"" result: "ALLOWED" } ] result: "ALLOWED" } backendTargetProjectNumber: "projects/12345567" cacheDecision: [2] remoteIp: "00.100.11.104" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }
If you're using a regional internal Application Load Balancer, regional external Application Load Balancer, or cross-region internal Application Load Balancer, there is no
proxyStatus
field in the log. The policy that allowed the request is also logged inpolicies
. See the following example:{ httpRequest: {8} insertId: "example-id" jsonPayload: { @type: "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" authzPolicyInfo: { policies: [ 0: { details: "allowed_as_no_deny_policies_matched_request" result: "ALLOWED" } 1: { details: "name: "projects/12345567/locations/$REGION/authzPolicies/allow-authz-policy-test"" result: "ALLOWED" } ] result: "ALLOWED" } backendTargetProjectNumber: "projects/12345567" cacheDecision: [2] remoteIp: "00.100.11.104" } logName: "projects/example-project/logs/requests" receiveTimestamp: "2024-08-28T15:33:56.046651035Z" resource: {2} severity: "WARNING" spanId: "3e1a09a8e5e3e14d" timestamp: "2024-08-28T15:33:55.355042Z" trace: "projects/example-project/traces/8c8b3dbf9a19c85954d0fa2d958ca509" }