Skip to content

Define network access for your application

After completing this guide, your application will have the network access rules it needs — whether that’s receiving traffic from other in-cluster services, reaching services in other namespaces, communicating with the Kubernetes API, or connecting to external hosts.

  • UDS CLI installed
  • Access to a Kubernetes cluster with UDS Core deployed
  • Familiarity with the Package CR

UDS Core enforces strict network policies by default. All intra-cluster and external traffic must be explicitly declared in your Package CR’s allow block. The UDS Operator translates these declarations into Kubernetes NetworkPolicy resources, Istio AuthorizationPolicy resources, and for external egress, into Istio ServiceEntry and routing resources.

Each allow entry specifies a direction (Ingress or Egress), a selector to match your pods, and details about the remote end (namespace, labels, host, or a generated target). See the Package CR Reference for the full list of fields.

  1. Allow ingress from other namespaces

    To accept traffic from a service in a different namespace, add an Ingress rule with remoteNamespace and remoteSelector:

    uds-package.yaml
    apiVersion: uds.dev/v1alpha1
    kind: Package
    metadata:
    name: my-app
    namespace: my-app
    spec:
    network:
    allow:
    - description: "Allow queries from Grafana"
    direction: Ingress
    selector:
    app.kubernetes.io/name: my-app
    remoteNamespace: grafana
    remoteSelector:
    app.kubernetes.io/name: grafana
    port: 8080

    This allows pods labeled app.kubernetes.io/name: grafana in the grafana namespace to reach port 8080 on your application.

  2. Allow in-cluster egress

    To send traffic to destinations inside the cluster, add an Egress rule. Choose the pattern that matches your target:

    To reach a service in a different namespace, specify remoteNamespace and remoteSelector:

    uds-package.yaml
    apiVersion: uds.dev/v1alpha1
    kind: Package
    metadata:
    name: my-app
    namespace: my-app
    spec:
    network:
    allow:
    - description: "Query Prometheus metrics"
    direction: Egress
    selector:
    app.kubernetes.io/name: my-app
    remoteNamespace: monitoring
    remoteSelector:
    app.kubernetes.io/name: prometheus
    port: 9090
  3. Allow external egress

    By default, workloads in the mesh cannot reach the internet. Choose the approach that fits your use case:

    In ambient mode, the dedicated egress waypoint is automatically included in UDS Core. No additional components need to be enabled.

    Add an allow entry with direction: Egress and remoteHost to your Package CR:

    uds-package.yaml
    apiVersion: uds.dev/v1alpha1
    kind: Package
    metadata:
    name: my-app
    namespace: my-app
    spec:
    network:
    serviceMesh:
    mode: ambient
    allow:
    - description: "Allow HTTPS to external API"
    direction: Egress
    port: 443
    remoteHost: api.example.com
    remoteProtocol: TLS
    selector:
    app: my-app
    serviceAccount: my-app

    The serviceAccount field is optional but strongly recommended for ambient egress rules with remoteHost or remoteGenerated: Anywhere. It scopes egress access to specific workload identities, enforcing least privilege.

    When applied, the UDS Operator creates:

    • A shared ServiceEntry in the istio-egress-ambient namespace, registering the external host
    • A centralized AuthorizationPolicy that allows only the specified service accounts to reach that host
  4. Build and deploy

    Include the Package CR in your application’s Zarf package, then build and deploy:

    Terminal window
    uds zarf package create --confirm && uds zarf package deploy zarf-package-*.tar.zst --confirm

Check that the Package CR was reconciled:

Terminal window
uds zarf tools kubectl get package my-app -n my-app

For external egress, check that the routing resources were created:

Terminal window
# For ambient mode
uds zarf tools kubectl get serviceentry -n istio-egress-ambient
uds zarf tools kubectl get authorizationpolicy -n istio-egress-ambient
# For sidecar mode
uds zarf tools kubectl get serviceentry -n my-app
uds zarf tools kubectl get virtualservice -n istio-egress-gateway

Symptoms: Application cannot reach a service in another namespace; connection timeouts or resets.

Solution:

  • Verify the remoteNamespace and remoteSelector match the target pods exactly
  • Check that the port matches the port the remote service is listening on
  • Ensure both sides have the necessary rules — if app A needs to talk to app B, app A needs an Egress rule and app B needs an Ingress rule

Symptoms: Application cannot reach an external service; connection timeouts or resets.

Solution:

  • Verify the remoteHost matches exactly — google.com is not the same as www.google.com
  • Check that your selector and serviceAccount match the workloads you expect
  • For sidecar mode, run istioctl proxy-config listeners <egress-pod> -n <egress-namespace> to verify expected routes

Symptoms: Operator logs a warning; traffic on custom ports does not egress.

Solution: The port is not exposed on the egress gateway service. Add it to service.ports in the gateway overrides as shown in the sidecar mode tab.

  • TLS passthrough: External egress uses TLS passthrough mode, meaning traffic exits the mesh as-is. Without TLS origination, HTTP paths cannot be inspected, restricted, or logged.
  • Domain fronting: TLS passthrough only verifies the SNI header, not the actual destination. This is only safe for trusted hosts. See domain fronting for background.
  • DNS exfiltration: UDS Core does not currently block DNS-based data exfiltration.
  • Audit all egress entries: Platform engineers should review all Package custom resources to verify that every Egress entry is scoped appropriately — each one represents a traffic path that will be opened. Ensure all declared egress is either intra-cluster communication or intentional external access.

These guides and concepts may be useful to explore next: