A released tag cannot be moved or deleted, and only trusted principals may create one
A tag is the name a consumer installs by, and git lets anyone with push access repoint one at a different commit. Moving a released tag changes what every later fetch resolves to while the version number stays put, which is the one change a version number exists to make visible. Restricting who may create a tag matters for the same reason from the other end: where the registry reads the forge rather than taking an upload, creating the tag is the publish, so tag creation is the last gate before a version becomes public and the only thing standing where an approval gate would stand on the registry-push track.
Observable check
on GitHub, a repository ruleset targeting refs/tags/* blocks tag update and tag deletion and restricts tag creation to named principals, read back with gh api repos/{owner}/{repo}/rulesets rather than inferred from the write; on GitLab, protected tags cover the release tag pattern with a create access level set and no role permitted to force-update it, read back with GET /projects/:id/protected_tags. This rule covers a git tag only. A container registry tag is mutable by design, lives outside the forge, and is reachable by no forge control, so the immutable identity of a published image is its digest rather than its tag.
Where this comes from
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets
- https://docs.gitlab.com/user/project/protected_tags/
- https://go.dev/doc/modules/publishing
- https://go.dev/ref/mod
- https://proxy.golang.org/
Last read against these sources on 2026-07-31.
The forge mechanics are documented; the rule that a released tag must be immutable is this project's own position, and Go is where the consequence is written down by somebody else. Go's publishing guide states it directly: 'Don't change a tagged version of a module after publishing it... If the two differ, Go tools will return a security error.' The module reference explains why the author cannot undo it either, because the checksum database 'ensures that the bits associated with a specific version do not change from one day to the next, even if the module's author subsequently alters the tags in their repository', and the proxy adds that a bad release may stay cached even after the repository is deleted. Every other ecosystem has the same exposure without a checksum database to make it loud. The tag-creation half is the narrower claim and the newer one: it exists because the PUB preamble's tag-published track drops R-PUB-04, so without it anyone with push access can publish an immutable version with no gate at all. Retire the creation half if a forge ever offers an approval gate on tag creation itself, which would be the better control; retire the immutability half never, because nothing replaces it.