3
votes

GCP allows external HTTPS load balancers to be protected by Identity Aware Proxy (IAP), using your google account credentials to protect the web server behind the load balancer. This an easy way to protect web services you want to use internally. Sometimes you need to provide access within a website on another domain, however, such as another team's subdomain, or when using a third party service like Honeycomb.io's Secure Tenancy. This requires Cross-origin resource sharing, or CORS, to be enabled.

GCP can be configured to allow CORS requests across IAP, but the documentation is minimal. How do you actually enable it?

2
CORS is implemented in the browser and by the browser. This is not related to IAP. To send CORS headers, you do so in your web application. The load balancer is not involved and neither is IAP. Is there something that I do not understand in your question?John Hanley
GCP IAP does not allow CORS OPTIONS requests by default. You have to enable it. Unfortunately, it's not yet exposed easily. You're correct that the browser is making these requests, but the backend still has to accept the requests.Andrew Ring
Andrew, interesting. I will study the answer you posted.John Hanley

2 Answers

4
votes

As of gcloud 277.0, this can be done through the gcloud beta iap settings command. Cloud Console support is coming soon. You want something like:

cat > settings <<EOF
accessSettings:
  corsSettings:
    allowHttpOptions: true
EOF
gcloud beta iap settings set settings \
  --project=project-id \
  --resource-type=compute \
  --service=backend-service-name
1
votes

UPDATE: https://twitter.com/mattsachs/status/1220907777247154178?s=19

At this time, GCP does not expose this api through the Cloud Console, the gcloud command line tool, or their various language api libraries. It requires making a web request with something like curl from within a VM instance.

VM Creation

NOTE: It appears this can be done with Cloud Shell, avoiding the need for a VM.

To begin, create your IAP enabled External Load Balancer within GCP, and a VM instance within the same network to connect to. It should be in the same project as the IAP enabled load balancer. IMPORTANT: When creating the VM, select Allow full access to all Cloud APIs within Identity and API access>Access scopes.

SSH into the VM [or Cloud Shell], and use that session for shell commands through the rest of the process.

Variables

We will prepare the following environment variables (or substitute values manually later):

BEARER_TOKEN = OAuth token used in curl API calls
PROJECT_ID = ID for the compute project
INSTANCE_ID = ID for the IAP instance
IAP_NAME = Name for the IAP instance

Signed Header JWT Audience

  • Go to GCP Console -> Security -> Identity-Aware Proxy
  • Find the instance that needs CORS, click the three vertical dots button on the far right, Select Signed Header JWT Audience
  • The popup should contain the path: /projects/[PROJECT_ID]/global/backendServices/[INSTANCE_ID]
  • Save off the PROJECT_ID and INSTANCE_ID by running shell commands in the VM: PROJECT_ID=<PROJECT_ID> and INSTANCE_ID=<INSTANCE_ID>

Shell Commands

  1. First we save the PROJECT_ID and INSTANCE_ID from the previous step into environment variables (replace with the real values)
PROJECT_ID=<PROJECT_ID>
INSTANCE_ID=<INSTANCE_ID>
  1. Next we get an OAuth token used to make the change. Note that you need sufficient permissions to perform this operation. Note that we do NOT use export when saving this environment variable; it's only accessible within the shell session, and not to other applications.
BEARER_TOKEN=`gcloud auth application-default print-access-token`
  1. Next we can construct the name/path used in the api:
INSTANCE_NAME="projects/${PROJECT_ID}/iap_web/compute/services/${INSTANCE_ID}"
  1. Next we query to check the current setting:
curl --request GET --header "Accept: application/json" --header "Content-Type: application/json" --header "Authorization: Bearer ${BEARER_TOKEN}" "https://iap.googleapis.com/v1/${INSTANCE_NAME}:iapSettings"
  1. Now we build the json for the body of the update request:
SETTINGS_BODY='{"name":"'${INSTANCE_NAME}'","accessSettings":{"corsSettings":{"allowHttpOptions":true}}}'
  1. We're now ready to update the setting:
curl --request PATCH --header "Accept: application/json" --header "Content-Type: application/json" --header "Authorization: Bearer ${BEARER_TOKEN}" --data ${SETTINGS_BODY} --compressed "https://iap.googleapis.com/v1/${INSTANCE_NAME}:iapSettings"

This should return the updated setting, similar to the output from step 5, but with the new value.

ENJOY!