As Kubernetes platforms evolve, many organisations reach a point where their original architecture, optimised for speed and accessibility, no longer meets modern security expectations.
A common pattern in earlier-stage environments is to rely on:
While these approaches are widely used, they introduce long-term challenges. VPNs extend the network perimeter and add operational overhead. Bastion hosts centralised access but still exposes public IP addresses and requires ongoing maintenance. In both cases, access is still fundamentally based on network location rather than identity.
This case study explores how we designed and implemented a fully private, zero-trust Kubernetes access model that eliminates the need for public endpoints, VPNs, and bastion hosts.
At first glance, the platform appeared to follow good practices.
Clusters were provisioned using infrastructure-as-code, worker nodes were private, and deployments were handled through automated pipelines. From an operational standpoint, everything worked as expected.
However, a deeper review revealed a fundamental issue.
Although the worker nodes were private, the Kubernetes control plane remained publicly accessible. This meant:
This created a misleading situation where the clusters appeared secure, but the primary entry point remained exposed.
The Kubernetes API is the control surface for:
Even when protected by IAM and network rules, a public endpoint introduces unnecessary risk. The team needed to eliminate this exposure entirely by moving to private endpoint-only clusters.
Enabling private endpoints immediately exposed a deeper dependency.
The existing deployment workflow relied on:
Once the public endpoint was disabled:
This revealed a key architectural flaw:
The platform’s delivery model depended on the very exposure it now needed to remove.

The team also made a deliberate decision to avoid traditional solutions:
Instead, the solution needed to:
A similar challenge had already been encountered in an AWS environment, where clusters were fully private, but our engineers still needed to:
This reinforced a key insight:
Removing public access is only half the problem. The real challenge is enabling secure, controlled access back into private systems.
To address these challenges, the team implemented a multi-layered redesign, aligning the platform with zero-trust principles and removing reliance on network-based access.
The first step was to eliminate all public exposure.
Clusters were reconfigured to:
This ensured that:

With external access removed, the deployment model had to change.
Traditionally, services such as GitHub Actions and Bitbucket Pipelines run on external infrastructure and connect into the target environment to perform deployments.
The team reversed this model.
The source code remained in GitHub and Bitbucket, but the execution environment was moved inside the private network. A self-hosted CI/CD runner securely pulls the pipeline jobs and source code, then performs all deployment steps from within the VPC.
This means code stays external, but execution happens internally.
As a result:
A private CI/CD runner was deployed inside the same VPC as the cluster.
This runner:
This allowed the team to:
From a developer perspective, workflows remained largely unchanged, while security improved significantly behind the scenes.
To further strengthen the model, the team introduced GitOps principles.
Instead of relying on direct API calls:
Using Config Sync:
This creates a more resilient and secure deployment pattern.
A key part of the solution was removing reliance on network-level trust.
Instead of VPNs or bastion hosts, the team adopted identity-driven access patterns.
Access to clusters is handled through a managed API layer:
This means:
Access becomes:
In AWS, the same zero-trust objectives are achieved using a different model.
For automated deployments to private EKS clusters:
In this model, the pipeline execution environment runs inside the private network and initiates outbound connections to Bitbucket.
For engineers who need temporary access to services inside the cluster:
For example, a developer debugging a PostgreSQL instance can create a local tunnel that connects securely to the database inside the cluster without exposing it publicly.
This AWS model:
In Google Cloud, both CI/CD systems and human users access private Google Kubernetes Engine clusters through GKE Connect Gateway.
The execution environment remains external, but all access is brokered through Google's control plane and governed by Google Cloud IAM.
Although implemented differently, both AWS and Google Cloud follow the same architectural principles:
This is the foundation of a zero-trust architecture.

In Google Cloud, the control plane acts as the secure intermediary.
In AWS, trusted components run inside the private environment and establish outbound connections to external systems.
Both approaches eliminate public exposure while maintaining secure, auditable access for automation and engineers alike.

To complete the security model, outbound traffic was restricted.
A deny-by-default approach was implemented:
This ensures that workloads:
IAM was restructured to align with the new model:
This reduces risk and ensures access is granted only where necessary.
The outcome was a secure, scalable platform that aligns with modern zero-trust principles.
The platform was transformed from a traditionally secured Kubernetes environment into a fully private, identity-driven architecture based on zero-trust principles.
The new architecture significantly reduced the attack surface by removing public endpoints and replacing network-based trust with identity-based access controls.
All access is now:

These security improvements were achieved without disrupting day-to-day development.
The platform is now positioned to support further enhancements, including:
The organisation now has a secure and scalable Kubernetes platform that delivers:
This case study highlights a fundamental shift in platform security:
Secure access is no longer about protecting a network perimeter; it is about removing it entirely.
By replacing VPNs and bastion hosts with:
The team achieved a secure, zero-trust Kubernetes architecture without sacrificing usability, performance, or developer productivity.
We can help you redesign your platform around private endpoints, internal execution, and zero-trust access, without compromising operability.