Achieving Zero-Trust Access on GCP with Azure AD, IAP, and nginx Ingress


Introduction
Building secure public access to internal apps — without a VPN — is a common challenge in modern cloud environments. During one of my recent projects, I needed a secure and scalable way to expose internal web tools (like ArgoCD and Grafana) across multiple environments (DEV, QA, PROD). The solution had to support:
SSO via Azure Active Directory
Fine-grained, host-level access control
A VPN-free experience
Low operational cost
To solve this, I designed and deployed a cloud-native architecture using Google Cloud Identity-Aware Proxy (IAP), Workforce Identity Federation, and nginx ingress in GKE. Here's how it works and how you can build a similar setup.
The Challenge
I needed engineers and stakeholders to access services securely via browser, without needing VPN or static credentials. Requirements included:
Azure AD SSO for all users
Access segmentation by hostname and environment
Minimal operational overhead
Centralized IAM policy management
The Architecture
Here's the stack:
Azure AD groups and users
Google Workforce Identity Federation
GCP Identity-Aware Proxy
HTTP(S) Load Balancer
Dedicated nginx ingress controller ("gateway")
Kubernetes ingress routing per service
Workforce Identity Federation is configured at the GCP organization level. It allows to use Azure AD as an identity provider through an enterprise application (SAML) or app registration (OIDC). Entreprise applications and app registrations are configured in Azure. A single one of those is required for all environments (DEV, QA, PROD) and access is managed with GCP IAM, only groups must be defined in Azure AD.
It is integrated with Identity-Aware Proxy, a google managed service deployed on top of a HTTP load balancer to secure public endpoints.
The HTTP load balancer points to a dedicated nginx controller called “gateway” (with a dedicated ingress class) in order to segregate user access to web endpoints from internal web service routing.
Workforce Identity Federation Setup
Here is the Configure IAP with Workforce Identity Federation guide on GCP documentation.
Workforce Identity Federation lets us use Azure AD identities in GCP IAM. A single SAML or OIDC application in Azure covers all environments.
Examples of principals:
Azure AD group:
principalSet://iam.googleapis.com/locations/global/workforcePools/my-azure-ad/group/3a6f1b72-4c90-4310-94d8-6c4b5e1d21ff
Azure AD user:
principal://iam.googleapis.com/locations/global/workforcePools/my-azure-ad/subject/thibaut.tauveron@mycompany.com
These are assigned IAM roles in GCP with conditions to control access by hostname.
Protecting Ingress with IAP
Each Kubernetes cluster exposes a public service via a GCP HTTP(S) Load Balancer frontend by IAP. The Load Balancer forwards traffic to the nginx ingress controller using a dedicated class nginx-gateway
.
IAP enforces authentication before any request reaches Kubernetes, acting as a security gate at the edge. When used with the HTTP(S) Load Balancer, it also enables detailed HTTP access audit logging — giving you visibility into who accessed what, and when.
nginx Ingress and Routing
Sample ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx-gateway
nginx.ingress.kubernetes.io/proxy-buffer-size: 16k
nginx.ingress.kubernetes.io/proxy-buffering: on
nginx.ingress.kubernetes.io/proxy-buffers-number: 8
name: argocd
spec:
rules:
- host: argocd.dev.access.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
DNS:
A *.dev.access.mycompany.com 34.25.36.27
All environment subdomains resolve to their respective Load Balancer IP (the nginx ingress controller).
Host-Based Access Control with IAM Conditions
GCP IAM Conditions let us control access per ingress host:
Principal: principalSet://iam.googleapis.com/.../group/<group-id>
Condition: request.host == "argocd.dev.access.mycompany.com"
This ensures access is scoped to a specific app and environment.
Cost Efficiency
In GCP, there’s a flat rate for the first 5 forwarding rules per project : $0.025 / 1 hour, that’s roughly $220/year. With three environments, the total is <$1000/year. That said, you’re probably already using 1 or 2 forwarding rules in your project, so the additional one wouldn’t cost more.
Compared to tools like Teleport, which cost significantly more, this solution is both secure and budget-conscious.
Lessons Learned
It takes some upfront work to set up federation correctly, but the long-term payoffs in clarity and control are huge.
nginx + IAP allows a clean separation between auth and routing.
IAM Conditions are a powerful and underused tool.
When the login experience is seamless and access is predictable, federation can be introduced with little resistance.
Conclusion
If you're running on GCP with Azure AD, this pattern gives you zero-trust, hostname-level access control — without needing a VPN or additional third-party tools.
Secure, scalable, and surprisingly affordable.
Subscribe to my newsletter
Read articles from Thibaut Tauveron directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Thibaut Tauveron
Thibaut Tauveron
👋 Hi, I’m a cloud engineer and cybersecurity enthusiast based in Zürich. I’ve worn many hats over the years—developer, DevOps consultant, SRE, cloud architect—and what ties it all together is a passion for building secure, scalable systems that just work. I write about cloud infrastructure, DevSecOps, and anything that helps teams move faster without breaking things. I believe in automation, simplicity, and sharing knowledge—whether through blog posts, open source, or mentoring.