Safeguard
Developer Tools•

Annotated or lightweight git tag: which should mark a release?

Use an annotated tag, ideally signed, to mark a release. A lightweight tag is only a name for a commit, with no date, author, message or signature.

Safeguard Security Team
4 min read

Use an annotated tag for every release, and sign it if you can. Git's own manual says annotated tags are meant for release, while lightweight tags are meant for private or temporary labels. An annotated tag records who tagged, when, and why. A lightweight tag records none of that.

What each kind of tag is

A lightweight tag is a name that points at a commit. That is all. There is no object behind it, so there is nowhere to store a message or a signature.

An annotated tag is its own object in the repository. According to the git documentation, it holds a creation date, the tagger name and e-mail address, a tagging message, and an optional cryptographic signature.

PropertyLightweightAnnotatedAnnotated and signed
Tagger and date recordedNoYesYes
MessageNoYesYes
Can carry a signatureNoNoYes
Meant for releases (per git docs)NoYesYes

Why it matters for a release

Three practical reasons.

  1. Accountability. When a user asks who cut version 2.4.0 and when, an annotated tag answers. A lightweight tag points at a commit and the commit author may be someone else entirely.
  2. Tooling behaviour. The manual notes that some git commands that name objects, such as git describe, ignore lightweight tags by default. If your build embeds a version string from git describe, a lightweight release tag can be skipped. We cover that in a separate post on why git describe skips your tag.
  3. A place for a signature. Only a tag object can carry one. A signed tag lets a downstream user check that the key holder vouched for that commit. See how to verify a signed git tag before you build.

How to create each

# lightweight
git tag v2.4.0

# annotated
git tag -a v2.4.0 -m "Release 2.4.0"

# annotated and signed with your configured key
git tag -s v2.4.0 -m "Release 2.4.0"

# push one tag
git push origin v2.4.0

Per the manual, passing a message with no explicit flag implies an annotated tag, but being explicit avoids surprises.

If you want signing to be the default, git has a configuration variable that signs annotated tags automatically when you create them. Check the current git-config page for the exact name and behaviour before you rely on it in scripts.

What a signature does and does not tell you

A signed tag shows that someone holding a particular key created it. It does not show the code is free of bugs or that the key holder was uncompromised. Treat it as one control among several: protected tags, a build in CI, and published checksums all cover different gaps.

A short release routine

  1. Make sure the release commit is on the protected default branch.
  2. Create a signed, annotated tag with a useful message.
  3. Push the tag and let CI build from it.
  4. Publish checksums or signatures for the built files.

Safeguard can scan the dependencies in the commit you are about to tag. The free scan is at gold.safeguard.sh/scan.

Quick check

Is a lightweight tag ever fine?

Yes, for private or temporary labels such as marking a commit while you debug. Do not use one as the public marker for a release.

Does signing a tag make it impossible to move?

No. A signature proves who created the tag object. Moving or deleting a tag is a repository permission question, which is why protecting release tags matters.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.