Define network access for your application
What you’ll accomplish
Section titled “What you’ll accomplish”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.
Prerequisites
Section titled “Prerequisites”- UDS CLI installed
- Access to a Kubernetes cluster with UDS Core deployed
- Familiarity with the Package CR
Before you begin
Section titled “Before you begin”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.
-
Allow ingress from other namespaces
To accept traffic from a service in a different namespace, add an
Ingressrule withremoteNamespaceandremoteSelector:uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:allow:- description: "Allow queries from Grafana"direction: Ingressselector:app.kubernetes.io/name: my-appremoteNamespace: grafanaremoteSelector:app.kubernetes.io/name: grafanaport: 8080This allows pods labeled
app.kubernetes.io/name: grafanain thegrafananamespace to reach port 8080 on your application. -
Allow in-cluster egress
To send traffic to destinations inside the cluster, add an
Egressrule. Choose the pattern that matches your target:To reach a service in a different namespace, specify
remoteNamespaceandremoteSelector:uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:allow:- description: "Query Prometheus metrics"direction: Egressselector:app.kubernetes.io/name: my-appremoteNamespace: monitoringremoteSelector:app.kubernetes.io/name: prometheusport: 9090Operators, controllers, and other workloads that interact with the Kubernetes API or infrastructure endpoints use
remoteGeneratedtargets. The UDS Operator automatically resolves these to the correct CIDRs:uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-operatornamespace: my-operatorspec:network:allow:- description: "Kubernetes API access"direction: Egressselector:app.kubernetes.io/name: my-operatorremoteGenerated: KubeAPIAvailable
remoteGeneratedvalues for in-cluster targets:Value Description KubeAPIKubernetes API server KubeNodesAll cluster nodes (e.g., for DaemonSet communication) CloudMetadataCloud provider metadata endpoints (e.g., 169.254.169.254)IntraNamespaceAll pods in the same namespace -
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
allowentry withdirection: EgressandremoteHostto your Package CR:uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:serviceMesh:mode: ambientallow:- description: "Allow HTTPS to external API"direction: Egressport: 443remoteHost: api.example.comremoteProtocol: TLSselector:app: my-appserviceAccount: my-appThe
serviceAccountfield is optional but strongly recommended for ambient egress rules withremoteHostorremoteGenerated: Anywhere. It scopes egress access to specific workload identities, enforcing least privilege.When applied, the UDS Operator creates:
- A shared
ServiceEntryin theistio-egress-ambientnamespace, registering the external host - A centralized
AuthorizationPolicythat allows only the specified service accounts to reach that host
For workloads running in sidecar mode, you first need to enable the optional sidecar egress gateway in your UDS Core bundle, then define the egress rule in your application’s Package CR.
-
Enable the egress gateway in your UDS Core bundle
uds-bundle.yaml kind: UDSBundlemetadata:name: uds-core-bundledescription: UDS Core with sidecar egress gatewayversion: "0.1.0"packages:- name: corerepository: registry.defenseunicorns.com/public/coreref: x.x.x-upstreamoptionalComponents:- istio-egress-gatewayIf your egress requires a port other than 80 or 443, add it to the gateway’s service ports in the same bundle:
uds-bundle.yaml overrides:istio-egress-gateway:gateway:values:- path: "service.ports"value:- name: status-portport: 15021protocol: TCPtargetPort: 15021- name: http2port: 80protocol: TCPtargetPort: 80- name: httpsport: 443protocol: TCPtargetPort: 443- name: custom-portport: 9200protocol: TCPtargetPort: 9200 -
Create and deploy your UDS Core bundle
Terminal window uds create --confirm && uds deploy uds-bundle-*.tar.zst --confirm -
Define the egress rule in your Package CR
uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:serviceMesh:mode: sidecarallow:- description: "Allow HTTPS to external API"direction: Egressport: 443remoteHost: api.example.comremoteProtocol: TLSselector:app: my-app
uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:allow:- description: "Allow all external egress"direction: Egressselector:app: my-appremoteGenerated: AnywhereserviceAccount: my-app - A shared
-
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
Verification
Section titled “Verification”Check that the Package CR was reconciled:
uds zarf tools kubectl get package my-app -n my-appFor external egress, check that the routing resources were created:
# For ambient modeuds zarf tools kubectl get serviceentry -n istio-egress-ambientuds zarf tools kubectl get authorizationpolicy -n istio-egress-ambient
# For sidecar modeuds zarf tools kubectl get serviceentry -n my-appuds zarf tools kubectl get virtualservice -n istio-egress-gatewayTroubleshooting
Section titled “Troubleshooting”Intra-cluster traffic blocked
Section titled “Intra-cluster traffic blocked”Symptoms: Application cannot reach a service in another namespace; connection timeouts or resets.
Solution:
- Verify the
remoteNamespaceandremoteSelectormatch the target pods exactly - Check that the
portmatches 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
Egressrule and app B needs anIngressrule
External egress blocked
Section titled “External egress blocked”Symptoms: Application cannot reach an external service; connection timeouts or resets.
Solution:
- Verify the
remoteHostmatches exactly —google.comis not the same aswww.google.com - Check that your
selectorandserviceAccountmatch the workloads you expect - For sidecar mode, run
istioctl proxy-config listeners <egress-pod> -n <egress-namespace>to verify expected routes
Port not exposed (sidecar egress)
Section titled “Port not exposed (sidecar egress)”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.
Security considerations
Section titled “Security considerations”- 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
Packagecustom resources to verify that everyEgressentry 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.
Related documentation
Section titled “Related documentation”Next steps
Section titled “Next steps”These guides and concepts may be useful to explore next: