How Did We Discover the Need for a Private EKS ArgoCD Setup?
While working on a massive infrastructure modernization project for a fast-growing FinTech platform, our team encountered a critical security compliance mandate. The client’s engineering team was utilizing the AWS Elastic Kubernetes Service (EKS) managed ArgoCD capability in public mode. It was a highly efficient setup, fully integrated with their corporate Single Sign-On (SSO) provider to manage developer access. However, a routine security audit flagged a major concern: the ArgoCD control panel was accessible over the public internet.
The mandate was clear—we needed to restrict ArgoCD access strictly to the company’s corporate IP addresses, moving the internal EKS communication to private subnets without losing the seamless SSO experience that the development teams relied on. When enterprises look to hire software developer teams for infrastructure scaling, handling these nuanced security-versus-usability trade-offs is where true engineering maturity shines.
Our initial thought was to simply switch EKS to a private endpoint. However, if you isolate ArgoCD completely, external SSO Identity Providers (IdPs) can no longer reach the callback URLs, breaking authentication. We realized we needed an architecture that utilized a private VPC endpoint for internal cluster management while safely exposing the ArgoCD UI through an AWS Application Load Balancer (ALB) locked down by IP restrictions. This challenge inspired this article, providing a blueprint for teams facing similar Zero-Trust compliance hurdles.
Why is Securing AWS EKS ArgoCD Behind a Public ALB So Challenging?
In a standard cloud-native architecture, ArgoCD operates within the Kubernetes cluster and exposes a unified UI and API server. When operating in public mode, ingress controllers natively handle traffic routing and SSO providers (like Okta, Auth0 or Azure AD) easily resolve the redirect URIs.
The architectural friction occurs when you attempt to lock this down. The business use case requires that only developers operating from whitelisted corporate IPs can reach the ArgoCD login screen. However, you cannot simply put the ArgoCD service in a private subnet and expect OIDC (OpenID Connect) authentication to work smoothly. The authentication flow requires the browser to redirect to the IdP and then return a token to an externally resolvable ArgoCD callback URL.
This creates a routing paradox: ArgoCD must be private to satisfy security, but its callback endpoint must be resolvable via a public DNS record routed through a load balancer. Misconfiguring this architecture leads to broken CI/CD pipelines, locked-out developers and deployment bottlenecks.
What Happens When You Restrict ArgoCD IP Access Improperly?
During our initial diagnostic phase, we observed several failure points when naively transitioning from a public to a private ArgoCD setup.
First, when we deployed an internal-only ALB and routed traffic through an NGINX reverse proxy inside EKS, remote developers outside the corporate VPN immediately lost access. More critically, when we adjusted the ALB to be internet-facing with AWS Security Group IP restrictions, the SSO integration failed. Users would click “Login via SSO”, successfully authenticate at the IdP and then be redirected into a black hole—or worse, an infinite HTTP 302 redirect loop.
The logs inside the ArgoCD server pods revealed `oauth2: cannot fetch token: 400 Bad Request`. This occurred because the TLS termination was happening at the AWS ALB level, passing unencrypted HTTP traffic to the NGINX ingress controller. ArgoCD, expecting a secure HTTPS connection for OIDC callbacks, detected a protocol mismatch between the originally requested `https://` URL and the internal `http://` routing. Furthermore, the ArgoCD CLI, which relies heavily on gRPC, began throwing connection reset errors because the load balancer was not correctly configured to route HTTP/2 traffic.
How Can Engineering Teams Design a Secure ArgoCD Architecture?
To resolve this, we mapped out multiple architectural paths. When companies hire cloud developers for secure infrastructure, they expect a thorough evaluation of tradeoffs rather than a brute-force fix.
Did We Consider Using a Client VPN with Internal Ingress?
The most traditional approach is to place the entire EKS cluster, including the ingress controller, on a private subnet and force all developers to connect via a Client VPN. While secure, this adds immense friction. Developers dislike keeping a VPN active at all times and external CI/CD runners (like GitHub Actions) would require complex bastion host setups to trigger ArgoCD syncs.
Could We Use AWS WAF on a Public EKS Endpoint?
Another option was to keep the ArgoCD ingress public but attach an AWS Web Application Firewall (WAF) containing a strict IP match rule. While this solves the IP restriction problem, it leaves the EKS ingress broadly exposed to the internet before traffic is filtered. The security team rejected this because they wanted the compute nodes entirely isolated in a private subnet using VPC endpoints.
Why Did We Choose a Private VPC Endpoint with NGINX and ALB?
The winning architecture combined an internet-facing AWS ALB (acting as the public entry point) with an internal NGINX Ingress Controller running inside the private EKS cluster. The ALB was locked down using AWS Security Groups to only allow corporate IPs. Traffic passing the ALB was forwarded to the internal NGINX controller, which then proxied the requests to the ArgoCD services. To make SSO work, we had to carefully configure ArgoCD to trust the forwarded headers from the ALB.
How Do You Configure an EKS Private ArgoCD Behind an ALB with SSO?
Implementing this architecture requires precise configuration across AWS infrastructure and Kubernetes manifests. Here is the sanitized approach we finalized.
1. Configuring the AWS Load Balancer Controller
We deployed an Ingress resource specifically to provision the AWS ALB. Notice the annotations that enforce IP restrictions and handle TLS termination:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-alb-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/inbound-cidrs: "203.0.113.0/24, 198.51.100.0/24" # Corporate IPs
alb.ingress.kubernetes.io/backend-protocol: HTTP
spec:
rules:
- host: argocd.internal-corp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-nginx-controller
port:
number: 80
2. NGINX Ingress Controller Configuration
The ALB forwards traffic to the internal NGINX controller. We had to ensure NGINX passed the correct `X-Forwarded-Proto` headers to ArgoCD, which is critical for SSO.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-nginx-ingress
namespace: argocd
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: argocd.internal-corp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
3. Securing ArgoCD ConfigMaps for OIDC
Finally, to prevent the infinite redirect loop and ensure the SSO callback succeeded, we updated the `argocd-cm` and `argocd-cmd-params-cm` ConfigMaps. We forced ArgoCD to run its internal server in insecure mode (since TLS is terminated at the ALB) while defining the absolute external URL so the IdP knows exactly where to return the token.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
namespace: argocd
data:
server.insecure: "true"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.internal-corp.com
oidc.config: |
name: Corporate SSO
issuer: https://idp.corporate.com
clientID: argocd-client-id
requestedScopes: ["openid", "profile", "email", "groups"]
What Are the Key Takeaways for Securing EKS Delivery Pipelines?
Solving complex routing and authentication issues requires deep architectural foresight. Here are the actionable insights for engineering teams:
- Understand TLS Termination Boundaries: When putting an ALB in front of an NGINX proxy, know exactly where TLS encryption ends. If it ends at the ALB, your downstream services must be configured to accept HTTP while trusting the `X-Forwarded-Proto: https` header.
- Absolute URLs are Mandatory for SSO: Dynamic host resolution fails behind complex proxies. Always hardcode your exact external URL in the ArgoCD ConfigMap so OIDC callbacks validate successfully.
- gRPC vs. HTTP/2 Compatibility: If your developers use the ArgoCD CLI, ensure your ALB is configured to support HTTP/2 and gRPC routing; otherwise, CLI commands will hang or drop connections.
- WAF for Granular Security: If AWS Security Group CIDR limits are too rigid, consider attaching an AWS WAF to the ALB. This allows for dynamic IP rate limiting and geographic blocking.
- Isolate Ingress Controllers: Do not use the same NGINX ingress controller for internal tooling (ArgoCD) and public-facing customer applications. Maintain a dedicated internal ingress class.
How Can Your Organization Securely Scale its Kubernetes Deployments?
Restricting AWS EKS ArgoCD to private corporate IPs while maintaining SSO is a complex routing puzzle involving load balancers, ingress proxies and OIDC strictness. By terminating TLS at an internet-facing ALB restricted by security groups, routing to an internal NGINX controller and configuring ArgoCD to operate securely within a private VPC, we provided the client with a resilient, Zero-Trust compliant delivery pipeline.
Building and maintaining secure cloud-native infrastructure requires specialized knowledge. If you are looking to scale your engineering efforts, you can hire devops engineers for kubernetes management who understand these enterprise complexities. To discuss how our pre-vetted, dedicated remote teams can assist your architecture modernization, contact us.
Social Hashtags
#ArgoCD #AmazonEKS #KubernetesSecurity #DevSecOps #GitOps #AWSCloud #Kubernetes #CloudSecurity #ZeroTrustSecurity #AWSALB #SingleSignOn #OIDC #DevOpsEngineering #CloudNative #InfrastructureSecurity
Frequently Asked Questions
This usually happens due to protocol mismatch. When the ALB terminates TLS, it forwards traffic as HTTP. If ArgoCD doesn't know it is being accessed externally via HTTPS (configured via the `url` parameter in `argocd-cm`), it will attempt to redirect the SSO callback to an HTTP endpoint, which identity providers reject.
Yes, you can route directly from the ALB to the ArgoCD service pods. However, using NGINX as a middle layer often simplifies complex routing rules, custom header injection and localized path rewrites within the cluster that native ALB rules might make cumbersome.
The ArgoCD CLI utilizes gRPC. You must ensure your ALB Target Group protocol version is set to gRPC or HTTP/2. Additionally, the ingress annotations must explicitly declare `backend-protocol: GRPC` if bypassing HTTP boundaries.
Security Groups operate at the network level (Layer 4) and are cheaper and faster for strict, static corporate IP whitelisting. AWS WAF operates at Layer 7 and is better suited if you need complex, dynamic rules, geographic restrictions or active threat detection alongside your IP filters.
Yes, generally you set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap. This tells the ArgoCD server pod not to generate its own self-signed certificates, allowing the ALB (or NGINX) to handle the TLS termination cleanly without certificate mismatch errors.
Success Stories That Inspire
See how our team takes complex business challenges and turns them into powerful, scalable digital solutions. From custom software and web applications to automation, integrations, and cloud-ready systems, each project reflects our commitment to innovation, performance, and long-term value.

Recruitment Operations Automation with Offshore Software Dev Team

Hospitality Review Intelligence Product Development with Offshore AI Team



















