WEBVTT

00:00:02.440 --> 00:00:03.220
In this demo,

00:00:03.230 --> 00:00:05.520
we're going to use GitHub Actions to upload Docker

00:00:05.520 --> 00:00:07.560
images to the Docker registry.

00:00:09.040 --> 00:00:11.370
We are also going to rebuild Docker images on a

00:00:11.370 --> 00:00:13.410
schedule to reduce vulnerabilities.

00:00:13.410 --> 00:00:16.560
Or in other words, we're going to take a proactive approach.

00:00:18.640 --> 00:00:21.550
We're also going to see how Trivy can be circumvented.

00:00:22.740 --> 00:00:25.340
This can be through Docker registry tampering.

00:00:25.340 --> 00:00:26.850
And also,

00:00:26.850 --> 00:00:30.660
we're going to investigate what types of vulnerabilities Trivy cannot find.

00:00:33.340 --> 00:00:37.850
Okay, back to the proactive workflow we've seen earlier in this course.

00:00:37.850 --> 00:00:41.570
In the last demo, we focused on the pull request process.

00:00:41.870 --> 00:00:46.160
Now, it's time to focus on what occurs after the pull request is accepted.

00:00:46.840 --> 00:00:48.850
There's a couple open questions here.

00:00:48.850 --> 00:00:53.360
After scanning, how do the Docker images get into the Docker registry?

00:00:54.040 --> 00:00:54.750
And also,

00:00:54.760 --> 00:00:59.260
what happens if the Docker images housed in the registry are updated

00:00:59.270 --> 00:01:02.260
outside of this process that's currently on the screen?

00:01:02.740 --> 00:01:03.490
In other words,

00:01:03.500 --> 00:01:06.040
if an attacker compromised our Docker registry

00:01:06.040 --> 00:01:08.760
credentials and uploaded a malicious image,

00:01:08.820 --> 00:01:09.850
how would we know?

00:01:10.240 --> 00:01:12.540
We'll explore this in the upcoming demo.

00:01:12.590 --> 00:01:14.230
Let's start with the workflow summary.

00:01:14.520 --> 00:01:18.440
This workflow invokes a script that builds Docker images and

00:01:18.450 --> 00:01:20.860
uploads them to the remote Docker registry.

00:01:21.540 --> 00:01:22.210
Also,

00:01:22.280 --> 00:01:25.300
this workflow invokes a script that does signature

00:01:25.300 --> 00:01:28.890
validation to ensure Docker images within the Docker

00:01:28.890 --> 00:01:31.050
registry have not been tampered with.

00:01:32.040 --> 00:01:35.960
At this point, we're going to focus on the events that trigger this workflow.

00:01:36.740 --> 00:01:38.560
First off is the schedule event.

00:01:39.240 --> 00:01:43.210
When our Docker images are rebuilt, package updates occur.

00:01:43.210 --> 00:01:46.430
By executing this workflow on a recurring schedule,

00:01:46.430 --> 00:01:50.060
we minimize vulnerabilities that can be discovered by Trivy.

00:01:50.740 --> 00:01:55.580
Now, this is just commented out to save resources. And while we're here,

00:01:55.590 --> 00:01:58.070
I just want to take a little bit of time to dive

00:01:58.070 --> 00:02:00.060
deeper into this update process.

00:02:00.640 --> 00:02:03.820
The reason these updates occur is because we have a command in our

00:02:03.820 --> 00:02:07.260
Dockerfile to update the operating system's packages.

00:02:07.740 --> 00:02:10.820
This is simply an apt‑get upgrade command in our case.

00:02:11.340 --> 00:02:12.130
But anyhow,

00:02:12.140 --> 00:02:15.320
this upgrade command will depend on the operating system you're

00:02:15.320 --> 00:02:20.040
leveraging within the Dockerfile. And once again, from a blue teamer

00:02:20.040 --> 00:02:25.250
perspective, we are moving from a reactive to a proactive approach by

00:02:25.250 --> 00:02:27.750
preventing vulnerabilities in the first place.

00:02:28.440 --> 00:02:30.360
Second off is the push event.

00:02:30.840 --> 00:02:32.640
When a pull request is accepted,

00:02:32.650 --> 00:02:36.810
its code is merged into the main branch. At that point,

00:02:36.820 --> 00:02:39.470
this workflow will be triggered and the Docker images will

00:02:39.470 --> 00:02:41.250
be uploaded to the registry.

00:02:43.340 --> 00:02:45.510
Next off is the path's ignore block.

00:02:45.530 --> 00:02:49.830
When a Docker image is built, the image's unique signature is committed

00:02:49.840 --> 00:02:54.380
into the main branch of the Git repo. Long story short,

00:02:54.390 --> 00:03:00.630
the image_sha.txt will be created and committed into the main branch.

00:03:00.630 --> 00:03:03.830
If we allowed this path to trigger this workflow,

00:03:03.830 --> 00:03:06.810
there would be an infinite loop, so we just need to account for that

00:03:06.810 --> 00:03:09.120
edge case. But don't worry too much about this,

00:03:09.120 --> 00:03:12.050
we're going to dive deeper into this process in the next

00:03:13.840 --> 00:03:16.220
section. Similar to the previous workflow file,

00:03:16.220 --> 00:03:21.780
we check out the Trivy tutorial GitHub repo. But there's a difference

00:03:21.780 --> 00:03:25.070
here. In this case, we use a separate GitHub user.

00:03:25.070 --> 00:03:29.660
In other words, an automation user specifically for this workflow.

00:03:29.660 --> 00:03:33.610
This user is given admin permissions so they can bypass the

00:03:33.610 --> 00:03:37.640
branch protection roles and commit the Docker image signature

00:03:37.640 --> 00:03:39.220
directly into the main branch.

00:03:39.220 --> 00:03:40.580
For more context on this,

00:03:40.580 --> 00:03:45.690
you can check out the setup instructions. Then we go ahead and install Trivy.

00:03:45.690 --> 00:03:50.080
It's important to remember that every time this workflow is instantiated,

00:03:50.090 --> 00:03:52.700
a fresh virtual machine is created.

00:03:52.700 --> 00:03:55.910
In other words, it won't have Trivy installed, so every

00:03:55.910 --> 00:04:00.370
single time we need to run the install script. Next, we log

00:04:00.370 --> 00:04:02.850
into the Docker Hub image registry.

00:04:02.850 --> 00:04:06.140
This allows us to eventually upload our Docker images. Once

00:04:06.140 --> 00:04:09.260
again, for setup instructions on how to do this, check out the

00:04:11.540 --> 00:04:15.620
README. Then, we get to the main logic and we invoke the

00:04:15.620 --> 00:04:18.070
docker‑registry‑orchestrator script.

00:04:18.070 --> 00:04:21.140
We'll explore the script's arguments in the next section.

00:04:21.149 --> 00:04:24.240
The README also includes instructions on how to attach

00:04:24.240 --> 00:04:27.550
secrets to your GitHub repo. Okay, let's check out that script.
