The Rendered Manifests Pattern (Enhancing GitOps Visibility and Control)

Nitish Kumar

Nitish Kumar - Akuity
The Rendered Manifests Pattern: A Complete Guide to GitOps Visibility
The Rendered Manifests Pattern: A Complete Guide to GitOps Visibility

By Nicholas Morey and Nitish Kumar. Originally published May 2025. Updated July 2026 by Nitish Kumar to cover sourceHydrator, Kargo, and OCI artifacts.

Intro

GitOps has become a clear marker of operational maturity for cloud native organizations. In CNCF's 2026 Annual Cloud Native Survey, 58% of the most advanced cloud native organizations report using GitOps principles extensively, compared to just 23% of early adopters.

GitOps principles address the core problems of visibility and collaboration in Kubernetes environments. They establish declarative desired state and continuous reconciliation as foundations, but say little about how to put either into practice.

That gap shows up clearly in one of GitOps's core claims: that Git is the source of truth for what's running on the cluster. For most teams, that's not quite accurate. When a GitOps tool like Argo CD is paired with Helm or Kustomize, what's actually in Git is an abstraction: a chart, a set of templates, a values file, overlays.

The real Kubernetes manifests applied to the cluster are rendered at sync time by the GitOps engine, held briefly in memory, and never persisted anywhere. Git contains the inputs to the desired state, not the desired state itself, and that lack of visibility makes it harder to reason about change, audit risk, and collaborate with confidence.

The Rendered Manifests Pattern solves this by rendering manifests before they reach the cluster and storing the final, immutable YAML directly in Git or an OCI registry. The result is a more stable, auditable, and observable desired state.

The Akuity team, also the original creators of Argo CD, first introduced this pattern in 2023. Since then, it has evolved from a CI workflow convention into a first-class capability.

What is the Rendered Manifests Pattern?

The Rendered Manifests Pattern is a GitOps practice that renders Kubernetes manifests before they reach the cluster and stores the final, immutable YAML in Git or an OCI registry, instead of letting Argo CD render Helm charts or Kustomize overlays at sync time. The rendered output becomes the source of truth.

Key Takeaways

  • The Rendered Manifests Pattern renders Kubernetes manifests before they reach the cluster and stores the immutable output in Git or an OCI registry, instead of Argo CD rendering Helm charts or Kustomize overlays at sync time.

  • There are four implementation approaches: CI-based rendering, sourceHydrator, Kargo, and OCI artifacts, each building on the last in capability.

  • CI-based rendering and sourceHydrator solve visibility; Kargo adds full promotion and image watching; OCI artifacts add immutability and supply chain security.

  • The core trade-off across all four approaches is operational complexity versus capability: simpler approaches require less infrastructure but offer less automation, while more capable approaches require more systems to run.

  • Regardless of approach, the underlying principle is the same: render once, store durably, and sync plain YAML with no abstraction layer between Git and the cluster.

The Core Premise of the Rendered Manifests Pattern

The desired state should be treated like a container image: immutable, and applied as-is. Running Helm or Kustomize at sync time is the equivalent of running apt-get install inside a container's startup script. The source of truth shouldn't be mutated right before it gets applied.

Treating rendering as a build step rather than a runtime step removes that risk entirely. The abstraction layer disappears before the GitOps agent ever sees it, leaving no gap between what's declared and what's deployed.

The pattern reached a wider audience at ArgoCon EU 2024, where Nicholas Morey, then a Developer Advocate at Akuity, presented it directly to the Argo community. That talk inspired the official Argo CD proposal for sourceHydrator, submitted by Argo CD maintainers later that year. Argo CD now has native support through sourceHydrator, Kargo builds promotion pipelines on top of it, and OCI registries offer an alternative to Git for storing the rendered output.

Isn't This Gitflow?

On the surface, environment-specific branches might sound like Gitflow. They aren't. Short-lived feature branches or trunk-based development can still be used in the GitOps repo.

The branches in this pattern aren't used to promote changes between environments. A change in one branch is never merged into another. Instead, an automated workflow generates and maintains the contents of each branch based on what's on main. Think of these branches as a release bundle: a rendered snapshot of an environment's desired state. No one commits to them directly, the same way no one pulls a container image, edits it, and pushes it back to the registry.

This distinction matters once Kargo enters the picture. Kargo's promotion mechanism, covered below, moves freight between stages and is a genuinely different concept from the branch-per-environment pattern.

The Problem: Not Knowing What's Running on the Cluster

With a traditional Helm and Argo CD setup, an Application spec points at a chart and a values file:

spec:
  project: default
  source:
    repoURL: https://github.com/your-org/your-repo.git
    targetRevision: HEAD
    path: guestbook
    helm:
      valueFiles

When Argo CD syncs, the repo-server runs `helm template` command internally, renders the manifests, applies them, and moves on. Those rendered manifests live briefly in the repo-server's cache and are then gone. This creates a number of problems.

  • The rendered manifests aren't visible in Git. A git log shows commits like "bump replicas to 3," not which Kubernetes resources actually changed. Finding out requires running helm template locally, with a Helm version that matches whatever the repo-server is using, or asking Argo CD directly with something like argocd app manifests guestbook-dev. Either way, the rendered YAML lives in Argo CD's memory or cache, not in Git.

  • Auditing what was deployed isn't possible from Git alone. When compliance asks what was running in production on a specific date, Git can't answer that. The commit active at that time has to be found, the chart checked out, and the output rendered locally, with no guarantee it matches what was actually applied.

  • Diffing between environments doesn't work. Comparing dev-values.yaml with prod-values.yaml shows parameter differences: replica counts, image tags, resource limits. It doesn't show whether those differences produce a two-line change or a two-hundred-line change in the actual manifests. A conditional block in a template can produce entirely different resources in dev versus prod, invisible from a values diff alone. A single Helm chart version bump can be a one-line diff in Git and nearly 1,000 lines of change in the resulting manifests, invisible until rendered.

  • Promotion is blind. When an image is promoted from dev to prod by updating prod-values.yaml, the pull request shows a values file diff. The reviewer approves a parameter change, not a manifest change, trusting that the template logic is correct without seeing the rendered output.

  • The repo-server becomes a bottleneck. Every refresh cycle, Argo CD re-runs helm template or kustomize build for every application. In large deployments, this gets expensive. Repo-servers provisioned with 32 CPUs and 200GiB of memory aren't unusual once hundreds of applications are running; work that could be rendered once and cached instead.

The Rendered Manifests Pattern: Four Approaches to Implementing It

Each change to main brach triggers a workflow that renders the manifests either by running `helm template` or `kustomize build` command and stores the output which are the rendered manifests as-is in Git, separated into environment-specific branches. As changes land on these branches, the diff between commits is fully transparent: exactly what a change to main does to each environment becomes visible.

There are four ways to implement this. Each builds on the last.

Approach 1: CI-Based Rendering (Traditional Approach)

How CI-Based Rendering Works

The simplest approach renders manifests in a CI pipeline and commits the output to environment-specific branches. The main branch stays the dry source, holding the chart, values files, and templates. On every push to the main branch, a workflow runs helm template with the environment-specific values file and commits the rendered YAML to an orphan branch (env/dev, env/staging, env/prod).

Argo CD Applications then point at these branches instead of main. They sync plain YAML, with no Helm or Kustomize processing on Argo CD's end:

# Before: renders at sync time by running helm template internally
source:
  repoURL: https://github.com/your-org/your-repo
  targetRevision: main
  path: guestbook
  helm:
    valueFiles:
      - environments/dev-values.yaml

# After: syncs pre-rendered plain YAML 
source:
  repoURL: https://github.com/your-org/your-repo
  targetRevision: env/dev
  path: .

Argo CD doesn't need to know this was ever a Helm chart. Each environment branch carries its own commit history, which provides a clean audit trail (`git log env/dev` shows every manifest change), no cross-environment noise, and branch protection rules that control who can push to env/prod. For eg. Bumping replicas from 1 to 3 in dev-values.yaml and the traditional setup shows a one-line diff in a values file.

With CI-based rendering, after the workflow runs, git diff origin/env/dev~1 origin/env/dev shows the actual manifest change. Diffing between environments is just as direct:



CI-Based Rendering Trade-offs

  • CI-based rendering is battle-tested and easy to understand, but it moves complexity into the CI pipeline.

  • A workflow must be maintained to stay in sync with the chart. If CI breaks, rendering stops and deploys stall.

  • The rendering logic lives in CI YAML rather than declaratively in the GitOps config, and Git push credentials have to be managed in CI.

  • Pipeline complexity grows with the number of apps times environments, and there's no built-in promotion mechanism: moving changes from dev to staging is still manual.

Approach 2: sourceHydrator

How sourceHydrator Works

sourceHydrator is a first-class Argo CD feature that does what the CI pipeline does, built into Argo CD itself. Instead of spec.source, spec.sourceHydrator is used, with two sections: drySource, where the un-rendered chart lives, and syncSource, the branch and path the rendered output gets pushed to.

spec:
  sourceHydrator:
    drySource:
      repoURL: https://github.com/your-org/your-repo
      path: guestbook
      targetRevision: HEAD
      helm:
        valueFiles:
          - environments/dev-values.yaml
    syncSource:
      targetBranch: environments/dev
      path

Argo CD detects changes on main, renders the manifests with its repo-server, and pushes the hydrated output to the target branch through a dedicated commit-server component. It then syncs from that branch, the same outcome as the CI approach, with no pipeline to maintain. Unlike the traditional CI-based rendering, it’s Argo CD that is running the helm template command but instead of storing those rendered manifests in the cache, it pushes those rendered manifests to the `syncSource.targetBranch`.

The rendering config lives declaratively in the Application CR rather than in a workflow file. Push credentials are managed separately through repository-write secrets in the argocd namespace, isolated from pull credentials. The hydrator tracks hydration state with Git notes and only commits when manifests actually change. It also supports a hydrateTo field, a staging-branch pattern where rendered manifests land on a review branch first and a PR gates promotion to the sync branch, providing human review of the actual rendered output before it reaches the cluster.

sourceHydrator Trade-offs

sourceHydrator is the simplest setup, with no CI pipeline or external tools required. It's currently alpha, it doesn't watch image registries for new tags, and its promotion capabilities are limited to the hydrateTo PR pattern. Teams that need a full promotion pipeline need something more.

Approach 3: Kargo

How Kargo Works

Kargo combines rendering with environment promotion in a single declarative pipeline. It introduces a few concepts: a Warehouse that watches sources, such as image registries or Git repos, for new artifacts. Freight is a versioned bundle of those artifacts such as a new image tag or commit that needs to be promoted. A Stage represents an environment with a promotion template defining what happens when new Freight arrives. Promotion is the act of rendering manifests and pushing them through the pipeline. Jesse Suen, Alexander Matyushentsev, and Hong Wang, the original creators of Argo CD, also created Kargo.

Each Stage defines a sequence of steps: clone the repo, optionally update the image tag, render with helm template, commit the rendered output to an environment branch, push, and trigger Argo CD to sync.

Kargo adds image watching: a Warehouse can subscribe to a registry and create Freight automatically when a new tag appears. It enforces stage ordering, so Freight must pass through dev before it can be promoted to staging, declared with requestedFreight.sources.stages. It supports conditional steps, so the same Stage definition handles both image promotions and config promotions by checking the origin of the incoming Freight. And it provides pipeline visualization in the Kargo UI, showing Warehouses, Stages, and Freight flowing through, with manual or automated promotion.

When a new image tag appears, the Warehouse creates Freight. Promoting that Freight to dev has Kargo clone the repo, update the image tag in the dev values file, render the chart, commit to env/dev, push, and trigger an Argo CD sync. Once dev is verified, the same Freight promotes to staging and then prod with their respective values. A direct config change on main follows the same pipeline, skipping the image update step and re-rendering with the new values.

Kargo Trade-offs

Kargo is the most capable option: rendering, promotion, image watching, and stage gating in one tool. It's also an additional system to install and operate. Teams that just need rendered manifests without a promotion pipeline may find CI or sourceHydrator sufficient.

Approach 4: OCI Artifacts

How OCI Artifacts Work

The three approaches above store rendered manifests in Git branches. OCI offers an alternative: push the rendered manifests to a OCI registry as an OCI artifact and have Argo CD pull from there.

The rendering step is identical; helm template still produces plain YAML. Instead of committing to a branch, the output is packaged and pushed with ORAS:

helm template guestbook-dev guestbook \
  -f guestbook/environments/dev-values.yaml \
  > manifests.yaml

tar -czvf

The Argo CD Application points at the OCI registry instead of a branch:

source:
  repoURL: oci://ghcr.io/your-org/guestbook-manifests
  targetRevision: dev-latest
  path: .

Argo CD pulls the artifact, extracts the YAML, and syncs.

Native OCI support has been available since Argo CD v3.1. Blake Pettersson, Senior Solutions Architect at Akuity and Argo CD Maintainer, led the effort to bring OCI registry support into Argo CD as a first-class source type, extending the pattern already established for container images to deployment configuration.

OCI adds three things:

  • Immutability: Git branches can be force-pushed, but OCI digests are content-addressed, so a digest always refers to the same content, and production can pin to a digest rather than a mutable tag.

  • Signing: Tools like cosign and notation sign OCI artifacts natively, allowing cryptographic verification that what's deployed to production matches what the CI pipeline produced.

  • Unified infrastructure: Container images and deployment manifests live in the same registry, authenticated and cached the same way, which also simplifies air-gapped environments where mirroring an OCI registry is already standard practice.

OCI Artifacts Trade-offs

OCI wins on immutability and supply chain security but loses some developer ergonomics. Diffing environments with Git branches is as simple as running a one-line git diff. With OCI, both artifacts need to be pulled locally first, and registry tags don't provide the same linear history as git log. Many teams run both: Git branches as the primary workflow for visibility and collaboration, OCI as an additional distribution mechanism for security and air-gapped scenarios.

A Note on Secrets

This pattern is incompatible with tools that render encrypted secrets at apply time, such as Kustomize with SOPS. Those tools rely on in-cluster tooling to decrypt secrets during rendering, which means the decrypted secrets would end up in plain text on the environment-specific branches or in the OCI artifact. Before adopting this pattern, use a tool like External Secrets Operator, which stores only a reference to the secret data in Git and lets an in-cluster controller generate the actual Kubernetes Secret. This is the safer approach regardless of whether the Rendered Manifests Pattern is adopted.

Choosing the Right Approach

There's no single right answer. It depends on where a team is and what problem is being solved.

Start with CI-based rendering if visibility and auditing are the priority. It's the simplest to set up, uses familiar tools, and delivers the core benefits: rendered manifests in Git, clean diffs, an auditable history.

Move to sourceHydrator for the same outcome with less maintenance. No CI pipeline to manage, declarative rendering config, and the hydrateTo pattern provides a review gate. Keep in mind it's currently alpha.

Adopt Kargo when a real promotion pipeline is needed: declarative stage gating, image watching, and a unified rendering-and-promotion workflow across multiple environments.

Add OCI when immutability and supply chain security matter. OCI doesn't replace other approaches; it's an alternative storage layer for rendered output, useful alongside Git branches or as the primary mechanism in air-gapped or compliance-heavy environments.

The core idea stays the same across every implementation: render once, store durably, sync plain YAML. Whichever method produces and stores the rendered output, Argo CD applies it the same way, with full visibility, no rendering at sync time, and complete auditability.

The State of Rendered Manifests in 2026

Kubernetes environments accumulate complexity fast: Helm charts, Kustomize overlays, environment-specific values, and templating logic layered across repositories. Cloud native organizations running GitOps at scale face a recurring problem: manifests defining desired state become harder to inspect as more tooling sits between Git and the cluster. Drift becomes difficult to trace. Reviews miss what will actually deploy. Debugging requires reconstructing what a template engine produced rather than reading what was committed.

The Rendered Manifests Pattern addresses this directly by ensuring the state stored in Git matches what reaches the cluster, without hidden transformation. Four approaches now implement this pattern: CI-based rendering, sourceHydrator, Kargo, and OCI artifacts. Each solves for a different priority: visibility, promotion, or supply chain integrity. Teams have the opportunity to choose the approach that fits their constraints, whether that means minimal infrastructure overhead, tighter promotion control across environments, or verifiable artifacts for supply chain security.

Want to Dive Deeper?

If you want to learn more about the Rendered Manifests pattern, check out our Advanced GitOps workshop. Be on the lookout for a upcoming webinars and events near you! Interested in a personalized demo book here.

Additional Resources


Ready to simplify delivery with Akuity?

Deploy, promote, and operate applications reliably, powered by OSS you trust and Intelligence you control.

Ready to simplify delivery with Akuity?

Deploy, promote, and operate applications reliably, powered by OSS you trust and Intelligence you control.

Ready to simplify delivery with Akuity?

Deploy, promote, and operate applications reliably, powered by OSS you trust and Intelligence you control.

Sign Up for Akuity Updates

Practical guidance on MTTR reduction, GitOps at scale, and safe automation, with product updates from the Argo CD and Kargo team.

@2026 Akuity Inc. All rights reserved.

Akuity Inc. 440 N. Wolfe Road, Sunnyvale, CA 94085-3869 US +1-510-771-7837

SOC2 Type 2 Compliant

Sign Up for Akuity Updates

Practical guidance on MTTR reduction, GitOps at scale, and safe automation, with product updates from the Argo CD and Kargo team.

@2026 Akuity Inc. All rights reserved.

Akuity Inc. 440 N. Wolfe Road, Sunnyvale, CA 94085-3869 US +1-510-771-7837

SOC2 Type 2 Compliant

Sign Up for Akuity Updates

Practical guidance on MTTR reduction, GitOps at scale, and safe automation, with product updates from the Argo CD and Kargo team.

@2026 Akuity Inc. All rights reserved.

Akuity Inc. 440 N. Wolfe Road, Sunnyvale, CA 94085-3869 US +1-510-771-7837

SOC2 Type 2 Compliant