Safeguard
Security Guides•

How do you stop accidental public exposure of Kubernetes Services?

Block surprise LoadBalancer and externalIPs Services at admission, with a CEL example, a review path for approved exposure and a quick audit.

Safeguard Security Team
4 min read

Make exposure an explicit, reviewed choice by rejecting Service types that publish workloads, such as LoadBalancer and NodePort, unless a namespace is approved for them. Add the DenyServiceExternalIPs plugin where you can, and audit what is already exposed. One extra line in a manifest should not open a service to the internet.

What can expose a Service

The Kubernetes documentation lists the Service types. ClusterIP is the default, internal to the cluster. NodePort exposes the Service on each node's IP at a static port. LoadBalancer exposes it externally using an external load balancer, which on cloud providers provisions one for the Service. ExternalName maps the Service to a DNS name. Ingress and Gateway resources are another route to the outside, handled separately.

Each of those can turn a private workload into a public one with a small change.

The externalIPs field

The admission controller reference describes DenyServiceExternalIPs: it rejects all net new use of the Service externalIPs field, because the feature is powerful, allows network traffic interception, and is not well controlled by policy. Existing uses are not affected, and people may remove values. It is a validating plugin that is not on by default, so check whether your cluster enables it.

Step 1: write a policy for Service types

A ValidatingAdmissionPolicy can match Services on create and update and reject the types you want to gate.

validations:
  - expression: "object.spec.type != 'LoadBalancer' && object.spec.type != 'NodePort'"
    message: "Public Service types need an approved namespace"

Bind it with Warn and Audit first, as the documentation's validation actions allow. Use a namespaceSelector on a separate binding, or exemption labels governed by RBAC, so approved namespaces such as an edge or ingress namespace can still create what they need.

Step 2: decide the approved path

NeedApproved route
Public web appShared ingress or gateway in an edge namespace
Internal service for other teamsClusterIP, optionally with an internal load balancer annotation per your provider
Admin or debug accessPort forward or a bastion, not a public Service
Temporary exposureTime limited exception with an owner and an expiry

Describe this in a short page developers can find. A block without a path forward just creates workarounds.

Step 3: cover Ingress too

Services are not the only way out. Add a policy or a review requirement for Ingress and Gateway objects, such as requiring a hostname from an approved list and TLS configuration. Which fields to check depends on your ingress implementation, so read its documentation.

Step 4: audit what is already public

Admission only sees new changes, so run a sweep of current Services and Ingresses.

  1. List every Service of type LoadBalancer or NodePort and every Ingress.
  2. For each, record owner, purpose and whether it is meant to be public.
  3. Close the ones nobody claims, and add the rest to the approved list.
  4. Repeat on a schedule, and alert on new ones.

Do not forget the network layer

Cloud load balancers and node firewalls also matter. A NodePort may be blocked by firewall rules in one environment and open in another. Treat the admission rule as one layer and check your cloud settings as well.

Where Safeguard fits

Safeguard's asset discovery helps you build an inventory of what you run, and its policies and gates enforce rules on changes before release. Cluster exposure itself is enforced by the Kubernetes API and your network configuration.

Quick check

Does blocking LoadBalancer Services stop all exposure?

No. NodePort, externalIPs, Ingress and Gateway objects are other routes. Cover each one.

Will DenyServiceExternalIPs remove existing externalIPs?

No. The documentation says existing uses are not affected. It rejects new usage.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.