For production, pin Argo CD to a commit SHA or a version tag that your team controls, and keep HEAD or branch tracking for development. The Argo CD documentation calls commit pinning the most restrictive option and says it is typically used to control production, because a SHA cannot change meaning.
What targetRevision actually decides
An Argo CD application points at a source, usually a Git repository or a Helm chart repository. The targetRevision field says which version of that source the cluster should match. Whatever that field resolves to becomes the desired state, and with auto-sync on, a difference is applied as soon as it is detected.
That makes it a dependency decision. A manifest repository you do not fully control, such as a shared platform repo or a third-party chart, is a dependency like any library. The question is how much of its future you accept without review.
The four ways to track
| Strategy | What you write | What moves it | Typical use |
|---|---|---|---|
| Branch or HEAD | A branch name or HEAD | Any push to that branch | Local development |
| Tag | A Git tag | Retagging, or a new tag if you use a range | Staging |
| Semver range | A range such as 1.2.* | A new matching tag | Pre-production patch tracking |
| Commit SHA | A full commit hash | Only an edit to the application | Production |
The documentation describes branch tracking as continually comparing live state against the tip of the branch. It describes tags as generally more stable, but notes that a tag can be redeployed by retagging it to a different commit. A tag is a convention, not a lock.
For Helm sources, chart versions are semantic versions, so ranges apply there too. The same page lists a star range for local development and an exact version such as 1.2.0 for production.
Where the risk hides
Three habits cause most surprises.
First, tracking HEAD in production. Any merged change to the manifest repo reaches the cluster on the next sync, including changes made by people who did not know that repo feeds production.
Second, trusting a tag you do not protect. If anyone with write access can move a tag, a tag pin is only as strong as your tag protection rules. Check who can force-push or delete tags in that repository.
Third, ranges that silently widen. A star range follows every release. The docs also note that pre-release tags are only compared when you add the -0 suffix, so a range can behave differently from what you read at a glance.
A simple promotion pattern
- Development tracks a branch, so changes show up quickly.
- Staging tracks a tag or a narrow patch range.
- Production pins a commit SHA, changed by a pull request that someone other than the author reviews.
- The pull request that bumps the SHA shows the diff between the old and new commit, so the reviewer reads real changes.
Because the SHA only changes when someone edits the application, you also get a clean audit trail: every production change corresponds to a reviewed commit in the repository that holds your application definitions.
One caveat from the docs: parameter overrides can still be set on an application pinned to a revision, so pinning does not freeze every input. Review overrides as part of the same change.
Where a scanner fits
Pinning tells you what version you run. It does not tell you whether that version is vulnerable. Safeguard's dependency scanning and SBOM generation can inventory the charts, images and manifests behind a pinned revision, and its pull request gates can hold a change that introduces a known problem. Check that your scanner reads the file types in your manifest repository. You can try a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Watch how a gate holds a change before it merges, which is the same checkpoint you want in front of a production SHA bump.
Quick check
Is a Git tag as safe as a commit SHA?
Not by default. The Argo CD documentation says a tag can be redeployed by retagging it to a different commit, while a commit SHA cannot change meaning. A tag is safe only if you restrict who can move or delete tags.
Can I use a semver range on a branch?
No. The documentation says semver constraints are matched only against tags, never branches, because semver resolution uses the list of Git tags.
Sources
Last reviewed: 19 October 2026.