Exposing Argo CD with NGINX ingress controllers

Argo CD needs its web UI and gRPC CLI reachable through one ingress path with a clear TLS decision. This page explains how to choose passthrough or termination on NGINX and what to plan before you publish it.

On this page

Exposing Argo CD with NGINX ingress controllers: when you need it and what it decides

If you are installing Argo CD in your own cluster, you need an ingress path when people and automation outside the cluster must reach the web UI and the argocd CLI. NGINX is one common way to publish both, but the choice comes down to two decisions: which NGINX controller you run, and where TLS ends. Those two choices determine the Ingress objects you create, whether the API server runs with TLS of its own, and how the CLI's gRPC traffic reaches it. Settle them before you write any manifests, because changing the TLS point later usually means reworking the routing and the certificate setup together.

The Argo CD ingress guide covers two families of NGINX. The first is the community kubernetes/ingress-nginx controller, which the guide documents as deprecated. It supports either SSL passthrough, where NGINX forwards encrypted traffic to Argo CD unchanged, or TLS termination, where NGINX holds the certificate and talks to Argo CD over an internal connection. The second is the F5 NGINX Ingress Controller, which the guide documents as needing HTTP/2 enabled and separate Ingress objects for HTTP and gRPC. Read the guide for the exact annotations and settings for each option, and confirm with your platform team which controller your cluster already runs and whether its support window covers your plan.

Whichever path you pick, the TLS point decides the server configuration. Passthrough keeps the certificate on Argo CD's API server, while termination usually means setting server.insecure in the argocd-cmd-params-cm ConfigMap so the server does not expect TLS from the ingress. Ask who will issue and rotate the certificates, which hostnames users and CI jobs will use, and whether your network policy allows the CLI's gRPC calls through to the cluster. Those answers shape the rest of the install, so record them in your design notes before you choose an installation method.

Which NGINX controller you are running and what it changes

The Argo CD ingress guide documents kubernetes/ingress-nginx and notes that it is deprecated. It supports two patterns. In SSL passthrough, NGINX forwards encrypted traffic to the Argo CD server, which terminates TLS itself. In TLS termination, NGINX ends TLS and forwards plain HTTP to the server, which requires server.insecure to be set. The pattern you choose decides how both the web UI and the CLI's gRPC traffic reach the API server, so it shapes the whole design.

  • Passthrough keeps one hostname simple. A single host can serve the UI and gRPC because the server handles both behind the same TLS session.
  • Termination moves certificates to the controller. Certificates are managed at NGINX, and the Argo CD server runs without its own TLS listener.
  • server.insecure must match the pattern. Set it only when NGINX terminates TLS, and confirm that the internal path between NGINX and the server is trusted by your network policy.
  • Passthrough is a controller-level setting. Enabling it changes how the controller handles traffic for every ingress it serves, so the platform team should approve it.
  • Deprecation is a planning item. It remains documented, but you should confirm its maintenance outlook before standardizing on it for a long-lived installation.

Before building, confirm the controller's current support status with the controller project and check whether your platform team allows passthrough.

TLS and server options compared for NGINX

This table compares three ways to publish Argo CD through NGINX: SSL passthrough, TLS termination at NGINX with server.insecure, and separate gRPC and HTTPS hostnames. Read each row against your controller, how your CLI users connect, and who owns the certificates. The main takeaway is that the CLI's gRPC path shapes the choice more than the browser path does, so confirm that path first.

OptionController fitWhat the CLI needsCertificate ownershipMain risk
SSL passthroughkubernetes/ingress-nginx (deprecated); confirm the passthrough setting for your controller versionReaches the Argo CD TLS endpoint directly; confirm the CLI flags for your hostnameArgo CD serves the certificate, so the cluster team manages it inside Argo CD's TLS setupNGINX cannot inspect or route by path, and the certificate must match the single hostname exposed
TLS termination at NGINX with server.insecurekubernetes/ingress-nginx (deprecated) per the ingress guide; confirm the backend protocol annotationsConfirm whether the CLI uses gRPC over HTTPS through the same ingress and whether grpc-web fallback is neededNGINX holds the public certificate; traffic between NGINX and Argo CD is plain unless you add re-encryptionUnencrypted hop inside the cluster; confirm network policy and the owner of the NGINX certificate secret
Separate gRPC and HTTPS hostnamesF5 NGINX Ingress Controller, which needs HTTP/2 enabled and two Ingress resourcesA dedicated gRPC hostname with HTTP/2 support, separate from the browser hostnameTwo certificates or one certificate covering both names; confirm which secrets each Ingress referencesMismatched host rules or a missing HTTP/2 setting can break CLI logins while the UI still loads
Choice of controllerCheck which NGINX controller your platform team runs before choosing a rowAsk the team that operates the cluster which controller and version is in useOwned by the team that runs the ingress and its TLS secretsBuilding on the deprecated controller without a migration plan
Browser accessAll three options can serve the UI; the difference is in how traffic reaches Argo CDBrowser login uses the web path onlyPublic hostname certificate must be renewed on scheduleExpired certificates block logins for both UI and CLI
Who to confirm withPlatform team for the controller, security team for certificate policyEngineers who run argocd login in automationCertificate authority and renewal ownerAssumptions about CLI flags that differ by Argo CD version

Publishing Argo CD through NGINX step by step

This sequence takes Argo CD from an installed API server to a published UI and CLI path through NGINX, with a check at each stage so the team knows the route works before anyone relies on it. The output is a reachable HTTPS endpoint for browsers and argocd login, with the TLS choice and controller settings documented for the next change.

  1. Confirm the ingress controller and its HTTP/2 setting

    The platform engineer identifies which NGINX controller runs in the cluster, because kubernetes/ingress-nginx and the F5 NGINX Ingress Controller have different annotations and gRPC requirements. For the F5 controller, confirm that HTTP/2 is enabled in its configuration, as the Argo CD ingress guide requires. Check the controller version and its deprecation status against the upstream project before you build anything on it. Done means you can name the controller, its version and whether HTTP/2 is on, and you have written those facts into the change record.

  2. Choose passthrough or TLS termination

    The team decides where TLS ends. With SSL passthrough, NGINX forwards encrypted traffic to the Argo CD server, which keeps its own certificate and serves both the UI and gRPC on one hostname. With TLS termination, NGINX holds the certificate and forwards to the server over plain HTTP, which needs separate HTTP and gRPC routes. Record the choice with the reason, such as how certificates are issued in your environment and whether the security team needs to inspect traffic at the edge. Done means one written decision that the remaining steps follow.

  3. Set server.insecure only when terminating TLS

    If the choice is termination, the administrator sets server.insecure to true in the argocd-cmd-params-cm ConfigMap so the Argo CD server accepts plain HTTP from NGINX, then restarts the server deployment. If the choice is passthrough, leave this setting off so the server keeps its TLS endpoint. Verify the setting with a read of the ConfigMap and confirm the server pod has rolled out. Done means the configured value matches the TLS decision in the previous step, and nothing else in the cluster depends on an insecure server.

  4. Create the HTTP Ingress

    The administrator creates an Ingress for the argocd-server Service on the chosen hostname. For passthrough, the Ingress uses the controller's SSL passthrough annotation and the server's HTTPS port. For termination, it references a TLS secret and points to the HTTP port. Apply the manifest through your normal GitOps or change process and confirm the controller reports the Ingress as synced. Done means the Ingress has an address, the hostname resolves to it, and the controller logs show no rejected configuration for the resource.

  5. Create a separate gRPC Ingress on F5 NGINX

    When the F5 NGINX Ingress Controller is in use, the Argo CD ingress guide calls for a second Ingress dedicated to gRPC, because the CLI traffic needs HTTP/2 routing that differs from the browser route. Create it with the gRPC-specific annotations for the controller and the same hostname or the hostname your CLI users will target. With kubernetes/ingress-nginx, confirm whether a single Ingress with the required annotations is sufficient for your setup, and check the upstream guide before relying on it. Done means both routes exist, each shows as healthy in the controller, and you can list them with kubectl.

  6. Issue, install and plan rotation for certificates

    The platform team obtains the certificate from your internal CA or public issuer, installs it as a Kubernetes TLS secret in the namespace NGINX reads, and records its expiry date and owner. For passthrough, the certificate lives on the Argo CD server instead, so confirm which secret the server mounts. Set a rotation process that the change owner can run before expiry, and test renewal in a non-production cluster first. Done means the certificate chain validates for the hostname, the expiry date is recorded, and a named owner can renew it.

  7. Verify UI and CLI login through argocd login

    The operator opens the Argo CD hostname in a browser and confirms the login page loads over HTTPS with the expected certificate. Then they run argocd login against the same hostname, adding the flags that match your TLS choice and gRPC route, and confirm the CLI returns a successful session. Run argocd account get-user-info after logging in to confirm the identity. If the browser works but the CLI fails, check the gRPC Ingress and the TLS mode before changing anything else. Done means a browser session and a CLI session both authenticate against the published endpoint.

Why the TLS termination point changes the CLI and certificate work

The TLS termination point decides who holds the certificate, who handles the gRPC traffic, and which Argo CD settings you must change. With SSL passthrough, NGINX forwards the encrypted connection to the Argo CD API server without reading it, so TLS stays end to end and the API server presents the certificate for the hostname. Certificate issuance, renewal and any custom CA trust for the Argo CD endpoint then live in the Argo CD server configuration and the cluster, and the API server keeps its default TLS behavior. Passthrough is the simpler path when you want one hostname and no change to the server's transport settings, but it depends on NGINX passthrough being enabled on the controller you run.

With TLS termination, NGINX holds the certificate, decrypts the browser and CLI traffic, and forwards it to the API server over plain HTTP. That is the reason the API server must run with server.insecure set to true in the argocd-cmd-params-cm ConfigMap, and the reason the internal hop must be treated as a trusted network segment. Certificate renewal moves to the ingress layer. gRPC is the part most likely to break in this model: the Argo CD CLI uses gRPC, which needs HTTP/2 between the client and the proxy, and the F5 NGINX Ingress Controller requires HTTP/2 enabled and a separate gRPC Ingress alongside the HTTP one. Confirm the exact annotations and backend protocol settings for your controller version in the Argo CD ingress guide.

Test the CLI against the published hostname, not only the web UI. A browser can load the UI over HTTP/1.1 while argocd login fails, times out or reports a certificate error, because the CLI negotiates gRPC differently. Run a login with the ingress endpoint, a list of applications and a read of one application, and record which hostname and flags the CLI needs. Also confirm that gRPC requests reach the gRPC path and not the web path after any proxy change, since a misrouted request often shows up only in CLI output. Plan the CLI test as a gate in your change, and rerun it after each controller or certificate update.

Security controls to plan at the NGINX edge

The ingress layer is the first gate in front of the Argo CD API server and UI, so it inherits part of the security model. The cards below cover the controls to decide before publishing the host: how TLS is carried, who owns certificates, who can reach the login page, how the built-in admin user is retired, and what the ingress records.

Keep the JWT and TLS model intact

The Argo CD security documentation says the API authenticates requests only with JSON Web Tokens and uses TLS for traffic, including between its own components. Terminating TLS at NGINX is a valid choice, but it changes where the encryption ends. Confirm whether the hop from NGINX to the Argo CD pods stays encrypted, and whether server.insecure is set only because TLS is ended at the edge, so the reasoning is documented.

Assign certificate lifecycle ownership

Whoever terminates TLS owns the certificate, its renewal and its private key. With passthrough, Argo CD's own certificate is the one clients see, so the platform team manages it in the cluster. With termination, the edge certificate is separate from any internal one. Name the owner of each certificate, the renewal process, and the alert that fires before expiry, because an expired certificate on the gRPC host breaks CLI logins as well as the UI.

Restrict who can reach the UI

The ingress is the place to limit exposure of the login page and the API. Decide whether the host is reachable from the public internet, a corporate network or a VPN only, and enforce that with network policy, load balancer rules or NGINX allow lists. Confirm that the gRPC host follows the same restriction, since CLI traffic often reaches a different path than the browser.

Disable the built-in admin user

The user management documentation recommends using the built-in admin account only for initial setup. Once local users or SSO are configured, set admin.enabled to false in argocd-cm. Before doing this, confirm that at least one SSO group maps to an administrator role, and that a break-glass path exists outside Argo CD, so a login outage does not lock out the team.

Record access at the ingress

NGINX access logs show which client addresses reached the login page and API, and when. Argo CD's own audit trail covers actions inside the application, but it may not show failed requests that never reached the server. Decide where the ingress logs are sent, how long they are kept, and whether they include the client address, host and status code. Confirm that logs redact tokens and credentials, since the Argo CD security documentation says credentials are redacted from its own logs.

Questions teams ask before exposing Argo CD through NGINX

Should we use TLS passthrough or TLS termination for Argo CD?

Choose passthrough when you want Argo CD's own server to hold the certificate and serve HTTPS end to end, and termination when the ingress layer must hold certificates, apply policy, or serve separate hostnames for the UI and gRPC. The driver is usually who owns certificate issuance and renewal, and whether your security team needs to inspect or filter traffic at the ingress. Passthrough keeps one hostname and fewer moving parts. Termination needs the ingress to forward gRPC correctly and a clear answer on TLS between the ingress and Argo CD, which is where server.insecure often comes into the design. The community kubernetes/ingress-nginx controller is deprecated, so confirm its support status before you build on it. The Argo CD ingress guide documents both approaches for that controller and for the F5 NGINX Ingress Controller.

Does the Argo CD CLI work through the same hostname as the UI?

It can, but only if the ingress routes gRPC correctly alongside the web UI. The CLI speaks gRPC, which needs HTTP/2 between the client and the server. With the F5 NGINX Ingress Controller, the Argo CD ingress guide calls for HTTP/2 to be enabled and for separate HTTP and gRPC Ingress resources, so one hostname can serve both through distinct routing rules. With passthrough, the TLS session reaches Argo CD intact, so gRPC usually works without extra routing. Test the CLI with a login and a list command after every ingress change, because a configuration that serves the UI correctly can still fail for argocd login. If a path or header rule breaks the CLI, confirm the exact controller annotations for your version in the guide rather than copying settings from older examples.

How much effort does exposing Argo CD through NGINX take?

The effort depends on four drivers: the ingress controller you run, the TLS policy you choose, the number of hostnames, and whether SSO sits in front of the UI. A single hostname with passthrough on a cluster that already has a working controller is the smallest case. Termination with separate gRPC and HTTPS hostnames, certificates from an internal authority, and an SSO callback that must match the public URL add configuration and test cycles. Each added hostname also adds DNS records, certificate subjects and firewall rules. No duration is fixed by the project, so ask any partner to break the estimate into these drivers and to state which controller and version the plan assumes. Your own team can estimate the work by listing the same items for your environment.

Can our own team expose Argo CD without outside help?

Yes, if your team controls the cluster, can change the ingress configuration, and owns the certificate process. Those three things cover most of the work. The harder parts are usually not the YAML: they are agreeing on where TLS ends, confirming the controller's support status, and testing gRPC and SSO after each change. Teams that run Argo CD in production often keep a short written runbook covering the chosen design, the certificate renewal path and the CLI test. If you lack one of the three ownership points, for example no one can issue certificates for the gRPC hostname, the project will stall there. Outside help is one option for the design and first deployment, and your team can then operate the result.

What does the exposure work need from our team?

Plan for access and decisions before any change is made. You will need cluster access with rights to read and change the Argo CD namespace, the ingress controller and its configuration, and the ability to deploy into a test namespace or cluster first. DNS changes must be possible for each hostname you plan to publish. You need a certificate authority or an issuance process that can sign certificates for those names, along with a decision on whether the chain is public or internal. Agree on a test window with the teams that use Argo CD, because the UI and CLI may be briefly unavailable during cutover. Confirm the identity provider's callback URLs with the people who own it, since SSO redirects must match the final hostname.

Can DeployOpen quote this as a fixed-scope engagement?

Yes. DeployOpen plans, implements and hardens self-hosted open-source platforms inside your own infrastructure, and most engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts. For this topic, a written scope would name the controller and version, the TLS design, the hostnames, the SSO integration if any, the test plan and the handover. DeployOpen does not publish a price list, so a quote follows from that written scope. Ask for the quote to list what is included, what you must provide, and what is excluded, such as certificate authority work or identity provider changes. Ongoing support and upgrades are available as a separate retainer.

What to test and operate once Argo CD is reachable

Reachability is not the same as working. Once the ingress is live, test the path a real operator uses: open the UI hostname in a browser and sign in through SSO or a local account, then confirm that the group mapping gives the expected role and no more. Log in with the argocd CLI against the gRPC hostname or path, then run a sync on a low-risk application. The CLI test matters most for ingress, because the browser can work while gRPC fails. If you terminate TLS at NGINX, confirm that the gRPC route carries HTTP/2 and that the separate gRPC Ingress is the one matched for CLI requests. If you run server.insecure, confirm that the API server is not reachable on a plaintext path from outside the cluster. Record which hostnames, ports and certificate chain each test used so the next person can repeat it.

Certificate expiry is an operations item, not a one-time setup step. Add expiry monitoring for every certificate the ingress presents, and for the backend certificate if you use passthrough, since the Argo CD API server serves it directly. Alert well before expiry and confirm that renewal, such as cert-manager or your internal CA process, updates the Secret that the Ingress references. Confirm, too, that the CLI and any webhook senders trust the chain after renewal. Plan a controller upgrade as a change to the exposure. Read the upgrade notes for the Argo CD version you are moving to, including the Argo CD 2.14 to 3.0 upgrade notes, because RBAC and tracking changes can alter what users see after login. Then check the ingress-nginx or F5 NGINX controller release notes for changes to annotations, the default TLS behavior and the gRPC settings. Re-run the login and sync tests after each change.

Keep the ingress manifests in Git with the rest of the Argo CD configuration. The Ingress or VirtualServer objects, the TLS Secret references, the server.insecure setting in argocd-cmd-params-cm, and the argocd-server service definition should be reviewed through the same pull request flow as application changes. A reviewer can then see when a hostname was added, when TLS moved from passthrough to termination, or when an annotation changed the timeout for long-running gRPC streams. Ask your platform team to confirm where the controller and its values file are stored and who can merge changes to them, because a change to the ingress can expose the login page to a new network. Keep a note of the controller version alongside the manifests so that a rebuild in another cluster starts from the same exposure you tested.

How DeployOpen scopes and delivers an Argo CD ingress setup

DeployOpen plans and implements the Argo CD UI and gRPC CLI publishing path inside your own clusters and network, starting from a written scope. The work covers the ingress controller choice, the TLS model, the separate gRPC route, and the operating notes your team needs after handover.

How we scope

  • Confirm which NGINX ingress controller your clusters run and whether it is the community or F5 NGINX product
  • Record the TLS model, passthrough or termination, and who owns certificate issuance and renewal
  • Agree in writing which hostnames, CLI access paths and SSO flows are covered

How we build

  • Configure Ingress or controller resources for the UI and a separate gRPC route with HTTP/2 enabled
  • Set server.insecure only where TLS ends at the ingress, and document the trust boundary
  • Test CLI login, UI access and gRPC sync calls from the networks your users actually use

How we hand over

  • Deliver the manifests or Helm values, the configuration record and a tested runbook for changes
  • Document the upgrade path for kubernetes/ingress-nginx, noting its deprecated status, and the alternative controller path
  • Walk your platform and security teams through verification steps and the failure checks they will repeat

How we support

  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts
  • Ongoing support, upgrades and continuous testing are available as a retainer
  • Quotes follow from the written scope, so confirm controller version, cluster count and hostname plan first

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.