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:
- Generate git credentials (username and password) in your IAM account and use them for HTTPS authentication
- Associate an SSH key with your IAM user
- 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:
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):
SSH Instructions (for reference - don’t do this):
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 "ordinaryexperts-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:
- Alestic.com - Using AWS CodeCommit With Git Repositories In Multiple AWS Accounts
- AWS - CodeCommit Authentication and Access Control
- James Wing - Using CodeCommit and GitHub Credential Helpers
Happy Coding!
Dylan