Migrating from NGINX Ingress to Pomerium does not require a disruptive rewrite. Most teams adopt Pomerium incrementally, starting with internal services where the security and operational gains are immediate. An initial objective can be to decouple routing from access control for internal services. Step 1: Identify Internal Services Begin by inventorying services that: Are not intended for public access Currently rely on VPNs or basic auth Contain sensitive data or administrative controls Common examples include Grafana, Argo CD, GitLab, Prometheus, and internal APIs. Step 2: Restrict Network Access Ensure that these services are only reachable from Pomerium: Update Kubernetes NetworkPolicies Adjust security groups or firewall rules Remove public ingress exposure This guarantees that all access flows through the identity-aware layer. Step 3: Configure Identity and Policies Define access policies using identity claims rather than IPs. Example: Authentication is handled by your IdP; authorization is enforced by policy. Step 4: Validate Access and Audit Logs Test access with different user roles and verify that: Unauthorized users are denied Authorized users can access services seamlessly Audit logs capture identity, resource, and decision context Step 5: Decommission VPN Access As confidence grows, teams often reduce or eliminate VPN usage for internal tools, shrinking their attack surface and simplifying operations. The End State In the end state: Access control is centralized Policies are explicit and auditable Internal services are simpler The blast radius of compromised credentials is dramatically reduced Migration Patterns That Work Well Successful migrations tend to: Start small Focus on internal tools Run ingress and identity-aware access side by side Expand coverage gradually The result is a cleaner architecture where access control is centralized, explicit, and auditable.