Using Github's Dependabot with AWS CodeArtifact
Tags: cicd, tooling, cloud, devops
Published: 2023-05-16 13:01:02

Recently I wanted to use Github's [Dependabot](https://github.com/dependabot) in a repository with a private NPM registry in AWS [CodeArtifact](https://aws.amazon.com/codeartifact/). I ran into a credentials problem and used automation with Github Actions to solve it. This was thanks to some great tooling from Github and AWS. 

## Running into trouble
To allow Dependabot access to your CodeArtifact repository, you need an authorization token. My first thought was that I could manually get the token and paste it into my organization's Dependabot secrets in the Github UI. I could then tell Dependabot to use it in the `dependabot.yml` file.

Below is an example of the `dependabot.yml` file. Replace the angle brackets with your appropriate values.
```yaml
version: 2
registries:
  codeartifact:
    type: npm-registry
    url: https://<domain>-<account>.d.codeartifact.<region>.amazonaws.com
    # I called the secret CODEARTIFACT_TOKEN, you can call it whatever you want
    token: ${{secrets.CODEARTIFACT_TOKEN}}
updates:
 - package-ecosystem: "npm"
   directory: "/"
   schedule:
      interval: "weekly"
   registries:
     - codeartifact
```
But the idea didn't quite go as planned. I used the AWS CLI to get a token (see [here](https://docs.aws.amazon.com/codeartifact/latest/ug/tokens-authentication.html#get-auth-token-api) for more about tokens), but the problem I ran into was that the token expired after 12 hours. This is helpful for security hardening but a pain in my situation. I would have to manually ensure that an updated token is in the Dependabot secret before Dependabot does it's checks.

## Automation to the rescue
To solve this problem, I created a Github action that updated the Dependabot secret with a fresh token every 12 hours. I can do this using the AWS CLI to get the token (see [here](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html)), and the Github CLI to update the secret (see [here](https://cli.github.com/manual/gh_secret)). I used [OIDC](https://auth0.com/docs/authenticate/protocols/openid-connect-protocol#:~:text=OpenID%20Connect%20(OIDC)%20is%20an,obtain%20basic%20user%20profile%20information.) and `aws-actions/configure-aws-credentials@v2` [action](https://github.com/aws-actions/configure-aws-credentials) to assume the appropriate role. For more on OIDC in Github, click [here](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) for the official docs. If you are a newbie to AWS, this [post](https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/) shows how to set it up on AWS.

Below is the workflow file for the automation to update the token. Replace the angle brackets with your appropriate values.
```yaml
name: Update CodeArtifact Token

on:
  schedule:
    # CodeArtifact token expires in 12 hours, update token every 11 hours
    - cron: 0 */11 * * *
  # run manually if needed
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    # These permissions are needed to interact with GitHub's OIDC Token endpoint.
    permissions:
      id-token: write
      contents: read
    env:
      # need a token with admin access to update the secret
      GH_TOKEN: ${{ secrets.GH_CLI }}
    steps:
      - uses: actions/checkout@v3
      # using OIDC to assume the proper role 
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-region: <aws_region>
          # this should be the role arn that you created in AWS
          role-to-assume: arn:aws:iam::<account-number>:role/<your_role_name>
      - name: Get token and update secret
        run: |
          export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain <my_domain> --domain-owner <account_number> --region <aws_region>  --query authorizationToken --output text`
# Remember we called the organization secret CODEARTIFACT_TOKEN, make sure the code below matches whatever you called your secret
          gh secret set CODEARTIFACT_TOKEN --org <my_org> --visibility all --app dependabot --body "$CODEARTIFACT_AUTH_TOKEN"
```
With this workflow running, I can rest assured that Dependabot will always have a valid token. I am also using secure practices since my automation uses OIDC to assume a role with limited scopes. In addition, there are no long-lived AWS tokens in the actions. The incredibly powerful CLI's from AWS and GH really make it easy to build this kind of automation. Understanding these kinds of tools and familiarizing yourself with Github Action capabilities will set you up to build all sorts of automation. This will make your code safer and your life easier. 

_Cover photo by Tara Winstead: https://www.pexels.com/photo/robot-pointing-on-a-wall-8386440/_