Securing GitHub CodeSpaces with Trivy
In this article I show how to create a container for GitHub CodeSpaces for some Azure + Terraform work. Usually, azterraform from Microsoft is my go-to, but in this instance I needed a PowerShell base, and the addition of the GitHub CLI client.
Obviously, it has to be built in CI, and let’s add some security love with Trivy too!
You can re-use this same process to make your own CodeSpaces container (or any container, for that matter), with the tools that work for your use cases.
Updating the GitHub PR with Trivy results
Here’s the CI pipeline in a nutshell:
- Build the docker image & scan it for security smells.
- Publish the report summary table as a comment on the PR.
- Create a link to the full Trivy report on the Actions step summary page.
Here’s some pictures from the end state:
The Trivy report table posted as a PR comment - and a link to the full report
We're going to use the Actions 'summary' page for the full report
A taster from the full outputBuild the workflow
The full workflow is available in /.github/workflows/docker-pr-build-and-scan.yml.
Starting at the top:
| |
With the fine-grained access model, we need to make sure the permissions block allows write access to the PR, so we can add comments
| |
The build process is pretty standard - in the final step we’re using Aqua Security’s GitHub Action for Trivy to run the scan.
| |
This will take the Trivy report and extract just the report table at the top, and then add this to the PR as a comment
| |
Finally - we use the “well known” variable GITHUB_STEP_SUMMARY to post the contents to the Actions log.
That’s the end of the PR flow.
Publishing to Docker Hub
A separate action publishes the container to Docker Hub once the PR is merged.
Here it is: kewalaka/az-pwsh-terraform - Docker Image | Docker Hub
Use in CodeSpaces
Here’s an example of how you can use this in your own repositories, including the config to switch the default shell to PowerShell (place in .devcontainer/devcontainer.json)
| |
Here is an example: terraform-azure-starter-template/.devcontainer/devcontainer.json
Call to action
Perhaps try this container out in your own CodeSpaces?
It is very customised to my use case hence you may not agree with my choice of tooling - but you can always simply re-use the above with just a change to the Dockerfile, then have one that works just for you!
Where next?
In my first iteration, I built the container on the PR, and then I re-build it when pushing to Docker Hub, and when tagging.
This is sub-optimal, because what I end up with after the PR might not be the same as what gets built in the deploy or tagging stage.
In the next article, I’ll illustrate one way to fix this - by using GHCR as a staging ground before promoting it to Docker Hub.
