Exposing an app via Identity Aware Proxy(IAP) on GKE

Snigdha Sambit Aryakumar
6 min readNov 29, 2023
https://cloud.google.com/iap/docs/concepts-overview

Introduction

If we have any internal systems or applications that we run at our organisation, which we want to be able to access from outside we can use Google’s Identity-Aware Proxy (IAP)!

IAP implements Google’s BeyondCorp security model. The goal of IAP is to get rid of corporate VPNs: the bane of the existence of office workers all around the world. In this model, corporate applications are accessed through a proxy that deals with authenticating and authorizing the user. That proxy is available directly on the Internet, removing the need for a VPN. When accessing an application behind IAP, the user is authenticated, authorized, and the connection is encrypted (with SSL).

Prerequisite

Security is an essential aspect of any IT assembly and securing your application is a must. We will be discussing how to secure your front end application deployed on GKE using IAP. So, let’s see what the prerequisites are:

  • Your application deployed on GKE.
  • Domain, e.g. example.com
  • An inbuilt Ingress controller of GKE. Or you can also use an external Ingress controller (like Nginx).
  • Assuming that you should have already deployed your application on GKE and created a NodePort/ClusterIP service to expose your deployment.
  • GKE has an inbuilt Ingress controller, which creates a global reserved IP address which will be utilized by HTTPS load balancer using the following command:
gcloud compute addresses create <strong>app-gke-ip</strong> –global
  • Now, create an Ingress using the YAML code given below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gke-ingress # name you want
namespace: gke # Namespace
annotations:
kubernetes.io/ingress.allow-http: "false" # Allow only https connections
kubernetes.io/ingress.global-static-ip-name: app-gke-ip # Put the global reserved address name created in 3rd step
networking.gke.io/managed-certificates: ssl-cert # Put ssl certificate name created in 4th step
kubernetes.io/ingress.class: gce
spec:
rules:
- host: test.example.com # Domain you used for ssl ceritficate
http:
paths:
- path: /*
pathType: Prefix
backend:
service:
name: gke-svc # This would be a NodePort/ClusterIP service you created for app
port:
number: 8080 # This is a service Port you defined in service yaml spec
  • This Ingress will create an HTTPS load balancer. Put this load balancer’s IP in the DNS record of type A. Recordset will look like test.example.com == Ip of the load balancer. It will take some time for the Google-managed certificate to be active.
  • Once that is done, you can access app URL, i.e. test.example.com with HTTPS connection.

Enabling IAP

OAuth consent

To enable the IAP, you need first to configure the OAuth consent screen. If you still haven’t configured the OAuth consent screen, you can do so with an email address and product name.

  1. Firstly, visit the OAuth consent screen.
  2. Then, under the support email section, just select the email address you want to display as a public contact.
  3. Ensure that the email address you mention should be yours or of a Google group that you own.
  4. Just need to enter the application name that you want to be displayed and add the optional details according to your choice.
  5. After this, click on the Save button

OAuth credentials

Now we need to create the OAuth credentials.

  1. Please visit the Credentials page.
  2. Select the OAuth client ID from the Create credentials drop-down list and then select web application from the application type.
  3. Next, add a name for your OAuth client ID and click create.

4. Once you click on creating your OAuth client ID and client secret gets generated and displayed on the OAuth client window.

5. Now, click on Ok and select the client created by you.

6. After this, copy the client ID to the clipboard, and now it is time to add the universal redirect URL to the authorized redirect URLs field.

7. Click on the download JSON located on top of the page. You can use the credentials in the later stage.

IAP Access

Now let’s set up the IAP access.

  1. Please visit the Identity-Aware Proxy page.
  2. Now, select a project that you want to secure with IAP and then select the checkbox located next to the resource where you want to add the members.
  3. On the right side, there is a panel, click add member.
  4. Once the add members dialog appears, just enter the email addresses of groups or individuals who should have the IAP-secured Web App User for the project.
  5. The members should belong to either of the following accounts:
    1. Google Account: user@gmail.com
    2. Google Group: admins@googlegroups.com
    3. Service account: server@example.gserviceaccount.com
    4. G Suite domain: company.com
  6. Make sure you add a Google Account that you have access to.
  7. Select Cloud IAP>IAP, then secured Web App User from Roles’ drop-down list and then click Save.

Configure Backend Config

Please be aware that if some parameters for the health check are incorrect this will result in that the backend config is no longer being used for the health check and that the k8s service parameters will be used for path, port and other values. This can result in undesirable failure of the health check and service unavailability.

Now, let’s configure the BackendConfig for IAP.

  1. First, create a Kubernetes Secret.
  2. To create a secret, run the following command where client_id_key and client_secret_key are the keys from the JSON file that you downloaded when you created OAuth credentials:
kubectl create secret generic my-secret --from-literal=client_id=client_id_key \

--from-literal=client_secret=client_secret_key

3. After this add an IAP block to your BackendConfig; the BackendConfig will use a Kubernetes Secret to wrap your OAuth client that you have created earlier.

4. Specify the enabled and secretName values to configure the BackendConfig for IAP. While specifying these values, make sure that you have the permission to compute.backendServices.update. Now, add the IAP block to BackendConfig. In this block, my-secret is the Kubernetes Secret name that you have created earlier:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: config-default
namespace: my-namespace
spec:
iap:
enabled: true
oauthclientCredentials:
secretName: my-secret

5. Set up health checks for your backend service

spec:
healthCheck:
checkIntervalSec: 5
timeoutSec: 5
healthyThreshold: 2
unhealthyThreshold: 3
type: HTTP
requestPath: /app

6. To trigger the IAP, you just have to associate the service ports with your BackendConfig. One method to make this association is by making all the service ports default to your BackendConfig, and this can be done by adding the annotation given below to your service resource:

metadata:
annotations:
beta.cloud.google.com/backend-config: '{"default": "config-default"}'

See documentation on several examples on how to configure the backend config. https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#associating_backendconfig_with_your_ingress

Test your configurations

To test the configuration, run kubectl get events. If you get this message “no BackendConfig for service port exists”, then it means that you have correctly associated a service port with your BackendConfig. Still, the BackendConfig resource was not found. This error can occur in the event of fone of the following scenarios:

  • Haven’t created the BackendConfig resource
  • Created it in the wrong namespace
  • Misspelled the reference in the Service annotation.

If the secretName that you referred to doesn’t exist or isn’t structured correctly, then one of the following error messages will be displayed:

  • BackendConfig default/config-default is not valid: error retrieving secret “foo”: secrets “foo” not found. Ensure that you have created the Kubernetes Secret correctly, as mentioned in the previous section, to solve this error.
  • BackendConfig default/config-default is not valid: secret “foo” missing client_secret data. Ensure that you have created the OAuth credentials properly to solve this error. This also ensures that you referred to the correct client_id and client_secret keys in the JSON that you downloaded earlier.

When the enabled flag is set to true, and the secretName is correctly set, then the IAP gets configured for your selected resource. After the IAP gets configured, app deployed on GKE using IAP is secured.

--

--

Snigdha Sambit Aryakumar

Technical Lead @ Travix International | Helps building and delivering software faster