In this demo,
we're going to use GitHub Actions to upload Docker
images to the Docker registry.
We are also going to rebuild Docker images on a
schedule to reduce vulnerabilities.
Or in other words, we're going to take a proactive approach.
We're also going to see how Trivy can be circumvented.
This can be through Docker registry tampering.
And also,
we're going to investigate what types of vulnerabilities Trivy cannot find.
Okay, back to the proactive workflow we've seen earlier in this course.
In the last demo, we focused on the pull request process.
Now, it's time to focus on what occurs after the pull request is accepted.
There's a couple open questions here.
After scanning, how do the Docker images get into the Docker registry?
And also,
what happens if the Docker images housed in the registry are updated
outside of this process that's currently on the screen?
In other words,
if an attacker compromised our Docker registry
credentials and uploaded a malicious image,
how would we know?
We'll explore this in the upcoming demo.
Let's start with the workflow summary.
This workflow invokes a script that builds Docker images and
uploads them to the remote Docker registry.
Also,
this workflow invokes a script that does signature
validation to ensure Docker images within the Docker
registry have not been tampered with.
At this point, we're going to focus on the events that trigger this workflow.
First off is the schedule event.
When our Docker images are rebuilt, package updates occur.
By executing this workflow on a recurring schedule,
we minimize vulnerabilities that can be discovered by Trivy.
Now, this is just commented out to save resources. And while we're here,
I just want to take a little bit of time to dive
deeper into this update process.
The reason these updates occur is because we have a command in our
Dockerfile to update the operating system's packages.
This is simply an apt‑get upgrade command in our case.
But anyhow,
this upgrade command will depend on the operating system you're
leveraging within the Dockerfile. And once again, from a blue teamer
perspective, we are moving from a reactive to a proactive approach by
preventing vulnerabilities in the first place.
Second off is the push event.
When a pull request is accepted,
its code is merged into the main branch. At that point,
this workflow will be triggered and the Docker images will
be uploaded to the registry.
Next off is the path's ignore block.
When a Docker image is built, the image's unique signature is committed
into the main branch of the Git repo. Long story short,
the image_sha.txt will be created and committed into the main branch.
If we allowed this path to trigger this workflow,
there would be an infinite loop, so we just need to account for that
edge case. But don't worry too much about this,
we're going to dive deeper into this process in the next
section. Similar to the previous workflow file,
we check out the Trivy tutorial GitHub repo. But there's a difference
here. In this case, we use a separate GitHub user.
In other words, an automation user specifically for this workflow.
This user is given admin permissions so they can bypass the
branch protection roles and commit the Docker image signature
directly into the main branch.
For more context on this,
you can check out the setup instructions. Then we go ahead and install Trivy.
It's important to remember that every time this workflow is instantiated,
a fresh virtual machine is created.
In other words, it won't have Trivy installed, so every
single time we need to run the install script. Next, we log
into the Docker Hub image registry.
This allows us to eventually upload our Docker images. Once
again, for setup instructions on how to do this, check out the
README. Then, we get to the main logic and we invoke the
docker‑registry‑orchestrator script.
We'll explore the script's arguments in the next section.
The README also includes instructions on how to attach
secrets to your GitHub repo. Okay, let's check out that script.