From ec2e4b38c431f8e3f8db9c0c440fe1ec5625d0f0 Mon Sep 17 00:00:00 2001 From: codyshoffner Date: Tue, 19 May 2026 16:08:48 -0500 Subject: [PATCH 1/4] chore: networking patterns --- docs/configuration.md | 3 + docs/networking-patterns.md | 151 ++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 docs/networking-patterns.md diff --git a/docs/configuration.md b/docs/configuration.md index 3c95a7d..cd5cfc4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -88,6 +88,9 @@ overrides: For external databases (non-operator), set `postgres.password` directly and provide the `host`, `dbName`, and connection details for your database service. +> [!NOTE] +> Setting `postgres.internal` to `false` also changes the egress rule from a scoped namespace selector to unrestricted egress. See [Networking patterns](networking-patterns.md) for details. + > [!IMPORTANT] > You can learn more about configuring the databases and operator within the [Postgres Operator docs](https://github.com/zalando/postgres-operator/tree/master/docs). diff --git a/docs/networking-patterns.md b/docs/networking-patterns.md new file mode 100644 index 0000000..8419790 --- /dev/null +++ b/docs/networking-patterns.md @@ -0,0 +1,151 @@ +# Networking patterns + +UDS packages declare their networking in a `Package` CR. The UDS Operator translates those declarations into Kubernetes `NetworkPolicy` and Istio resources, so package authors never write those directly. + +> [!NOTE] +> For a full explanation of the networking model, see [Networking & Service Mesh](https://docs.defenseunicorns.com/core/concepts/core-features/networking/) and the [Packages CR reference](https://docs.defenseunicorns.com/core/reference/operator--crds/packages-v1alpha1-cr/). + +## Standard package network block + +A typical UDS package network block covers three concerns: exposing the application through a gateway, scoped intra-namespace communication, and egress to its dependencies. + +```yaml +# chart/templates/uds-package.yaml +spec: + network: + + expose: + - service: reference-package + selector: + app: reference-package + gateway: tenant # tenant (end-user) or admin (platform-ops) + host: reference-package # resolves to reference-package. + port: 8080 + + allow: + # Intra-namespace — scoped to known pod labels where possible + - direction: Ingress + selector: + app: reference-package + remoteSelector: + app: reference-package + + - direction: Egress + selector: + app: reference-package + remoteSelector: + app: reference-package + + # Cross-namespace — scoped to the target namespace and pod selector + - direction: Egress + selector: + app: reference-package + remoteNamespace: postgres + remoteSelector: + cluster-name: pg-cluster + port: 5432 + description: "Postgres database" +``` + +## Non-authservice SSO + +Applications that handle OIDC natively (not through authservice) need to add the Keycloak network rules manually. The operator only generates these automatically for authservice clients. + +```yaml +# chart/templates/uds-package.yaml +allow: + # Direct backend connection to Keycloak + - direction: Egress + remoteNamespace: keycloak + remoteSelector: + app.kubernetes.io/name: keycloak + selector: + app: reference-package + port: 8080 + description: "Keycloak OIDC backend" + + # Keycloak issuer URL resolves through the tenant gateway, not directly + - direction: Egress + remoteNamespace: istio-tenant-gateway + remoteSelector: + app: tenant-ingressgateway + selector: + app: reference-package + port: 443 + description: "Keycloak via tenant gateway for OIDC issuer" +``` + +## External egress + +To reach a known external host, use `remoteHost`. Each host requires its own entry; wildcards are not supported. + +```yaml +# chart/templates/uds-package.yaml +allow: + - direction: Egress + selector: + app: reference-package + remoteHost: api.example.com # exact hostname; wildcards are not supported + port: 443 + description: "External API" +``` + +`remoteProtocol` defaults to `TLS` when `remoteHost` is set. Use `HTTP` for plaintext egress. + +## Internal vs. external dependency toggle + +Packages that support both in-cluster and external dependencies use a values flag with a Helm conditional to switch between a scoped rule and an unrestricted one: + +```yaml +# chart/templates/uds-package.yaml +allow: + - direction: Egress + selector: + app: reference-package + {{- if .Values.postgres.internal }} + remoteNamespace: {{ .Values.postgres.namespace | quote }} + remoteSelector: + {{ .Values.postgres.selector | toYaml | nindent 10 }} + port: {{ .Values.postgres.port }} + {{- else }} + remoteGenerated: Anywhere + {{- end }} + description: "Postgres database" +``` + +Bundle deployers toggle this via the config chart: + +```yaml +# bundle/uds-bundle.yaml +overrides: + reference-package: + uds-reference-package-config: + values: + - path: postgres.internal + value: false +``` + +> [!IMPORTANT] +> `remoteGenerated: Anywhere` opens unrestricted egress. Prefer a specific `remoteHost` or scoped `remoteNamespace` rule wherever the target is known. + +## Extending network rules at deploy time + +Packages expose an `additionalNetworkAllow` key so deployers can inject rules for integrations not known at package-authoring time: + +```yaml +# bundle/uds-bundle.yaml +overrides: + reference-package: + uds-reference-package-config: + values: + - path: additionalNetworkAllow + value: + - direction: Egress + selector: + app: reference-package + remoteNamespace: my-service + remoteSelector: + app: my-service + port: 8080 + description: "Custom integration" +``` From aa8c35ce7758c2b87a60f80f1f4c1988b19c1781 Mon Sep 17 00:00:00 2001 From: codyshoffner Date: Tue, 19 May 2026 16:15:29 -0500 Subject: [PATCH 2/4] chore: networking patterns --- docs/configuration.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index cd5cfc4..a38552a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,9 +4,10 @@ The Reference Package is configured using the [application's Helm chart](https:/ ## Bundle Overrides -Use bundle overrides in `bundle/uds-bundle.yaml` to configure the Database, SSO, and Monitoring. +Use bundle overrides to configure the Database, SSO, and Monitoring. ```yaml +# bundle/uds-bundle.yaml overrides: reference-package: reference-package: @@ -31,9 +32,10 @@ overrides: The underlying Go application requires a database connection string provided via a Kubernetes secret. -If you are using the [uds-package-postgres-operator](https://github.com/uds-packages/postgres-operator) in your bundle, the `uds-reference-package-config` chart (located in `./chart`) will create the secret, via the below values: +If you are using the [uds-package-postgres-operator](https://github.com/uds-packages/postgres-operator) in your bundle, the `uds-reference-package-config` chart will create the secret via the below values: ```yaml +# chart/values.yaml postgres: username: "reference" # Note: Specifying password as anything other than "" will not use the existingSecret @@ -59,6 +61,7 @@ postgres: The Zalando Postgres Operator uses a `{namespace}.{username}` format for the `users` key in its config. That namespace prefix determines **which namespace** the operator places the credentials secret in. Given the following bundle override on the `postgres-operator` package: ```yaml +# bundle/uds-bundle.yaml overrides: postgres-operator: uds-postgres-config: @@ -73,9 +76,10 @@ overrides: The operator creates a secret named `reference-package.reference-package.pg-cluster.credentials.postgresql.acid.zalan.do` in the `reference-package` namespace. -`chart/templates/postgres-secret.yaml` then looks up that secret, extracts the credentials, and writes a `postgres://` connection string into `reference-package-postgres` in the same namespace. The application chart consumes it via the `database` bundle override: +`chart/templates/postgres-secret.yaml` then looks up that secret, extracts the credentials, and writes a `postgres://` connection string into `reference-package-postgres` in the same namespace. The application chart consumes it via the `database` override: ```yaml +# bundle/uds-bundle.yaml overrides: reference-package: reference-package: From 12e0b0d8c4fdce49d203e6bc52a1580fe30312c6 Mon Sep 17 00:00:00 2001 From: codyshoffner Date: Tue, 19 May 2026 16:25:45 -0500 Subject: [PATCH 3/4] chore: networking patterns --- docs/networking-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/networking-patterns.md b/docs/networking-patterns.md index 8419790..8339271 100644 --- a/docs/networking-patterns.md +++ b/docs/networking-patterns.md @@ -18,7 +18,7 @@ spec: - service: reference-package selector: app: reference-package - gateway: tenant # tenant (end-user) or admin (platform-ops) + gateway: tenant host: reference-package # resolves to reference-package. port: 8080 From df95184119183312f4a566332ee42a409144a5b6 Mon Sep 17 00:00:00 2001 From: codyshoffner Date: Tue, 19 May 2026 16:27:14 -0500 Subject: [PATCH 4/4] chore: networking patterns --- docs/networking-patterns.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/networking-patterns.md b/docs/networking-patterns.md index 8339271..43a1843 100644 --- a/docs/networking-patterns.md +++ b/docs/networking-patterns.md @@ -77,7 +77,7 @@ allow: ## External egress -To reach a known external host, use `remoteHost`. Each host requires its own entry; wildcards are not supported. +To reach a known external host, use `remoteHost`. Each host requires its own entry. ```yaml # chart/templates/uds-package.yaml @@ -85,13 +85,11 @@ allow: - direction: Egress selector: app: reference-package - remoteHost: api.example.com # exact hostname; wildcards are not supported + remoteHost: api.example.com # exact hostname - wildcards are not supported port: 443 description: "External API" ``` -`remoteProtocol` defaults to `TLS` when `remoteHost` is set. Use `HTTP` for plaintext egress. - ## Internal vs. external dependency toggle Packages that support both in-cluster and external dependencies use a values flag with a Helm conditional to switch between a scoped rule and an unrestricted one: