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/[email protected]
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.