Default branch is unprotected (GitLab)
Part of the GitLab project protection check · fix arrives as a guide
What it is
The default branch is not protected, so it accepts direct pushes and force pushes from anyone with developer access.
Why it matters
The branch you deploy from can be changed without review and its history can be rewritten. A force push removes commits with no trace of what was there before.
How to unprotect a branch (what most people searching this want)
Settings → Repository → Protected branches, find the branch, Unprotect. Via API:
curl -X DELETE "https://gitlab.com/api/v4/projects/$PROJECT_ID/protected_branches/main" \
-H "PRIVATE-TOKEN: $GITLAB_TOKEN"Legitimate reasons exist — renaming a default branch, unwinding an over-broad rule, archiving a project. Do it knowing what switches off.
What you lose the moment it is unprotected
Everyone with Developer access can now push straight to the branch — no merge request, no review, no pipeline gate — and force push, which rewrites history for every clone and can silently discard commits. Branch deletion also becomes possible. On the default branch, that is the difference between “main is what survived review” and “main is whatever was pushed last”.
Why an unprotected default branch is always a decision
GitLab protects the initial default branch automatically when a project is created. Finding it unprotected means someone removed the rule — usually to make a one-off push work — and the removal outlived the reason. This check exists to catch exactly that drift.
Re-protect it properly
curl -X POST "https://gitlab.com/api/v4/projects/$PROJECT_ID/protected_branches" \
-H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
-d 'name=main&push_access_level=0&merge_access_level=40&allow_force_push=false'The settings worth choosing deliberately are on the branch-protection check page — re-protecting with the weak defaults just schedules the next finding.
How lumioguard fixes it
The scan lists branches carrying deployments or marked default and verifies each has a protection rule. The fix arrives as a guide with the rule to create and the API call — and the check keeps watching, so a temporary unprotect that becomes permanent gets caught.
Run them all on your app
Connect your repo and your live services with read-only scopes. The first scan is free, and nothing changes without your approval.