DEV Community

Georgi Tenev
Georgi Tenev

Posted on

Protecting your Git branches on AWS CodeCommit


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 the merge/commit actions for the ImportantRepo 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 in SelectedFew
  • use a Deny statement in a policy in Dev-Group to deny devs merge into master
  • attach a policy to SelectedFew which allows its users to merge into master

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.

Top comments (0)