Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 44 additions & 148 deletions content/patterns/layered-zero-trust/_index.adoc

Large diffs are not rendered by default.

180 changes: 180 additions & 0 deletions content/patterns/layered-zero-trust/lzt-architecture.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
---
title: Architecture
weight: 5
aliases: /layered-zero-trust/lzt-architecture/
---

:toc:
:imagesdir: /images
:_mod-docs-content-type: ASSEMBLY
include::modules/comm-attributes.adoc[]

[id="lzt-architecture"]
= Architecture

The Layered Zero Trust pattern implements a layered zero trust architecture that provides workload identity management, secure communication, secret management, runtime security monitoring, and compliance scanning on {rh-ocp}.

[id="layered-architecture-overview"]
== Layered architecture overview

The ZTVP is structured in three decoupled layers, each building on the one below:

* *Layer 0 — Foundation*: The always-deployed security baseline. These components are installed automatically with every ZTVP deployment and provide the core Zero Trust capabilities.
* *Layer 1 — Feature Sets*: Optional capabilities that can be enabled per use case. These extend the foundation with additional security services like supply chain signing, private registries, and network observability.
* *Layer 2 — Use Cases*: Real applications that demonstrate Zero Trust principles in practice. They consume the services provided by Layers 0 and 1.

image::layered-zero-trust/layered-zero-trust-architecture-diagram.png[Layered Zero Trust architecture diagram]

[id="layer-0-foundation"]
=== Layer 0 — Foundation

[cols="2,3,2",options="header"]
|===
| Component | What it does | Zero Trust contribution

| HashiCorp Vault
| Centralized secret storage and management with JWT-based authentication
| Dynamic secrets, just-in-time credential injection

| Zero Trust Workload Identity Manager (SPIRE/SPIFFE)
| Assigns short-lived cryptographic identities to workloads
| No shared secrets, mutual authentication

| Red{nbsp}Hat build of Keycloak
| User authentication and SSO via OIDC
| Centralized identity, per-application access control

| External Secrets Operator
| Synchronizes secrets from Vault into {ocp}
| Automated secret lifecycle management

| Red{nbsp}Hat Cert Manager

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| Red{nbsp}Hat Cert Manager
| Red{nbsp}Hat cert-manager

| Automated TLS certificate lifecycle
| Encrypted communications, daily CA rotation

| Compliance Operator
| CIS benchmark scanning and automated remediation
| Continuous compliance monitoring

| Red{nbsp}Hat Advanced Cluster Management
| Multi-cluster management control plane
| Centralized policy enforcement

| Red{nbsp}Hat Advanced Cluster Security
| Runtime security monitoring, threat detection and response
| Continuous monitoring, automated threat termination
|===

[id="layer-1-feature-sets"]
=== Layer 1 — Feature Sets

[cols="2,3,2",options="header"]
|===
| Component | What it does | Required for

| Red{nbsp}Hat Quay
| Private OCI image registry
| Supply chain security use cases

| Multicloud Object Gateway (NooBaa)
| Object storage service for {ocp}
| Quay storage backend, Network Observability

| Red{nbsp}Hat Trusted Artifact Signer (RHTAS)
| Keyless signing and verification of container images and artifacts
| Secure supply chain

| Red{nbsp}Hat Trusted Profile Analyzer (RHTPA)
| SBOM storage, analysis, and CVE cross-referencing
| Supply chain vulnerability analysis

| Red{nbsp}Hat OpenShift Pipelines
| Cloud-native CI/CD on {ocp}
| Automated supply chain workflows

| Network Observability (Loki + FlowCollector)
| Network flow monitoring and visualization
| Network traffic analysis
|===

[id="layer-2-use-cases"]
=== Layer 2 — Use Cases

[cols="2,3",options="header"]
|===
| Use case | Description

| link:/patterns/layered-zero-trust/lzt-data-protection/[Zero Trust Data Protection]
| The `qtodo` demo application shows how workload identity, dynamic secrets, user authentication, and network segmentation protect a real application.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| The `qtodo` demo application shows how workload identity, dynamic secrets, user authentication, and network segmentation protect a real application.
| The `qtodo` demo application shows how workload identity, dynamic secrets, user authentication, and network segmentation to protect a real application.


| link:/patterns/layered-zero-trust/lzt-secure-supply-chain/[Secure Supply Chain]
| Manual walkthrough of container image signing, SBOM generation, and artifact verification using RHTAS and RHTPA.

| link:/patterns/layered-zero-trust/lzt-automated-secure-supply-chain/[Automated Supply Chain]
| Tekton pipeline automating the build, sign, verify, and deploy workflow end-to-end.
|===

[id="sidecar-pattern"]
== Sidecar pattern

The sidecar pattern is a deployment model where a separate container runs alongside the main application to handle auxiliary tasks. In an {ocp} environment, pods simplify this by ensuring the sidecar and main application share the same lifecycle. This approach benefits Zero Trust architectures by enabling centralized enforcement of security policies such as authentication, authorization, traffic encryption (mTLS), rate limiting, auditing, and logging — without requiring developers to add this logic to every microservice.

The Layered Zero Trust pattern uses the sidecar approach to offload critical security functions from the main application. This centralizes policy enforcement, simplifies development, and separates security concerns.

[id="applied-sidecar-pattern-data-protection"]
=== Applied sidecar pattern: Data protection

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to go into the details here or just reserve it for the page specifically addressing data protection?


The following diagrams illustrate how the sidecar pattern is applied in practice to solve the Data Protection use case. They demonstrate how an application (`qtodo`) retrieves database credentials dynamically without hard-coding secrets.

==== Logical structure

The logical structure diagram shows the composition of the application pod and its relationship to the infrastructure.

* *Decoupled components*: The `qtodo` application logic is separated from security functions. The application container runs alongside helper sidecars (spiffe-vault-client, spiffe-helper) and init containers.
* *Infrastructure layers*: The sidecars bridge the gap between the application and the platform services:

** *Workload identity*: The sidecars interface with SPIRE to prove the pod's identity.
** *Secret management*: They connect to HashiCorp Vault to fetch secrets.
** *Trust anchors*: Keycloak and Cert Manager provide the root trust for the ecosystem.

image::layered-zero-trust/layered-zero-trust-data-protection-logical.png[Logical structure of the sidecar pattern for data protection]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This image is not rendering for me


==== Schematic workflow

The schematic diagram details the step-by-step execution flow:

* *Identity minting* (Steps 3-6): Upon startup, the SPIRE Agent validates the pod (via node attestors and kubelet) and mints a cryptographic identity (SPIFFE ID).
* *Secret retrieval* (Step 7): The spiffe-vault-client sidecar uses this verified identity to authenticate with HashiCorp Vault and request the specific credentials needed for the database.
* *Secure access* (Steps 8-9): The credentials are passed to the application, allowing it to authenticate and establish a connection to the PostgreSQL database securely.

image::layered-zero-trust/layered-zero-trust-data-protection-schematic.png[Schematic workflow of the sidecar pattern for data protection]

[id="deployment-variants"]
== Deployment variants

The pattern supports multiple deployment configurations:

[cols="2,3",options="header"]
|===
| Configuration file | Description

| `values-hub.yaml`
| Default hub cluster deployment with the full Layer 0 foundation

| `values-coco-dev.yaml`
| Development variant for Confidential Containers integration
|===

[id="feature-variant-system"]
== Feature variant system

Layer 1 features can be enabled or disabled independently using the `gen-feature-variants.py` script.

For example, to generate a `values-hub.yaml` with the supply chain feature set enabled:

[source,terminal]
----
$ python3 scripts/gen-feature-variants.py --features supply-chain --registry-option 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to explain what the registry option is here or is it assumed that the reader should refer to the reference below?

----

See the link:https://github.com/validatedpatterns/layered-zero-trust/blob/main/scripts/gen-feature-variants.md[Feature Variant Generator] in the repository for detailed information.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Secure supply chain - Automated approach
weight: 40

aliases: /layered-zero-trust/lzt-automated-secure-supply-chain/
---

Expand All @@ -13,7 +14,7 @@ include::modules/comm-attributes.adoc[]
= Use case: Automating the secure supply chain

[role="_abstract"]
The xref:/patterns/layered-zero-trust/lzt-secure-multitier/index.html [Secure multitiered applications] use case describes how to implement a secure supply chain for application development by using Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA). This use case demonstrates automation of the secure supply chain for application development by using link:https://docs.redhat.com/en/documentation/red_hat_openshift_pipelines/1.20[{rh-pipelines-first}].
The link:/patterns/layered-zero-trust/lzt-data-protection/[Data Protection] use case describes how to implement a secure supply chain for application development by using Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA). This use case demonstrates automation of the secure supply chain for application development by using link:https://docs.redhat.com/en/documentation/red_hat_openshift_pipelines/1.20[{rh-pipelines-first}].

{pipelines-short} orchestrates the application building and certification process. The Zero Trust Validated Pattern (ZTVP) creates a pipeline in the cluster named `qtodo-supply-chain`.

Expand Down
110 changes: 110 additions & 0 deletions content/patterns/layered-zero-trust/lzt-data-protection.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: Data protection
weight: 20
aliases:
- /layered-zero-trust/lzt-data-protection/
- /layered-zero-trust/lzt-secure-multitier
---

:toc:
:imagesdir: /images
:_mod-docs-content-type: ASSEMBLY
include::modules/comm-attributes.adoc[]

[id="lzt-demo-application"]
= Data protection

This use case demonstrates Zero Trust data protection using the `qtodo` demo application — a simple to-do list app built with Quarkus and PostgreSQL that is included in the default Layered Zero Trust pattern installation described in the link:/patterns/layered-zero-trust/lzt-getting-started/[Getting Started] guide. No additional setup is required to explore this use case.

[id="what-this-demonstrates"]
== What this demonstrates

On its own, the `qtodo` application is unremarkable. What makes it special is _how_ it runs inside the ZTVP — every interaction is authenticated, every credential is dynamic, and every network connection is explicitly authorized.

[id="lzt-application-components"]
== Application components

The `qtodo` application consists of the following key components:

* *`qtodo`*: A link:https://quarkus.io[Quarkus-based] frontend application protected by OpenID Connect (OIDC) authentication. Users are managed in Red{nbsp}Hat build of Keycloak (RHBK).
* *PostgreSQL*: The relational database used by `qtodo`, deployed in a separate `qtodo-db` namespace. Its credentials are dynamically generated and stored in HashiCorp Vault.
* *HashiCorp Vault*: Stores sensitive values for all components. Implements JSON Web Token (JWT)-based authentication to enable access using SPIFFE-based identities.
* *Zero Trust Workload Identity Manager (SPIRE/SPIFFE)*: Assigns a cryptographic identity to the `qtodo` pod, allowing it to authenticate with Vault and obtain database credentials.
* *link:https://github.com/spiffe/spiffe-helper[spiffe-helper]*: A sidecar container that dynamically fetches JWT-based identities from the SPIFFE Workload API.
* *`spiffe-vault-client`*: A sidecar container that uses the SPIFFE identity to authenticate with Vault and retrieve database credentials just-in-time.

[NOTE]
====
The `qtodo` pod uses a series of init containers and sidecar containers to supply the application with the credentials required for operation. Explore the pod details in the {ocp} web console (*Workloads > Pods* in the `qtodo` namespace) to see this in action.
====

[id="security-features-in-action"]
== Security features in action

When a user accesses the `qtodo` application, the following security features activate:

[id="user-authentication"]
=== 1. User authentication

The user is redirected to Red{nbsp}Hat build of Keycloak for login. Only users with the correct role in the `ztvp` realm can access the application. No credentials are stored in the application code.

[id="workload-identity"]
=== 2. Workload identity

The `qtodo` pod proves its identity using a cryptographic SPIFFE certificate (SVID). This identity is issued by SPIRE and rotates automatically every hour. No static service account tokens are used.

[id="dynamic-secrets"]
=== 3. Dynamic secrets

The `spiffe-vault-client` sidecar uses the pod's SPIFFE identity to authenticate with HashiCorp Vault and retrieve the PostgreSQL password. The password is never stored as a Kubernetes Secret — it's fetched just-in-time and exists only in memory.

[id="namespace-separation"]
=== 4. Namespace separation

The `qtodo` application and its PostgreSQL database run in separate namespaces (`qtodo` and `qtodo-db`). This isolation limits the blast radius of a compromise — an attacker who gains access to the application namespace cannot directly reach the database resources, and vice versa.

[id="network-isolation"]
=== 5. Network isolation

Default-deny NetworkPolicies are applied independently to both the application and database namespaces. Explicit allow rules permit only the connections that are strictly required: browser to `qtodo` (port 8443), `qtodo` to PostgreSQL (port 5432, cross-namespace), `qtodo` to Vault (port 8200), and `qtodo` to DNS (port 5353). Nothing else is permitted.

[id="before-vs-after"]
== Before vs. after

[cols="2,2,3",options="header"]
|===
| Aspect | Traditional deployment | With ZTVP

| Database credentials
| Static Kubernetes Secret in etcd
| Dynamic, fetched from Vault via SPIFFE

| User authentication
| Application-managed or none
| Centralized Keycloak SSO

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| Centralized Keycloak SSO
| Centralized Keycloak based SSO


| Network access
| Allow-all (Kubernetes default)
| Default-deny with per-pod allow rules across separate namespaces

| Workload identity
| Shared service account
| Cryptographic SPIFFE SVID (1-hour TTL)

| Code changes required
| N/A
| Application reads credentials from sidecar-generated files instead of environment variables
|===

[id="try-it-yourself"]
== Try it yourself

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this section overlap with the content of the Secure Multitiered Applications page?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now when I read the Secure multitiered applications page indeed there is a big overlapping. Maybe we should archive "Secure multitiered applications" in favor of Data Protection page?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the content that is in the "Secure multitiered applications". Lets indeed combine the pages


After deploying the ZTVP, you can access the `qtodo` application and observe the Zero Trust security features in action:

. Navigate to the `qtodo` route in the {ocp} Console (*Networking > Routes* in the `qtodo` namespace).
. You will be redirected to the Keycloak login page. Log in with the `qtodo` user credentials from Vault (path: `secret/hub/infra/users/keycloak-users`). See link:/patterns/layered-zero-trust/lzt-getting-started/#lzt-accessing-credentials[Accessing credentials] for instructions on how to retrieve secrets from Vault.

. Observe the OIDC redirect flow — the browser is redirected to Keycloak, authenticated, and then returned to the application. During the first login you will be asked to change your credentials.
. Add and remove to-do items to verify the application works end-to-end. You can also login as a `qtodo-admin` user, which can modify all demo application entries.

For a detailed technical breakdown of the sidecar architecture and data protection workflow, see the link:/patterns/layered-zero-trust/lzt-architecture/#sidecar-pattern[Sidecar pattern] section in the Architecture page.
Loading