Skip to content
Unified Defense StackUnified Defense Stack
You're viewing unreleased documentation from main. Go to the latest release

UDS Package Requirements

This page defines engineering standards for secure, maintainable UDS Packages that integrate with UDS Core. It uses RFC 2119 terminology: MUST indicates a mandatory requirement, SHOULD a strong recommendation, and MAY an optional practice. These terms have the same meaning regardless of who maintains the package.

UDS Packages are Zarf packages that integrate with UDS Core and follow these additional standards. Deploying successfully on UDS Core does not by itself demonstrate that a package meets these standards.

  • MUST minimize the scope and number of exemptions, to only what is absolutely required by the application. UDS Packages MAY make use of the UDS Exemption custom resource for exempting any Pepr policies, but in doing so they MUST document rationale for the exemptions. Exemptions SHOULD be documented in docs/justifications.md of the UDS Package repository.
  • MUST declaratively implement any available application hardening guidelines by default.
  • SHOULD consider security options during implementation to provide the most secure default possible (i.e. SAML w/SCIM vs OIDC).
  • MUST be declaratively defined as a Zarf package.
  • MUST integrate declaratively (i.e. no clickops) with the UDS Operator.
  • MUST support operation within the airgap and test installation, startup, and core user workflows without internet access.
  • MUST not use local commands outside of coreutils or ./zarf self references within zarf actions.
  • MUST use Helm charts for rendering Kubernetes resources. When available and suitable for UDS packaging, an upstream chart MUST be used. When using an upstream chart, UDS-specific configurations SHOULD be encapsulated in a separate config Helm chart.

    This keeps the package structure clean and maintainable by separating concerns into inspectable units. Using upstream charts also makes it easier to incorporate upstream changes over time.

  • MUST (except if the application provides no application metrics) implement monitors for each application metrics endpoint using its built-in chart monitors, monitor key, or manual monitors in the config chart. Monitor Resource
  • MUST include package documentation in a root-level docs folder (for configuration and dependencies) and include it in the Zarf package under the documentation key.
  • MUST review Package Metadata and decide which recommended annotations to include for the package and the UDS products that consume it.
  • SHOULD follow the Package Values guidance for exposing package configuration.

    Zarf Values is currently an Beta feature and may change as it matures (see zarf-dev/zarf#3946). Use values for package configuration. Retain existing Zarf Variables only when needed for backwards compatibility, and combine them with explicit values through templatedValuesFiles.

  • SHOULD limit the use of Zarf Variables and prioritize configuring packages via Zarf Values.

    Use values for package configuration whenever possible. Keep raw ###ZARF_VAR_*### tokens in ordinary valuesFiles; use .Variables.* in templatedValuesFiles only when existing variables must remain compatible or the package must apply precedence or compute a fallback.

  • SHOULD consider or allow for multiple flavors (ideally with common Zarf definitions in a ./common/zarf.yaml).

    Flavors in Zarf allow for varying binary content to be delivered in a package and can be used to deliver different base images a customer may want to select from based on security preferences or for handling license requirements where there are separate binaries for enterprise or community versions (without needing wholly separate package definitions for each). Flavors SHOULD NOT be used for differences in configuration alone - those configuration options SHOULD be exposed through Zarf Values instead.

  • MUST define network policies under the allow key as required in the UDS Package Custom Resource. These policies MUST adhere to the principle of least privilege, permitting only strictly necessary traffic.
  • MUST define any external interfaces under the expose key in the UDS Package Custom Resource.
  • MUST not rely on exposed interfaces (e.g., .uds.dev) being accessible from the deployment environment (bastion or pipeline).
  • MUST configure applications that communicate with external services, including backend services like databases, to trust the UDS Core uds-trust-bundle.
  • MUST deploy and operate successfully with Istio enabled.
  • SHOULD use Istio Ambient unless specific technical constraints require otherwise.
  • MAY use Istio Sidecars, when Istio Ambient is not technically feasible. Must document the specific technical constraints in docs/justifications.md if using Sidecars.
  • SHOULD avoid workarounds with Istio such as disabling strict mTLS peer authentication.
  • MAY template network policy keys to provide flexibility for customers to configure.
  • MUST protect end-user access through UDS Core single sign-on (SSO), using the sso key to configure a Keycloak client. Use the application’s native OIDC or SAML integration, or Authservice where appropriate. An application-local login alone does not satisfy this requirement.
  • SHOULD name the Keycloak client <App> Login (i.e. Mattermost Login) to provide login UX consistency.
  • SHOULD clearly mark the Keycloak client id with the group and app name uds-<group>-<application> (i.e. uds-swf-mattermost) to provide consistency in the Keycloak UI.
  • MAY end any generated Keycloak client secrets with sso to easily locate them when querying the cluster.
  • MAY template Keycloak fields to provide flexibility for customers to configure.

Validate package behavior before release:

  • MUST implement Journey testing, covering the basic user flows and features of the application. (see Testing Guidelines)
  • MUST implement Upgrade Testing to ensure that the current development package works when deployed over the previously released one. (see Testing Guidelines)
  • MUST automatically run journey and upgrade tests as part of release validation.
  • MUST identify the maintainers responsible for package updates, security fixes, and release approval in the package repository, for example in a CODEOWNERS file.
  • MUST automate dependency update detection and initiate a tracked update workflow for the application and its packaging dependencies, using a dependency management bot such as Renovate. Tracked workflows may use pull requests, merge requests, or issue-tracker tasks.
  • MUST publish the package to an organizationally identified package registry, using a namespace and name that clearly identifies the application (e.g., ghcr.io/uds-packages/neuvector).
  • SHOULD be created from the UDS Package Template.
  • SHOULD lint configurations with appropriate tooling, such as yamllint and zarf dev lint.
  • MUST use a Semver 2.0.0 compatible version. When an application is versioned following an upstream app version, a suffix SHOULD be used to capture the package changes as described below.
  • MUST version consistently across flavors. Flavors should differ in image bases or builds, not application versioning.
  • SHOULD prepend git tags with a v to distinguish them from other tags, while leaving OCI tags as the raw version.
Example suffixed versioning scheme

Versions follow the format <upstream-app-version>-uds.<uds-sub-version>.

  • upstream-app-version — the version of the application itself.
  • uds-sub-version — the UDS release number, it starts at 0 and increments with each release that doesn’t change the app version.

Example where App Version for Reference package is 0.1.0 and the App Version stays the same: • First UDS release 0.1.0-uds.0 • Second UDS release 0.1.0-uds.1

Example where App Version increments from 0.1.0 -> 0.2.0: • First UDS release 0.2.0-uds.0

This allows the application’s version to be readily apparent in the package’s version while still allowing the package to change manifests/configuration in between app releases.