
Protect your main/master branch in AWS CodeCommit by creating IAM policies that deny GitPush and merge operations on specific branch references. Junior developers can create and push to feature branches, while only senior developers (Approvers group) can merge pull requests into the protected main branch.
Introduction
AWS CodeCommit doesn't have native branch protection rules like GitHub or GitLab. To stop junior devs from pushing or merging directly to main/master, you have to do it through IAM policy conditions instead.
This post sets up two IAM groups (Juniors and Approvers). Juniors can create and push to feature branches but cannot merge to main. Approvers can merge. Same repo, two different access patterns enforced entirely through IAM.
Prerequisites
To follow along in this post, you should have:
- an AWS billing account
- a AWS IAM account with programmatic access and admin permissions to create roles, control services, and create objects in AWS
This pattern uses IAM policies for branch protection. Unlike GitHub or GitLab, CodeCommit doesn't have built-in branch protection rules - you must implement them through IAM policy conditions.
High Level Actions
- Create IAM Users: Junior Developer and SeniorDeveloper
- Generate CodeCommit Credentials JuniorDev and SeniorDev
- Create IAM Groups for Junior Developers Group and Approvers Group; add in respective members
- Attach Policies to Junior Developers Group to limit pushes and merges to master branch
- Attach policies for Approvers Group with more access to CodeCommit
- Create a Repository in CodeCommit
- Interacting with the Repository as Junior Developer and creating a Pull Request
- Interacting with the Repository as a Senior Developer to Review and Merge the branch
Create Users
aws iam create-user --user-name juniordev
aws iam create-user --user-name seniordev
Create Git Credentials for Users
aws iam create-service-specific-credential --user-name juniordev --service-name codecommit.amazonaws.com
aws iam create-service-specific-credential --user-name seniordev --service-name codecommit.amazonaws.com
Save the ServiceUsername and ServicePassword immediately after creation - they cannot be retrieved later. Store these credentials securely as they provide Git access to your CodeCommit repositories.
- Save the ServiceUsername and ServicePassword for each user as you will use them when interacting with git
Create Groups
aws iam create-group --group-name Juniors
aws iam create-group --group-name Approvers
Add Users to Groups
aws iam add-user-to-group --group-name Juniors --user-name juniordev
aws iam add-user-to-group --group-name Approvers --user-name seniordev
Create and Attach Policies to Groups
Juniors
- Create a file called juniorsPolicy.json with the contents:
{
"Version":"2012-10-17",
"Statement":[
{
"Effect": "Allow",
"Action": [
"codecommit:*"
],
"Resource": "arn:aws:codecommit:us-east-1:yourAWSAccountID:MyDemoRepo"
},
{
"Effect":"Deny",
"Action":[
"codecommit:GitPush",
"codecommit:DeleteBranch",
"codecommit:PutFile",
"codecommit:MergeBranchesByFastForward",
"codecommit:MergeBranchesBySquash",
"codecommit:MergeBranchesByThreeWay",
"codecommit:MergePullRequestByFastForward",
"codecommit:MergePullRequestBySquash",
"codecommit:MergePullRequestByThreeWay"
],
"Resource":"arn:aws:codecommit:*:*:*",
"Condition":{
"StringEqualsIfExists":{
"codecommit:References":[
"refs/heads/master"
]
},
"Null":{
"codecommit:References":"false"
}
}
}
]
}
The Condition block is key to branch protection. The "codecommit:References" condition restricts actions only when targeting refs/heads/master. Add "refs/heads/main" to the array if your repository uses 'main' as the default branch.
- Attach the Inline Policy
aws iam put-group-policy --group-name Juniors --policy-name JuniorsPolicy --policy-document file://juniorsPolicy.json
Approvers
- Create a file called approversPolicy.json with the contents (replacing us-east-1 with your region and 193591455755 with your AWS Billing Account ID:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codecommit:*"
],
"Resource": "arn:aws:codecommit:us-east-1:yourAWSAccountID:MyDemoRepo"
}
]
}
- Attach the Inline Policy
aws iam put-group-policy --group-name Approvers --policy-name ApproversPolicy --policy-document file://approversPolicy.json
Create Repository
aws codecommit create-repository --repository-name MyDemoRepo --repository-description "Description for MyDemoRepo"
Senior Developer Actions
Connect to Repository
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/MyDemoRepo
- Copy and paste the git credentials for the Senior Developer
Create and Add Content
cd MyDemoRepo
echo 'test1' > index.html
Commit and Push to Repository
git add .
git commit -m 'initial add'
git push
Junior Developer Actions
Connect to Repository
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/MyDemoRepo
- Copy and paste the git credentials for the Junior Developer
Create Branch and Add Content
cd MyDemoRepo
git checkout -b newFeature
echo 'testNewFeature' > index.html
Commit and Push to Repsoitory
git add .
git commit -m 'updated code'
git push origin newFeature
Merge (as Junior Developer)
This will produce an error:

aws codecommit create-pull-request --title "Merge newFeature into main" --description "new code" --targets repositoryName=MyDemoRepo,sourceReference=newFeature,destinationReference=master
aws codecommit merge-pull-request-by-fast-forward --pull-request-id "3" --repository-name MyDemoRepo
Merge (as Senior Developer)
This will NOT produce an error
aws codecommit create-pull-request --title "Merge newFeature into main" --description "new code" --targets repositoryName=MyDemoRepo,sourceReference=newFeature,destinationReference=master
aws codecommit merge-pull-request-by-fast-forward --pull-request-id "3" --repository-name MyDemoRepo
Move to Master and Delete Local and Remote Branch (as Senior Developer)
git checkout master
git branch -D newFeature
git push origin --delete newFeature
git pull
Bonus
For those with multiple git credentials in Windows and Credential Manager:
cmdkey /delete:git:https://git-codecommit.us-east-1.amazonaws.com
*Deletes the git entry*
cmdkey /generic:git:https://git-codecommit.us-east-1.amazonaws.com /user:"seniordev-at-193591455755" /pass:"JOs0yoySq/rU9+MESPYve4mZpfkA="
*Creates a git entry*
Use Windows Credential Manager commands (cmdkey) to switch between different CodeCommit user credentials when testing. This avoids the need to manually clear cached credentials.
Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| Junior developer can still push to master | IAM policy not attached or cache issue | Verify the policy is attached to the Juniors group. IAM policy changes can take a few seconds to propagate. Try the operation again. |
| "Unable to access" error when cloning | Git credentials not configured correctly | Verify the ServiceUsername and ServicePassword are entered correctly. Use git config --global credential.helper manager on Windows. |
| Senior developer also denied merge | User not added to Approvers group or wrong policy | Verify group membership with aws iam get-group --group-name Approvers. Check the Approvers policy doesn't include deny statements. |
| Policy condition not working | Wrong branch reference format | Use the full reference path: "refs/heads/master" not just "master". The condition is case-sensitive. |
| Credentials prompt appears repeatedly | Cached credentials conflict | Clear Windows Credential Manager entries for CodeCommit: cmdkey /delete:git:https://git-codecommit.[region].amazonaws.com |