Using AWS Vault to authenticate to AWS CodeCommit

February 11, 2019

TL;DR

If you already use AWS Vault, you can use this command to use your AWS Vault credentials with CodeCommit:

$ git clone \
--config 'credential.helper=!aws-vault exec [AWS_VAULT_PROFILE] -- aws codecommit credential-helper $@' \
--config 'credential.UseHttpPath=true' \
https://git-codecommit.[AWS_REGION].amazonaws.com/v1/repos/[REPO_NAME]

where [AWS_VAULT_PROFILE] is your AWS Vault profile, [AWS_REGION] is the region, and [REPO_NAME] is the name of the repo in CodeCommit.

Using AWS Vault to authenticate to AWS CodeCommit

AWS CodeCommit has a number of ways to authenticate - if using an IAM user there are three options:

  1. Generate git credentials (username and password) in your IAM account and use them for HTTPS authentication
  2. Associate an SSH key with your IAM user
  3. Use AWS Access Key and Secret and API calls with a git credential helper

Having tried all three methods, I believe that, when used with AWS Vault, the third method of using the AWS API to interact with CodeCommit actually gives the best developer experience and the most flexibility in terms of account setup.

AWS Vault

First, let me talk a little bit about AWS Vault. AWS Vault is a terrific utility which helps to secure and manage AWS credentials on developers’ laptops. Basically, instead of keeping AWS Access Keys and Secrets in the ~/.aws/credentials file, you delegate that responsibility to aws-vault, which uses the underlying operating systems method of securing passwords to encrypt your AWS credentials.

Then, when you need to use those credentials, AWS Vault can seamlessly generate short-lived STS tokens from your primary credentials for your applications to use. To learn more, you can read the announcement blog post by 99designs, the organization that created it.

However, for our purposes, just know that AWS Vault makes working locally with AWS credentials easier and more secure, so if you are still managing profiles in ~/.aws/credentials you should definitely check it out!

Authenticating to CodeCommit

To start, make sure you have a valid IAM user setup within AWS Vault. You should be able to do something like this:

$ aws-vault exec ordinaryexperts-dev -- aws s3 ls
... lots of buckets
$

The IAM user should have permissions to access the relevant CodeCommit repositories. Also, this method will work with both MFA and / or IAM cross-account roles - however there are some tricks needed for MFA which we will address at the end of this article.

Now that we have that sorted, let’s create a CodeCommit repository to authenticate to. We’ll use the aws-vault login feature to quickly open up the AWS Console in a browser:

$ aws-vault login ordinaryexperts-dev

Then we can navigate to the CodeCommit service and create a new repository:

Create a CodeCommit Repository

Once the repo is created, CodeCommit will show us information about the HTTPS and SSH methods of connecting - we aren’t going to use these but I thought I’d show them here for reference.

HTTPS Instructions (for reference - don’t do this):

HTTPS CodeCommit Instructions

SSH Instructions (for reference - don’t do this):

SSH CodeCommit Instructions

You can see from the above instructions some of the limitations of the HTTPS and SSH approaches. For the HTTPS approach, it is yet another username and password you have to manage. For the SSH approach, notice that the git endpoint does not have any account related information, so you have to have a different SSH key for each AWS account and manage them in your ~/.ssh/config file.

So let’s connect using our third method! All we really need to do at this point is use some special arguments with our git clone command to tell git to use the AWS git credential helper - if you follow that link you’ll see that AWS recommends you set up git’s global configuration to use their CodeCommit git helper - that causes trouble when using non-CodeCommit repositories, so we’ll apply the settings to each git repository individually. We use the HTTPS endpoint to clone, but pass some extra arguments to set up the authentication:

$ git clone \
--config 'credential.helper=!aws-vault exec ordinaryexperts-dev -- aws codecommit credential-helper $@' \
--config 'credential.UseHttpPath=true' \
https://git-codecommit.us-west-2.amazonaws.com/v1/repos/test-repo
Cloning into 'test-repo'...
warning: You appear to have cloned an empty repository.
$ cd test-repo
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
$

There we go! All done. Now we can use our CodeCommit repository as normal. The --config commands we passed to the git clone command updated the .git/config file for the repository:

$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[credential]
    helper = !aws-vault exec ordinaryexperts-dev -- aws codecommit credential-helper $@
    usehttppath = true
[remote "origin"]
    url = https://git-codecommit.us-west-2.amazonaws.com/v1/repos/test-repo
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
$

We can see here that our credential settings are being applied for this repository.

MFA

If you use MFA with AWS Vault, then the MFA prompt will interfere with the git credential helper process like so:

$ git fetch
Enter token for arn:aws:iam::xxxxxxxxxxxx:mfa/dylan: warning: invalid credential line:  status code: 400, request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Username for 'https://git-codecommit.us-west-2.amazonaws.com/v1/repos/test-repo': ^C
$

The Enter token ... part is from AWS Vault, asking for your MFA token. However, the git credential chain doesn’t wait, so the AWS API call fails and git falls back to asking for a username for HTTPS authentication.

There are two ways that I know of to deal with this.

1) Make sure you already have entered MFA for your AWS Vault session before doing git operations

For example:

$ aws-vault exec ordinaryexperts-dev -- aws s3 ls
Enter token for arn:aws:iam::xxxxxxxxxxxx:mfa/dylan: 123456
$ git fetch
$

2) Create another AWS Vault profile without MFA just for CodeCommit

For this method, you can add another profile without MFA for CodeCommit to use:

$ aws-vault add ordinaryexperts-dev-git
Enter Access Key ID: xxxxxxxxxxxxxxxxxxxx
Enter Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Added credentials to profile "oe-dev-git" in vault
$

Then you may have some sections like this in your ~/.aws/config:

[profile ordinaryexperts-dev]
region=us-west-2
mfa_serial=arn:aws:iam::xxxxxxxxxxxx:mfa/dylan

[profile ordinaryexperts-dev-git]
region=us-west-2

Then when doing the git clone command, use the profile with the -git suffix. This technique also would make it easy to create another IAM user / role with just the needed permissions for the CodeCommit commands, helping with the Grant Least Privilege best practice.

Additional Resources

Hopefully this helps ease your use of CodeCommit with AWS Vault - here are some additional resources that were helpful to me in figuring this out:

Happy Coding!

Dylan