Insufficient Flow Control Mechanisms
Code or artifacts can travel from a developer's keyboard to production without anything standing in the way.
If this is new to you
Think about the path a line of code takes from your editor to the thing your users touch. Somewhere along that path, something should be able to say no. That is all flow control means: a gate that can refuse.
It sounds bureaucratic until you notice what happens without it. If you can push a commit and that commit is live thirty seconds later, then anyone who gets hold of your laptop, your SSH key or your session cookie can also put code in production in thirty seconds. There is no second step where anybody notices. The whole attack is one step long.
The gate does not have to be heavy. A single required review, on the one branch that actually deploys, changes a compromise from an outcome into an attempt.
What to do about it
Protect the branch that deploys, and — this is the part people skip — include administrators in that protection. Most branch protection settings have a quiet exemption for repository admins, which means the accounts most worth stealing are the ones the rule does not apply to. That inverts the control entirely.
Require review from somebody who is not the author, and make sure "somebody" cannot be a second account the author controls or a bot they can trigger. Self-approval satisfies the letter of a review requirement and none of its purpose.
Then separate building from releasing. A build can be automatic and should be. A release is a decision, and decisions should be attributable to a person.
Going deeper
Once the obvious gates are in place, the interesting question becomes: what are all the paths to production, not just the intended one? If a laptop can reach the production host over SSH, branch protection is decoration — you have protected the front door and left the side gate open.
Tags are worth auditing specifically. If your pipeline deploys on tag creation, then the ability to create a tag is a deployment permission, and it is almost never governed like one.
Words used on this pagedefinitions
- Branch protection
- Rules a git host enforces on a named branch — requiring review, blocking force-pushes, requiring status checks to pass. The rules are only as good as their exemptions.
- Flow control
- Any mechanism that can stop a change progressing toward production. Review requirements, approval gates, staging environments, manual promotion steps.
Why this matters
Every other control in a pipeline assumes there is a gate somewhere. If a single actor can push, build and release in one motion, then compromising that actor is the whole attack — there is no second step to detect. Flow control is what turns a compromise into an attempt rather than an outcome.
What it looks like in practice
If any of these sound familiar, that is the point — most of them are things somebody did for a sensible reason on a busy afternoon.
- A default branch with no protection, so a direct push becomes a deployment.
- Branch protection that the repository's own administrators can bypass, which in practice means the people most worth compromising.
- A pipeline that auto-deploys on any tag, where creating a tag needs no review.
- Self-approval: a reviewer requirement satisfied by the author's second account, or by a bot the author controls.
- Artifact promotion straight from a build to production with no staging step that anyone actually looks at.
Check your own pipeline
Questions you can actually answer, rather than a maturity score. If you cannot answer one of them, that is itself the finding — and a more useful one than a number.
Can you push directly to the branch that deploys?
Try it on a scratch commit against a throwaway branch name that matches the protected pattern, and see whether the server refuses.
git push origin HEAD:refs/heads/main --dry-run
Can an administrator bypass the review requirement?
Read the branch protection settings specifically for the 'do not allow bypassing' and 'include administrators' options. This is the single most commonly left-open door.
Who or what can create a tag or release?
If tags trigger deployment, tag creation is a deployment permission. Audit it as one.
How to fix it
- Protect the branch that deploys, and include administrators in that protection. An exception for the most privileged accounts inverts the control.
- Require review from someone other than the author, and disallow self-approval by any identity the author controls.
- Separate 'build' from 'release'. A build can be automatic; a release should be a distinct, attributable act.
- Make the deployment path the only deployment path — if a laptop can reach production directly, branch protection is decoration.
Related
Did this get you to an answer?
No text box on purpose — please do not paste production logs anywhere
Risk taxonomy from OWASP Top 10 CI/CD Security Risks (Daniel Krivelevich and Omer Gil, September 2022, CC BY-SA 4.0). Explanations, checks, fixes and definitions written for this site.