Enforcing Code Quality with Bitbucket Branch Permissions: A Practical Guide
Learn how to lock down your main and release branches in Bitbucket, enforce approvals and build checks, and verify the setup—no guesswork, just step‑by‑step instructions.
11 Dec 2025, 07:25 UTC

Desired Outcome
The goal is to prevent accidental or unauthorized changes to critical branches (e.g., main or release/*) by enforcing:
- Only designated users or groups can push or delete.
- Pull requests must receive a minimum number of approvals.
- All CI builds must pass before a merge is allowed.
Prerequisites
- Bitbucket Cloud or Data Center/Server instance (v7.0+).
- Repository with admin rights (or project admin for global permissions).
- Active Bitbucket Pipelines project with at least one successful build defined.
- Users/groups that will be granted push/merge rights.
- Optional: REST API access token with
repository:adminscope.
Procedure
1. Define Branch Mask and Permissions (UI)
- Navigate to the repository settings:
Repository Settings > Branches > Branch Permissions. - Click Add a branch permission.
- Set Branch name pattern to
main(orrelease/*for all release branches). - Under Restrictions choose:
- Push:
Only adminsor specific groups. - Delete:
Only admins. - Merge:
Allowed only via pull request(enforces merge checks).
- Push:
- Save changes.
2. Configure Merge Checks (UI)
- Still in
Branch Permissions, click Add a merge check for the same branch pattern. - Enable:
- Minimum approvals: e.g., 2.
- Build status must succeed: select the pipeline that produces a
SUCCESSstatus.
- Save.
3. Verify Restrictions Locally (CLI)
Run the following as a non‑admin user to confirm push is blocked.
# Replace <repo-url> with your repository HTTPS URL
# and use a non‑admin account with git credentials set.
git clone <repo-url>
cd <repo-name>
# Attempt to push directly to main
git checkout -b temp-branch
# Make a trivial change
echo "test" >> README.md
git add README.md
git commit -m "Test push"
git push origin temp-branch:main
Expected output: remote: Permission denied or similar. If the push succeeds, the permission is mis‑configured.
4. Verify Merge Checks via Pull Request (Web UI)
- Create a PR from
temp-branchtomain. - Observe that the Merge button is disabled until:
- At least two reviewers approve the PR.
- Bitbucket Pipelines reports a successful build.
- Once both conditions are met, the button becomes enabled.
5. Optional: Use REST API for Automation
For large teams, scripting the permission setup can save time.
# Replace placeholders
API_URL="https://api.bitbucket.org/2.0/repositories/<workspace>/<repo_slug>"
TOKEN="Bearer <admin-access-token>"
# Create branch permission
curl -X POST "$API_URL/branch-restrictions" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "push",
"pattern": "main",
"users": ["[contact removed]"],
"groups": ["dev-team"]
}'
Check the response for a 201 status. If you receive a 400, review the JSON schema or pattern syntax.
Expected Checks
- Direct push attempts from non‑admin accounts return
Permission denied. - Pull requests show merge disabled until approvals and build status are satisfied.
- Repository settings page lists the branch permission and merge check entries.
- Pipeline runs are triggered automatically on PR creation.
Recovery Options
- Emergency hotfix: Grant yourself temporary
pushrights via the UI or API, perform the hotfix, then revoke the permission. - Pattern mis‑configuration: If the branch mask unintentionally blocks all feature branches, edit the pattern from
release/*torelease/*(ensuring correct regex) or remove the permission temporarily. - Rollback permission changes: Delete the branch restriction via UI (
Branch permissions > Delete) or API (DELETE <restriction-id>).
Limitations
- Bitbucket Cloud and Data Center/Server differ slightly in REST endpoints and UI layout; adjust URLs accordingly.
- Regex patterns are case‑sensitive; verify that the pattern matches your branch naming convention.
- Permissions are inherited from project-level settings; ensure no conflicting rules exist at the project level.
Practical Check
After configuring, perform a quick sanity test: create a new feature branch, push, open a PR, and confirm the merge button remains disabled until approvals and build pass. If all checks succeed, the protection is in place.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.