Skip to content

Commit 32b1643

Browse files
committed
Writeup update
1 parent 4eeeb95 commit 32b1643

17 files changed

+1019
-107
lines changed

.github/workflows/publish-labspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Package and deploy Labspace
22

33
env:
4-
DOCKERHUB_REPO: dockersamples/labspace-scout-overview
4+
DOCKERHUB_REPO: dockersamples/labspace-building-secure-images
55

66
on:
77
push:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.labspace/01-introduction.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
# Introduction
22

3-
👋 Welcome to the **Labspace starter** lab! During this lab, you will learn to do the following:
3+
👋 Welcome to this Labspace focused on helping you build secure container images.
44

5-
- Learning Objective 1
6-
- Learning Objective 2
7-
- Learning Objective 3
8-
- Learning Objective 4
5+
By the end, you will have learned the following:
96

7+
- Using Docker Scout to perform an analysis of a container image
8+
- Selecting base images for a more secure foundation
9+
- Resolving application-level CVEs
10+
- Configuring a default non-root user
1011

11-
## 🙋 What is a Labspace again?
1212

13-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi sit amet auctor accumsan. Maecenas suscipit, libero quis ullamcorper pulvinar, dolor nisl vehicula orci, vel egestas arcu nibh eget enim.
14-
15-
Suspendisse potenti. Pellentesque eleifend eget ante eu egestas.
16-
17-
Nunc sit amet dapibus erat. Aliquam diam arcu, fringilla hendrerit metus sed, pellentesque fringilla lacus.
18-
19-
Nulla ornare nulla risus. Curabitur ut ipsum euismod, accumsan lorem eu, pretium lorem. Fusce imperdiet fermentum hendrerit.
2013

14+
> [!IMPORTANT]
15+
> While this Labspace is using a Node-based application, the principles apply universally to all image builds. Therefore, don't put too much focus on the Node-specific elements.
2116
17+
With that, let's dive in and get to it!

.labspace/02-image-analysis.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Performing an image analysis
2+
3+
In this section, you're going to build an image and perform an analysis on the image.
4+
5+
6+
7+
## Building and analyzing the image
8+
9+
This lab already has a `Dockerfile`, so you can easily build the image.
10+
11+
1. Use the `docker build` command to build the image:
12+
13+
```bash
14+
docker build -t node-app:v1 .
15+
```
16+
17+
2. In order to use Docker Scout to analyze the image, you will need to be logged in. Run the `docker login` command and complete the steps to authenticate:
18+
19+
```bash
20+
docker login
21+
```
22+
23+
Follow the instructions to complete login. When you're done, you should see the following message:
24+
25+
```bash no-run-button no-copy-button
26+
Login Succeeded
27+
```
28+
29+
3. Now that you have an image and are authenticated, analyze the image with the `docker scout quickview` command:
30+
31+
```bash
32+
docker scout quickview node-app:v1
33+
```
34+
35+
You will see output indicating Scout is indexing the packages in the image. Eventually, you will see output similar to the following:
36+
37+
```plaintext no-run-button no-copy-button
38+
✓ Image stored for indexing
39+
✓ Indexed 790 packages
40+
✓ Provenance obtained from attestation
41+
42+
i Base image was auto-detected. To get more accurate results, build images with max-mode provenance attestations.
43+
Review docs.docker.com ↗ for more information.
44+
45+
Target │ node-app:v1 │ 2C 25H 23M 113L 4?
46+
digest │ 2fcf7b363939 │
47+
Base image │ node:18 │ 2C 20H 22M 109L 4?
48+
Updated base image │ node:24-slim │ 0C 0H 1M 24L
49+
│ │ -2 -20 -21 -85 -4
50+
```
51+
52+
This output tells you that there are a few issues with this image.
53+
54+
> [!IMPORTANT]
55+
> **The breakdown helps you understand what issues were inherited by the base image versus what you introduced in the application itself**.
56+
57+
You will learn how to fix these over the few sections.
58+
59+
4. If your account is part of an paid organization, you may have additional output that reflects policy alignment.
60+
61+
An example is below:
62+
63+
```plaintext no-copy-button
64+
Policy status FAILED (1/7 policies met, 2 missing data)
65+
66+
Status │ Policy │ Results
67+
─────────┼────────────────────────────────────────────────┼──────────────────────────────
68+
! │ No default non-root user found │
69+
! │ AGPL v3 licenses found │ 4 packages
70+
! │ Fixable critical or high vulnerabilities found │ 2C 24H 0M 0L
71+
✓ │ No high-profile vulnerabilities │ 0C 0H 0M 0L
72+
? │ No outdated base images │ No data
73+
? │ No unapproved base images │ No data
74+
! │ Missing supply chain attestation(s) │ 2 deviations
75+
```
76+
77+
Although you may not have these same policies, these are a great set of base policies to follow:
78+
79+
- Use a non-root user
80+
- No fixable critical or high vulnerabilities
81+
- And fixing attestation issues
82+
83+
Let's start making our image better by fixing vulnerabilities. You'll start with the base image selection.

.labspace/02-main-content.md

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# 📦 Base image selection
2+
3+
Choosing a good base image is critically important when it comes to your overall container security.
4+
5+
Some things to think about include:
6+
7+
- **Who is providing the base image?** Will it be supported and maintained?
8+
- **What OS distribution is being used?** Can you configure the environment with the packages and dependencies your application requires?
9+
- **What packages and tools are provided?** Are the required tools available? Are there extras that aren't needed?
10+
11+
Ideally, you want to keep the idea of "least privilege" - include only what's needed to run your application and nothing more. This reduces both maintenance and potential attack surfaces.
12+
13+
> [!TIP]
14+
> If your organization is looking for minimal images with near-zero CVEs and enterprise-grade SLAs, check out [Docker Hardened Images](https://www.docker.com/products/hardened-images/).
15+
16+
17+
18+
## 🗺️ Choosing a base image
19+
20+
The current `Dockerfile` has the following base image:
21+
22+
```dockerfile
23+
FROM node:18
24+
```
25+
26+
Based on the previous analysis, there were several issues. And, Node 18 is no longer supported. Time to update!
27+
28+
1. Use the `docker scout recommendations` command to get recommendations for a newer base image:
29+
30+
```bash
31+
docker scout recommendations node-app:v1
32+
```
33+
34+
In the output, you will see quite a few options provided to you.
35+
36+
2. As of writing this lab, Node 22 is the current LTS (Long Term Support) release. Scan through the list to find the two Node 22 options:
37+
38+
```plaintext no-copy-button
39+
Tag │ Details │ Pushed │ Vulnerabilities
40+
───────────────────────────────┼─────────────────────────────────────────────────────────┼─────────────┼─────────────────────────────────────
41+
22-slim │ Benefits: │ 1 day ago │ 0C 0H 1M 24L
42+
Major runtime version update │ • Image is smaller by 292 MB │ │ -2 -20 -21 -85 -4
43+
Also known as: │ • Image contains 418 fewer packages │ │
44+
• 22.20.0-slim │ • Major runtime version update │ │
45+
• 22.20-slim │ • Tag was pushed more recently │ │
46+
• lts-slim │ • Image introduces no new vulnerability but removes 128 │ │
47+
• jod-slim │ • Tag is using slim variant │ │
48+
• 22-bookworm-slim │ │ │
49+
• lts-bookworm-slim │ Image details: │ │
50+
• jod-bookworm-slim │ • Size: 79 MB │ │
51+
• 22.20-bookworm-slim │ • Runtime: 22.20.0 │ │
52+
• 22.20.0-bookworm-slim │ │ │
53+
│ │ │
54+
... │ ... │ ... │ ...
55+
│ │ │
56+
22 │ Benefits: │ 1 day ago │ 0C 6H 3M 143L 4?
57+
Major runtime version update │ • Major runtime version update │ │ -2 -14 -19 +34
58+
Also known as: │ • Tag was pushed more recently │ │
59+
• 22.20.0 │ • Image has similar size │ │
60+
• 22.20 │ • Image contains similar number of packages │ │
61+
• lts │ │ │
62+
• jod │ Image details: │ │
63+
• lts-jod │ • Size: 399 MB │ │
64+
• 22-bookworm │ • Runtime: 22.20.0 │ │
65+
• jod-bookworm │ │ │
66+
• lts-bookworm │ │ │
67+
• 22.20-bookworm │ │ │
68+
• 22.20.0-bookworm │
69+
```
70+
71+
You will see that one image is significantly smaller than the other (79MB vs 399MB) and includes far fewer packages (about 418 fewer).
72+
73+
With this difference, the `-slim` variant also has far fewer vulnerabilities.
74+
75+
3. In the `Dockerfile`, update the base image to use the `node:22-slim` image:
76+
77+
```dockerfile
78+
FROM node:22-slim
79+
```
80+
81+
4. Build the image again using the new base image. This time though, you're going to add two additional flags:
82+
83+
```bash
84+
docker build -t node-app:v2 --sbom=true --provenance=mode=max .
85+
```
86+
87+
- **`--sbom=true`** - automatically produce and attach a SBOM (Software Bill of Materials) to the image
88+
- **`--provenance=mode=max`** - automatically product and attach build provenance to the image. This includes details about how the image was built, its base image, and more. This is very valuable in multi-stage builds, as it captures details about all intermediate stages.
89+
90+
5. Before performing an analysis, take a look at the image size of the original image with this newer slim-variant-based image with the following `docker image ls` command:
91+
92+
```bash
93+
docker image ls --filter=reference=node-app
94+
```
95+
96+
You should see output similar to the following, showing the image size reduction:
97+
98+
```plaintext no-copy-button
99+
REPOSITORY TAG IMAGE ID CREATED SIZE
100+
node-app v2 029dbef31e69 2 minutes ago 363MB
101+
node-app v1 2fcf7b363939 About an hour ago 1.57GB
102+
```
103+
104+
Look at that! **1.57GB shrunk down to 363MB. That's a ~77% smaller image!** 🎉
105+
106+
6. Run another analysis on the image to determine if the problems have been fixed:
107+
108+
```bash
109+
docker scout quickview node-app:v2
110+
```
111+
112+
This time, when the analysis is performed, you should see it perform faster for two reasons:
113+
114+
1. **The image is smaller.** Smaller images will be analyzed faster.
115+
2. **`SBOM obtained from attestation.`** Scout leverages the SBOM attached to an image, if it exists. Otherwise, it will index the image itself. Since you built the image with the SBOM flag, that indexing has already been completed!
116+
117+
The output should now show a much better position:
118+
119+
```plaintext no-copy-button
120+
Target │ node-app:v2 │ 0C 5H 2M 28L
121+
digest │ 21616770631b │
122+
Base image │ node:22-slim │ 0C 0H 1M 24L
123+
Updated base image │ node:24-slim │ 0C 0H 1M 24L
124+
```
125+
126+
This indicates that there are still a few _high_ vulnerabilities. But, they are no longer coming from our base image. These must have been introduced by the application you packaged into the container image.

.labspace/03-conclusion.md

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)