Argo CD Config Management Plugins for custom manifest tools

Argo CD config management plugins let you render manifests with tools it does not ship, through a sidecar that reads plugin.yaml. This page covers how they work, what you trust when you add one, and what a partner plans.

On this page

When Argo CD needs a config management plugin for custom manifest tools

A Config Management Plugin is a sidecar that takes the output of a tool Argo CD does not render natively, such as a templating wrapper or an internal generator, and turns it into Kubernetes manifests that Argo CD can compare and apply. You need one when your team's source of truth is a generator rather than a plain manifest directory, Helm chart or Kustomize overlay, and you want Argo CD to own the sync instead of a pipeline that runs the generator and pushes results. In the Argo CD documentation, the plugin runs as a container next to argocd-repo-server, with argocd-cmp-server as its entrypoint, running as user 999. Its behavior is defined in a plugin.yaml file read from /home/argocd/cmp-server/config/plugin.yaml, which sets how the plugin is discovered for a repository and which command prints the rendered output.

Prefer a plugin only after you have checked the native options. If Helm or Kustomize can express your environments, a built-in source is simpler to upgrade and easier to review. A rendered-manifests workflow, where the generator runs in CI and commits its output to Git, moves the rendering out of the cluster's control plane and keeps Argo CD's repo-server free of custom code. A plugin fits best when the generator must run at sync time, for example because its inputs live outside Git. Confirm with your platform team which tool versions and binaries the sidecar image must carry, who owns that image, and how it is patched, because each of these becomes part of your delivery path.

Before you write plugin.yaml, decide what trust you are handing the plugin. The generate command must print valid Kubernetes YAML or JSON, and it runs on repository content inside the repo-server's execution context. The preserveFileMode and provideGitCreds settings both default to false and are security sensitive, so enable them only with a documented reason. Review every plugin the way you would review code that runs with access to your Git credentials and cluster-facing output. The Argo CD security documentation's warning about repository content applies here too: only let trusted repositories reach a plugin, and limit what the generator can read from the filesystem.

Plugin configuration options and when each fits

This table compares the plugin.yaml fields and Application-level settings that shape a Config Management Plugin, from discovery and generation to parameters and trust settings. Read each row as a decision: what the field does, when you need it, and whether it widens what the plugin can reach. The main takeaway is that the two security-sensitive flags, preserveFileMode and provideGitCreds, default to false and should stay that way unless a specific need justifies turning them on.

FieldWhat it controlsWhen to use itSecurity note
nameIdentifier the Application uses to select this pluginAlways set, so each plugin is referenced explicitly by ApplicationsLow risk, but unique names prevent a plugin from being chosen by mistake
discover rules (file pattern)Matches repository files that signal the plugin should handle an ApplicationUse when a specific file, such as a template marker, reliably identifies the sourceBroad patterns can claim Applications meant for another tool, so keep them narrow
discover rules (find command)Runs a command in the source directory and matches on its outputUse when detection depends on directory layout or several files togetherThe command runs inside the repo-server, so keep it read-only and simple
initCommand run once before generate, for example to fetch dependencies or prepare filesUse when the tool needs setup that should not repeat on each renderInit output and network access widen what the plugin can touch, so review what it downloads
generateCommand that must print valid Kubernetes YAML or JSON to standard outputRequired for every plugin, since it produces the manifests Argo CD appliesTest output with the same inputs Argo CD will pass, because invalid output fails the sync
parametersNamed inputs the Application can set, exposed to the generate commandUse when several teams reuse one plugin with different valuesParameters are user-controlled input, so validate them inside the generate command
preserveFileModeKeeps file permission bits from the repository when files are copied into the working treeEnable only when the tool needs executable files from Git, such as bundled scriptsDefault false. Enabling it lets repository content carry executable bits into the render
provideGitCredsPasses repository credentials to the plugin so it can clone or fetch other repositoriesEnable only when generate must pull from a private repository beyond the sourceDefault false. Enabling it exposes Git credentials to plugin code, so limit which plugins get them

How plugin.yaml discovery and generate commands fit together

Argo CD chooses a plugin for an application by running the discover rules in each plugin's plugin.yaml against the application's source directory. The file lives in the sidecar at /home/argocd/cmp-server/config/plugin.yaml, so the rules you write there decide which Git paths the plugin claims. Keep them narrow, because a rule that matches a common file name can capture applications that were meant for Helm or Kustomize. Before you ship, confirm in the official guide how Argo CD orders plugins and built-in tools when more than one rule matches, whether discovery matches file names, globs or both in your release, and how a discover failure is reported. Test each rule against a sample repository that includes application layouts that should not match.

The optional init command runs before generate and is meant for setup work, such as fetching a dependency or preparing a cache inside the working directory. The generate command does the rendering, and it must print valid Kubernetes YAML or JSON to standard output. Argo CD parses that stream as the application's manifests, so a log line, a progress bar or a stray debug print on stdout breaks the sync even when the generator itself succeeded. Send diagnostics to standard error, and validate the output in a test pipeline with a schema or dry-run check before the plugin reaches a cluster. Confirm in the guide what the repo-server does with a non-zero exit from init and whether init output is ever parsed.

Illustrative example: a minimal plugin.yaml for an internal generator called acme-gen might declare a ConfigManagementPlugin named acme-gen with a discover rule that matches a file such as acme-gen.yaml, an init command that restores generator dependencies, and a generate command that runs acme-gen render and prints the result. This shape is a sketch, not the official format. Before you rely on it, confirm the apiVersion and kind, the exact discover field names, and whether preserveFileMode and provideGitCreds should stay at their default of false. Enabling either one gives the plugin more of the repository or your Git credentials, so record why each change is needed and who approved it.

Choosing between a plugin, Helm, Kustomize and rendered manifests

Some teams already have an in-house program that turns service definitions into Kubernetes manifests. Argo CD does not ship a renderer for that tool, so a sidecar Config Management Plugin is the usual way to let the repo-server call it during a sync. The plugin adds a supported entry point: the generate command runs your generator against the checked-out source and must print valid Kubernetes YAML or JSON.

  • What the plugin adds: Argo CD diffs, syncs and reports health on the generator's output, with the same application view as Helm or Kustomize apps.
  • What you maintain: the plugin image, its plugin.yaml, the generator's versions and the discover rules that decide when the plugin runs.
  • What to confirm: whether the generator can run offline and without cluster access, whether it needs credentials, and who owns it after the original author moves on.
  • Trust to hand over: any file or network access the generator has is available inside the repo-server, so review what it reads.
  • Alternative to test first: whether the generator's output can be written as a Helm chart or Kustomize base with little loss.

Before committing, ask the team to show a repeatable, versioned generator with a documented output format. If the output depends on local state, the plugin will inherit that instability.

How to set up a config management plugin with checks

This sequence takes a custom manifest generator from a container image to a verified sidecar that Argo CD calls on a test Application. Each step ends with a check, so the team knows the plugin works before any production repository depends on it.

  1. Package the generator in a container image

    Your platform or build team builds an image that contains the templating wrapper or internal generator, its dependencies, and the argocd-cmp-server entrypoint that Argo CD expects. Pin the base image and the generator version so the output stays reproducible between builds. Run the image locally against a sample directory and confirm the generator prints valid Kubernetes YAML or JSON to standard output with no extra log lines mixed in. Store the image in a registry your cluster can pull from, and record the tag you tested.

  2. Add the plugin sidecar to argocd-repo-server

    Add the plugin container to the argocd-repo-server deployment as a sidecar, using your image and the argocd-cmp-server entrypoint. The sidecar runs as user 999, so confirm that the image, mounted volumes and any file permissions allow that user to read the repository workspace and write its temporary files. Apply the change through the same Git-managed path as the rest of your Argo CD installation. Check that the pod starts with both containers ready and that the sidecar logs show it has registered with the repo-server.

  3. Write the plugin.yaml configuration

    Create plugin.yaml at the path the sidecar reads, /home/argocd/cmp-server/config/plugin.yaml, typically by mounting it from a ConfigMap. Give the plugin a name, set the generate command to the wrapper's invocation, and add an init command only if the plugin needs preparation such as fetching dependencies. Leave preserveFileMode and provideGitCreds at their default of false unless a reviewed need exists, because both are security sensitive. Validate the file by running the generate command by hand inside the sidecar and confirming it exits successfully and prints only the expected manifests.

  4. Define discover rules for the plugin

    Add discover rules to plugin.yaml so Argo CD selects this plugin only for the directories it should handle. Rules can match on file names or on the presence of a specific file, so choose a marker file that your generator input uses and that other applications will not accidentally contain. Keep the rule narrow, because a broad match can route an application that Helm or Kustomize should render into your plugin. Verify the rule by listing which application paths it matches in a test repository and confirming that unrelated paths are not claimed.

  5. Declare parameters for application settings

    Define any parameters the generator needs, such as environment name, image tag or feature flags, so teams set them on the Application rather than editing the generator. Each parameter should have a clear name and a documented default, and the generate command should read values only through the parameters Argo CD passes in. Agree with the owners of the generator which values are safe for application teams to change and which belong to the platform team. Check the parameter wiring by setting one value on the test Application and confirming the rendered output changes as expected.

  6. Point a test Application at a non-production repository

    Create a test Application that uses the plugin and points at a non-production Git repository with sample generator input. Use a project with limited destinations and no production clusters as its target, so a mistake cannot change live workloads. Sync the Application and open the rendered resources in the UI or with the CLI, then compare them to the output you tested locally in the first step. Confirm the Application reaches a healthy, synced state and that repository credentials remain redacted in the logs and API responses.

  7. Verify output validity and the sidecar user

    Finish with checks that you can repeat on every change. Confirm the generate output is valid YAML or JSON that the API server accepts, for example with a server-side dry run or a schema validation step in your pipeline. Confirm the sidecar process runs as user 999 by inspecting the running container, since the default user and file access depend on the image and the Argo CD version. Record the Argo CD version and the plugin image tag together, then confirm the plugin behavior against the configuration reference for that version, because plugin fields and defaults can change between releases.

What you trust when you hand a plugin the repo-server

A config management plugin runs inside the repo-server's trust boundary, so whatever it executes, reads or receives is effectively trusted by Argo CD. The cards below cover the risks that follow from that: what repository content can trigger, which files a plugin can reach, two switches that widen access, what the sidecar can see, and the plugin image itself.

Repository content reaches executable code

The generate command runs on whatever the repository contains, and discover rules decide which applications a plugin claims. Any team with write access to a repository can therefore influence what code runs in the sidecar. Check who can merge to each repository the plugin discovers, and treat a plugin's discover rules as part of your change control, not just a convenience.

Out-of-tree file access

A plugin's generate step can read any file the sidecar process can reach, not only the application's own directory. Files from other applications or from the mounted filesystem can leak into rendered output. Confirm which paths the sidecar can see, keep the working tree limited to the application path, and review scripts that build paths from parameters.

preserveFileMode as a sensitive switch

The preserveFileMode setting defaults to false and, when enabled, keeps file permission bits from the repository inside the working copy. Executable bits from a repository can then carry into what the plugin reads or produces. Leave it off unless a specific tool needs it, and record each plugin that turns it on as an exception to review.

provideGitCreds as a credential exposure

The provideGitCreds setting defaults to false. When enabled, the plugin receives repository credentials so it can fetch additional Git content during generation. Those credentials then sit inside a process you wrote or adopted. Enable it only when the tool cannot work without it, use read-only credentials scoped to the repositories it needs, and confirm how the plugin logs or caches what it fetches.

Credentials visible to the sidecar

Argo CD redacts cluster, Git and OAuth2 credentials from its own API responses and logs, but a plugin script running in the sidecar is outside that redaction. Anything mounted into the sidecar container, including environment variables and secret volumes, is readable by the plugin. Mount only what the generate command needs, and verify that the plugin does not echo environment values into its output.

Patching and reviewing plugin images

The plugin image carries its own interpreters, templating binaries and library dependencies, and none of them are covered by Argo CD's release cadence. Pin image versions, rebuild when base images or tools receive fixes, and review changes to plugin.yaml and scripts through the same pull request process as application code. Ask who owns that rebuild cycle before the first plugin goes live.

Questions buyers ask about Argo CD plugins before hiring help

How much more effort is a config management plugin than a Helm or Kustomize source?

A plugin takes more work than a native Helm or Kustomize source because your team owns the rendering step end to end. Argo CD already ships Helm and Kustomize support, so those sources need only a chart or overlay path in Git. A plugin needs a container image with your tool, a plugin.yaml that defines discovery and a generate command, and tests that prove the output is valid Kubernetes YAML or JSON. The extra effort is mostly in building and maintaining that image and its configuration, not in the Argo CD side of the Application.

What drives the work up when we build a plugin?

The main drivers are the number of tools, the number of parameters each plugin exposes, the security review, and the testing required. Each tool adds its own image, discovery rules and generate logic. Each parameter adds a path that engineers must document and test. The security review grows when the plugin needs repository credentials or when file handling options such as preserveFileMode or provideGitCreds are enabled, since both default to false and are security sensitive. Testing scales with how many environments and Application shapes the plugin must render correctly.

What must our team supply before a partner can start?

Expect to supply four things: the generator source or the tool version it runs, a container image or build pipeline that packages it, read access to the repositories the plugin will render, and a named owner who makes decisions about the plugin after handover. Your team should also confirm which clusters and Argo CD instance the sidecar will run in, since the plugin runs next to argocd-repo-server. Ask any partner to list these inputs in the written scope so gaps show up before work begins.

Can our internal team build and run a plugin without outside help?

Yes, a team with Argo CD and container experience can build a plugin alone, provided it has time to test and someone accepts long-term ownership. The sidecar pattern is documented in the Argo CD Config Management Plugins guide, and the configuration is a single file plus a command. The risk lies in the trust the plugin receives: it runs as user 999 inside the repo-server pod and processes repository content. Teams that want an independent review of those permissions, or a second set of eyes on the generate logic, often bring in a partner for that part only.

How long does a plugin project take, and what decides it?

Duration depends on scope, and no single figure applies to every plugin. A plugin for one tool with a few parameters and a clear owner is a much smaller project than several generators with credential handling and a security review. Ask for a schedule with milestones for image build, plugin.yaml design, test coverage, security review and cutover. Also ask how many Applications will be migrated and whether a parallel run is planned. A written scope should state these inputs so the timeline can be compared across quotes.

How do plugin upgrades interact with Argo CD upgrades?

Plugin upgrades and Argo CD upgrades are separate changes that can affect each other. Argo CD minor releases ship four times a year and only the three most recent minor versions receive patch releases, so a plugin built against an older sidecar setup may need review when you move versions. The sidecar must match the configuration your Argo CD version expects, and the tool inside the plugin image has its own release cycle. Test both changes in a non-production instance, pin image versions, and confirm the upgrade notes for each Argo CD release before scheduling the move.

What should we check in a plugin before it goes into production?

Check that the generate command prints valid Kubernetes YAML or JSON for every Application it will serve, that discovery rules match only the intended repositories, and that preserveFileMode and provideGitCreds are set to false unless a documented need exists. Confirm that the plugin cannot read files outside its repository path, since the security documentation flags out-of-tree file access as a risk. Finally, confirm that a named owner, a rollback path and a test suite exist before the first sync.

Keeping a plugin working across Argo CD upgrades

A sidecar Config Management Plugin is part of your Argo CD runtime, so it has to move with every Argo CD upgrade. Pin the plugin's container image to a specific tag or digest rather than a floating tag, and treat the image, the plugin.yaml file and the argocd-cmp-server entrypoint as one versioned unit. Record which Argo CD minor version each plugin build was tested against, so a later change to the repo-server image cannot silently change the environment your manifests were rendered in.

The project ships a minor release about once every three months and only patches the three most recent minors. That cadence sets your test rhythm: each new minor should be tried against a staging instance that runs the same plugin image, with a representative set of Applications that use discover rules and generate commands. Confirm with your team which minor versions you intend to run and how long you can stay on a minor that has left patch support, because a plugin that still works today may need a rebuild when the base image or the repo-server behavior it depends on changes.

Major upgrades deserve closer reading. The 2.14 to 3.0 upgrade notes change RBAC so that update and delete permissions apply only to the application itself, and logs access now needs an explicit logs, get permission. Plugin users may therefore see different results from the UI or CLI even when rendering is unchanged, so check that each team's roles still cover the actions they perform on plugin-backed Applications. Annotation-based resource tracking is the default in that release as well, which can change how the plugin's output is tracked. Confirm each of these against the upgrade notes for your target version before you move a production instance.

How DeployOpen scopes and delivers Argo CD plugin work

DeployOpen plans, builds, documents and supports Config Management Plugins for Argo CD inside your own infrastructure, starting from a written scope. Each plugin is reviewed for what it can read, run and write before it reaches a production repo-server, so the trust you hand it is decided deliberately.

How we scope

  • Inventory every custom tool the plugin must run, its version, and the inputs it reads from Git.
  • Decide whether the plugin needs repository credentials or write access to anything beyond the rendered output.
  • Agree the written scope, deliverables and timeline in writing before any build work starts.

How we build

  • Write the plugin.yaml discovery rules, parameters and generate command as a sidecar on argocd-repo-server.
  • Keep preserveFileMode and provideGitCreds at false unless a documented need justifies enabling them.
  • Test generate output against valid Kubernetes YAML or JSON and against your sample applications.

How we hand over

  • Deliver the plugin configuration, sidecar manifests and a runbook covering discovery, parameters and failure modes.
  • Document the trust decisions made, including what the plugin can access on the repo-server and why.
  • Walk your platform team through a test sync so they can run and change the plugin themselves.

How we support

  • Offer ongoing support, upgrades and testing of the plugin as a retainer after handover.
  • Review plugin changes when the Argo CD minor release or the custom tool version changes.
  • Confirm the plugin still works with your supported Argo CD patch releases before you upgrade.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.