Table of Contents

    Book an Appointment

    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