Repository navigation
Protect release tags from moving #45
Description
Add a tag ruleset to repo-settings, and apply it to dev-kit
Type: security · Component: scripts/repo-settings.sh
Problem
Consumers resolve dev-kit by tag: DEV_KIT_VERSION in the Makefile, which curls
common.mk, and the flake.nix input. GitHub tags are mutable, and two mechanisms adopt a moved
tag with nobody reading code:
renovate-dev-kit-lockresolves the tag to a commit and writes it toflake.lock,
unattended. The visible diff is anarHash.common.mkis fetched from the tag and-included into make.
dev-kit's flake is the shell every consumer's CI runs in, so a moved tag means code execution in
every job across the org.
check-dev-kit-pins (#44) only detects this, and is itself fetched from the tag it checks.
Fix: the ruleset in repo-settings, applied to dev-kit first
The ruleset is per repository, and repo-settings.sh is how every repo gets one — so this ships
as a helper there and each repo opts in by running the target. dev-kit is where it is urgent,
because its tags are what every consumer resolves; the consumers want it for their own releases
too, which is the follow-up tickets.
{ "name": "protect-release-tags", "target": "tag", "enforcement": "active",
"conditions": { "ref_name": { "include": ["refs/tags/v*"], "exclude": [] } },
"rules": [ { "type": "update" }, { "type": "deletion" } ] }Add it to repo-settings.sh beside the existing protect-main ruleset — same create-or-update
shape, roughly 25 lines, pattern and enforcement as REPO_* variables. dev-kit tracks its own
common.mk from main (DEV_KIT_VERSION := main), so dev-kit gets this as soon as it
merges, with no release needed.
Prerequisite: dev-kit has no REPO_* block in its Makefile today, so repo-settings is not
yet configured for dev-kit itself. That has to come first.
Not an org-wide ruleset. ~ALL would reach all 25 live repos for the sake of ~5 of ours,
including forks of upstream projects — external-dns-management,
machine-controller-manager-provider-hcloud, gardener-extension-provider-hcloud — where
syncing a fork legitimately moves upstream tags. Same cross-team-agreement principle as the
.github defaults.
No CI breaks: repo-settings.sh is admin-run only — the workflow token cannot manage
rulesets — and the rules are update/deletion, not creation, so every repo's release tooling
keeps tagging normally.
The one behavioural change
A v* tag can no longer be moved or deleted in a repo that has the ruleset. A botched
release is fixed by bumping to the next patch, not by retagging. Decide whether bypass_actors
exempts org admins — it keeps the escape hatch and weakens the guarantee by exactly that much.
Acceptance criteria
-
REPO_*configured for dev-kit, somake repo-settingscan run there. -
make repo-settingscreates or updates a tag ruleset; pattern and enforcement areREPO_*
variables. - Moving and deleting an existing
v*tag in dev-kit are both refused. - A new dev-kit release still tags successfully.
- A decision recorded on admin bypass.
- Immutable releases enabled on dev-kit as defence in depth — a toggle; check it is available
on the plan and fits release-drafter's publish-from-draft flow. - dev-kit's README states that release tags are immutable, so consumers know a pinned tag
cannot change under them.
Out of scope
- Rolling the ruleset out to consumers. Their own release tags are worth protecting, but it
is a different goal from this one and each repo decides its ownREPO_*. Follow-up tickets
per repo, after the dev-kit v3 migrations (artifact-conduit#499,apiserver-kit#132,
ocm-components#106). - The
common.mkfetch. Immutable tags stop a tag being repointed; publishing a new
release still executes arbitrary make code in every consumer. Signing or SHA-anchoring that
fetch is a separate design. check-dev-kit-pins(feat: add check-dev-kit-pins and a flake.lock closure diff #44) stays: it still catches ordinary pin drift, which is how Solar
ended up split across v2.1.0 and v2.2.0.ocm-kit— left the org, frozen atv0.1.4.
Relations
From review of #44. Prerequisite for installing dev-kit-bot beyond
opendefensecloud/solution-arsenal — that app is what makes the tag-to-commit conversion
unattended. Suggested in opendefensecloud/renovate-config#20's follow-up notes.
Unrelated, noticed while scoping: apiserver-kit's Makefile has two DEV_KIT_VERSION
lines (v2.0.0, v2.1.0). Harmless today, fails check-dev-kit-pins on its v3 adoption. Own
issue.
Activity
michael-c-tsi commentedon Oct 12, 2026
@AlexHardAtWork - name the repos in ACs