Protecting your Git branches on AWS CodeCommit
Georgi Tenev
Posted on March 19, 2019
Borovets, Rila mountain, Bulgaria
This post gives a quick recipe on how to enable only selected users to merge/commit into CodeCommit Git branches.
The problem
Let's consider a common CD/CI scenario:
1) you have a team which pushes to a Git repo with important code.
2) when ready for a deploy, someone merges dev
into master
3) the merge event triggers a preconfigured deployment pipeline which would package the code from the repo and then delpoy it to production
The above is very nice and all, but care must be taken when it comes to who should be allowed to merge into the production branch.
The solution
(jump straight to the sample IAM policies)
Since we are in the context of AWS, the solution lies in using the IAM service (Identity and Access Management).
Here are the main steps of the solution:
- Have a generic group for all developers, say
Dev-Group
. All developers within your team belong to this group. Generic CodeCommit actions are allowed - e.g.pull
,clone
, etc. - Also attach to the
Dev-Group
a policy which specifies the repositories which we want to protect via the NotResource. For all other repos developers can have full access, if so desired. - Have a second IAM Group - e.g.
ImportantRepo-PowerUser
- it has a policy which enables themerge
/commit
actions for theImportantRepo
repo. - Add the selected few developers which should be able to trigger a build to this
ImportantRepo-PowerUser
group
Why bother writing this article - well, it's not that obvious how to implement the above. The tricky part is the evaluation logic of IAM. Due to it, the naïve solution below won't work:
- all devs in
Dev-Group
, the selected few inSelectedFew
- use a
Deny
statement in a policy inDev-Group
to deny devs merge into master - attach a policy to
SelectedFew
which allows its users to merge intomaster
If in the Dev-Group
you add a statement which explictly forbids (with a Deny
) users of the group to merge into master, then it's not possible to allow these actions in a different policy - so it won't be possible to allow our selected few developers to merge.
This is where the NotResource
comes in handy. With it you can exclude the protected repositories from a given statement without explicitly using the Deny
action. I.e. you can give full perms to all repositories excluding the protected ones. Since we haven't explicitly Deny-ied actions on the protected repositories, we can later add explicit Allow in a different policy - in a policy attached to the SelectedFew
group.
Show me the code
dev-group-generic-policy
We need the Dev-Group which gives generic permissions to all devs and also lists the protected repositories.
// the policy atached to the Dev-Group
{
"Version": "2012-10-17",
"Statement": [
// generic permissions for all devs
{
"Effect": "Allow",
"Action": [
"codecommit:Get*",
"codecommit:GitPull",
<whatever you need but not Push/Merge/etc.>
],
"Resource": "*"
},
// the gotcha - in the NotResource put the important repos whose branches you want to protect
{
"Effect": "Allow",
"Action": [
"codecommit:GitPush",
"codecommit:DeleteBranch",
"codecommit:Merge*"
],
"NotResource": [
"arn:aws:codecommit:*:*:<important-repo-name-1>",
"arn:aws:codecommit:*:*:<important-repo-name-2>"
]
},
// still allow all devs to push to non-production branches of the imporant repos
{
"Effect": "Allow",
"Action": [
"codecommit:GitPush",
"codecommit:DeleteBranch",
"codecommit:Merge*"
],
"Resource": [
"arn:aws:codecommit:*:*:<important-repo-name-1",
"arn:aws:codecommit:*:*:<important-repo-name-2"
],
"Condition": {
"StringNotEquals": {
"codecommit:References": [
"refs/heads/master",
"refs/heads/prod",
"refs/heads/Stg"
]
}
}
}
]
}
important-repo-1-power-users
A group for the power users for a specific important repo.
// the policy attached to the group for users that can push to all branches for a given important repo
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codecommit:GitPush",
"codecommit:DeleteBranch",
"codecommit:Merge*"
],
"Resource": [
"arn:aws:codecommit:*:*:<important-repo-name-1>",
]
}
]
}
To make the solution more generic, you can use some naming convention for the repositories - i.e. all repo names starting with xyz-
are considered important and only users in group xyz-power-users
can merge into the prod branch of these repos.
Posted on March 19, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.