{"id":15020016,"url":"https://github.com/docker/dc23-secure-workshop","last_synced_at":"2025-10-19T16:32:38.014Z","repository":{"id":198029235,"uuid":"696868636","full_name":"docker/dc23-secure-workshop","owner":"docker","description":"DockerCon 2023 Secure Development with Docker hands-on exercises code","archived":false,"fork":false,"pushed_at":"2024-03-27T17:20:54.000Z","size":16758,"stargazers_count":11,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-30T01:12:46.613Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-26T15:27:43.000Z","updated_at":"2024-06-25T14:20:36.000Z","dependencies_parsed_at":"2024-09-29T06:18:37.583Z","dependency_job_id":null,"html_url":"https://github.com/docker/dc23-secure-workshop","commit_stats":{"total_commits":7,"total_committers":2,"mean_commits":3.5,"dds":0.1428571428571429,"last_synced_commit":"a416e359d89c634a466843b738802990776ec393"},"previous_names":["docker/dc23-secure-workshop"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docker%2Fdc23-secure-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docker%2Fdc23-secure-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docker%2Fdc23-secure-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docker%2Fdc23-secure-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docker","download_url":"https://codeload.github.com/docker/dc23-secure-workshop/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237172178,"owners_count":19266627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T19:54:28.230Z","updated_at":"2025-10-19T16:32:31.575Z","avatar_url":"https://github.com/docker.png","language":"Dockerfile","readme":"# Secure Development With Docker \u0026mdash; DockerCon 2023 workshop\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003eSetup the workshop platform\u003c/h2\u003e\u003c/summary\u003e\n\n### Requirements\n\n- git\n- Docker Desktop 4.24.0 or greater\n- Docker Hub account `$ORG`\n\nDocker Desktop must be configured to use containerd.  In Docker Desktop, go to\nthe Settings (⚙️ icon) \u0026gt; Features in development and make sure the box next\nto \"Use containerd for pulling and storing images\". If you changed the setting,\nclick the \"Apply \u0026 Restart\" button.\n\n![Docker Desktop settings](./ss/desktop-containerd.png)\n\n### Prerequisites\n\n\u003e *Conventions:*\n\u003e `$ORG` is the name of the Docker Hub account you will use.\n\u003e It can be a personal or a team one. Better if you have full ownership on it.\n\n1. Clone the repository on your local machine\n2. (optional) export `ORG` environment variable so you can more easily copy/paste commands\n\n   ```console\n   export ORG=\u003cyour organization namespace\u003e\n   ```\n3. Configure organization for Docker Scout\n\n   ```console\n   docker scout config organization $ORG\n   ```\n4. Copy `env.dist` file to `.env`\n5. Edit `.env` and set `NAMESPACE` to `$ORG`\n6. Enroll your organization to Docker Scout\n\n   ```console\n   docker scout enroll $ORG\n   ```\n7. Checkout Hands-On #1\n\n   ```console\n   git checkout hands-on-1\n   ```\n8. Build demo images\n\n   ```console\n   docker compose --profile images build\n   ```\n\n   \u003e This command will build two images we will explore.\n   \u003e To know more about how they are built look at\n   \u003e [`./docker-compose.yml`](./docker-compose.yml) and\n   \u003e [`./backend/Dockerfile`](./backend/Dockerfile) that\n   \u003e contains the build definitions.\n\n   \u003e In case of network issues, you can also build the following\n   \u003e image that is prebuilt and don't need extra dependencies.\n\n   ```console\n   docker compose --profile low_network build\n   ```\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003eHands-on #1: Remediating vulnerabilities\u003c/h2\u003e\u003c/summary\u003e\n\n### Reset git repository\n\n```console\ngit reset --hard hands-on-1\n```\n\n### Base Image Fix (Docker Desktop)\n\n1. Open Docker Desktop and select the image `$ORG/scout-demo-service:v1`\n\n   ![](./ss/layer_view_scout-demo-service_v1.png)\n2. Take the time to explore the different information displayed on this page\n\n   - Image hierarchy, layers and the Images tab\n   - Vulnerabilities\n   - Packages\n\n3. Select your base image and explore vulnerabilities specific to the base image.\n   Then select \"Recommendations for base image…\" in the \"Recommended fixes\"\n   dropdown in the upper right portion of the window.\n\n   ![](./ss/select-base-image.png)\n\n4. Select _Change base image_ and set the current image to 3.14\n\n   ![](./ss/change-base-image.png)\n\n5. Open [`frontend/Dockerfile`](./frontend/Dockerfile) in your favorite file editor\n   and apply the \"Tag is preferred tag\" recommendation, i.e., change the `FROM` line to\n\n   ```dockerfile\n   FROM alpine:3.18\n   ```\n\n6. (optional) Update the tag to `v2` in [`docker-compose.yml`](./docker-compose.yml)\n7. Rebuild the image\n\n   ```console\n   docker compose --profile scout-demo-service build\n   ```\n8. Open the image inside Desktop and see the impact of your change\n\n   ![](./ss/layer_view_scout-demo-service_v2.png)\n\n### Base Image Fix (Docker Scout CLI)\n\n1. Run `docker scout cves` command against the image you just built:\n\n   ```console\n   docker scout cves $ORG/scout-demo-service:v1\n   ```\n\n   ![](./ss/scout-demo-service-v1-cves.png)\n2. (optional) Explore the filters options from `docker scout cves` command\n3. (optional) See vulnerable packages only\n\n   ```console\n   docker scout cves --format only-packages --only-vuln-packages $ORG/scout-demo-service:v1\n   ```\n\n   ![](./ss/scout-demo-service-v1-only-vuln-packages.png)\n\n4. Explore base image recommendations using `docker scout recommendations`\n\n   -\u003e specify the tag upfront, like we selected it in Docker Desktop\n\n   ```console\n   docker scout recommendations --tag 3.14 $ORG/scout-demo-service:v1\n   ```\n\n   ![](./ss/scout-demo-service-v1-recommendations.png)\n\n5. Apply the \"Tag is preferred tag\" recommendation to the [`frontend/Dockerfile`](./frontend/Dockerfile)\n6. (optional) Update the tag to `v2` in [`docker-compose.yml`](./docker-compose.yml)\n7. Rebuild the image\n\n   ```console\n   docker compose --profile scout-demo-service build\n   ```\n8. Run `docker scout cves` command against the image you just built and see the changes:\n\n   ```console\n   docker scout cves $ORG/scout-demo-service:v2\n   ```\n\n   ![](./ss/scout-demo-service-v2-cves.png)\n9. Compare the two images to see the differences:\n\n   ```console\n   docker scout compare $ORG/scout-demo-service:v2 --to $ORG/scout-demo-service:v1\n   ```\n\n   ![](./ss/scout-demo-service-compare.png)\n\n### Application Dependency Fix\n\n1. Explore the still existing vulnerabilities: (Desktop or CLI)\n   - find vulnerable package\n   - find fix version\n2. Update [`package.json`](./frontend/package.json) to upgrade the dependency\n3. (optional) Update the tag to `v3` in [`docker-compose.yml`](./docker-compose.yml)\n4. Rebuild the image\n5. Explore the built image to see what changed\n   - using Desktop\n   - using CLI\n\n### Extra Command\n\n1. Get a quick overview of your image, including vulnerabilities and recommendations\n\n   ```console\n   docker scout quickview $ORG/scout-demo-service:v1\n   ```\n\n### Extra Image\n\nRepeat the above steps for the `$ORG/scout-demo-service-back:v1` image (or any other image you have).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003eHand-on #2: Using Docker Scout to connect your data model\u003c/h2\u003e\u003c/summary\u003e\n\n### Reset git repository\n\n```console\ngit reset --hard hands-on-2\n```\n\n### Registry - https://scout.docker.com Integration\n\n#### Create repositories\n\nGo to https://hub.docker.com and create repositories for the images you will push\n\n- `$ORG/scout-demo-service`\n- `$ORG/scout-demo-service-back`\n\n#### Enable repositories for Docker Scout\n\n_Option 1: Use Docker Scout Dashboard_\n\n1. Go to https://scout.docker.com\n2. Select your organization in the dropdown next to your user\n3. Open the settings menu (⚙️ icon) and select _Repository settings_\n4. Select the repository to enable and enable it\n\n_Option 2: Docker Hub Integration using the CLI_\n\n```console\ndocker scout repo enable $ORG/scout-demo-service\n```\n\n```console\ndocker scout repo enable $ORG/scout-demo-service-back\n```\n\n### Push images\n\n1. Push an image to Hub\n\n   ```console\n   docker push $ORG/scout-demo-service:v1\n   ```\n\n2. Browse https://scout.docker.com and see your images (this might take up to a few minutes)\n\n   ![](./ss/pushes_images.png)\n\n### Analyze images\n\nReproduce the exploratory steps from _Hands-on #1_ on https://scout.docker.com.\nFind vulnerabilities, package information and compare your images.\n\nYou can build and push the different versions of the images you previously built (with vulnerabilities or with fixes).\nOr simply push the fixes you built in the first hands-on exercise.\n\n```console\ndocker push $ORG/scout-demo-service:v3\n```\n\n### Record images to an environment\n\n1. Record the image to an environment (adapt to your registry)\n\n   ```console\n   docker scout environment staging registry://$ORG/scout-demo-service:v1\n   ```\n\n   This will explicitly record the image that has been pushed to a registry, to the environment `staging`.\n\n   ![](./ss/staging.png)\n\n2. Investigate environment information from the CLI\n\n   ```console\n   docker scout environment\n   ```\n\n   ```console\n   docker scout environment staging\n   ```\n\n3. Compare your fixed local image to the one recorded as part of the `staging` environment\n\n   ```console\n   docker scout compare local://$ORG/scout-demo-service:v3 --to-env staging\n   ```\n\n   ![](./ss/scout-demo-service-compare-staging.png)\n4. Browse https://scout.docker.com\n\n   - find images recorded to an environment\n   - find vulnerabilities and packages in an environment\n   - compare images between versions and/or environments\n\n   ![](./ss/scout-demo-service-ui-compare.png)\n\n5. Record `v3` to the staging environment\n\n   ```console\n   docker scout environment staging registry://$ORG/scout-demo-service:v3\n   ```\n\n6. Verify you have no vulnerabilities in `staging` at https://scout.docker.com \u0026gt;\n   Vulnerabilities and select the staging environment\n\n7. Browse available integrations on https://scout.docker.com \u0026gt;\n   Settings (⚙️ icon) \u0026gt; Integrations\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003eHand-on #3: Explore \u0026 add provenance \u0026 SBOMs using Buildkit \u0026 Docker Scout\u003c/h2\u003e\u003c/summary\u003e\n\n### Reset git repository\n\n```console\ngit reset --hard hands-on-3\n```\n\n### Provenance Attestation\n\nRemember the `--tag` flag when we explore the base image recommendations or the dropdown to pick\nthe right one in the UI?\n\n```console\ndocker scout recommendations --tag 3.14 $ORG/scout-demo-service:v1\n```\n\nThis tag was needed because the base image exists under different tag (`latest`, `3`, `3.14` at least)\nand the information contained in the image are not sufficient to pick the right one.\n\nSo let's fix that.\n\n1. We have added a new command to the _end_ of the [`frontend/Dockerfile`](frontend/Dockerfile)\n   so it gets rebuilt, but quickly\n\n   ```dockerfile\n   ENV DUMMY=1\n   ```\n\n   (this line was introduced when you reset to the `hands-on-3` tag above)\n2. Build a new image with the _provenance_ attestation\n\n   ```console\n   ( cd frontend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service:provenance \\\n       --provenance=mode=max --push . )\n   ```\n3. Get recommendations about the image that has been pushed\n\n   ```console\n   docker scout recommendations registry://$ORG/scout-demo-service:provenance\n   ```\n\n   This time you didn't provided the `--tag` and it picked the right one!\n\n   \u003e Base image is `alpine:3.14`\n\n4. How did it do that? Let's look at the provenance.\n\n   ```console\n   docker buildx imagetools inspect $ORG/scout-demo-service:provenance \\\n     --format '{{ json .Provenance.SLSA }}'\n   ```\n\n   (note we are extracting an element called `SLSA`!)\n   That is a lot of information. Let's focus on information about the base image.\n   One place to see that is in the first element of the `llbDefinition` array:\n\n   ```console\n   docker buildx imagetools inspect $ORG/scout-demo-service:provenance \\\n     --format '{{ json .Provenance.SLSA }}' | jq '.buildConfig.llbDefinition[0]'\n   ```\n\n   (requires the [`jq`](https://jqlang.github.io/jq/) command)\n   See how the identifier has the exact SHA used as the base image?\n\n\u003e **Note on `push` and `registry://`**\n\u003e\n\u003e We need to access the provenance attestation from the image. It's written at the level\n\u003e of the _Image Index_ (same as for multi-arch images). The local Docker daemon doesn't allow\n\u003e currently to easily access those information.\n\u003e\n\u003e But they are available from registries. So when pushed, all these extra information will\n\u003e be available and CLI or https://scout.docker.com tools will be able to use them.\n\n### SBOM\n\nWhen an image is used on the CLI or pushed to https://scout.docker.com one of the first\nsteps is to index it. It means to go through the image and find all the packages for instance.\n\nIt also means this action might be performed multiple times, like if we want to see\nthe vulnerabilities of the image from different computers.\n\nBut it's possible to generate SBOM at the build time and push it along with the image.\nThat way, whatever the size of the initial image, we will only require the SBOM (enhanced\nwith provenance if available) and it will make all the CLI actions faster and be sure\nthe information displayed on https://scout.docker.com are the right ones.\n\n1. Change the value of the environment variable at the end of [`frontend/Dockerfile`](frontend/Dockerfile)\n   so the image gets rebuilt and pushed, quickly\n\n   ```dockerfile\n   ENV DUMMY=2\n   ```\n\n2. Build a new image with an _SBOM_ attestation (and keep the provenance!)\n\n   ```console\n   ( cd frontend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service:attests \\\n       --sbom=generator=docker/scout-sbom-indexer \\\n       --provenance=mode=max --push . )\n   ```\n3. Run any `docker scout` CLI command, e.g.,\n\n   ```\n   docker scout quickview $ORG/scout-demo-service:attests\n   ```\n\n   and you should see:\n\n   \u003e ✓ Provenance obtained from attestation\n   \u003e ✓ SBOM obtained from attestation, 79 packages indexed\n\n   This means we only get the SBOM from the attestation, and we are not indexing locally\n   the image anymore. It's faster and more accurate.\n\n### Explore SBOM\n\n1. Extract the SBOM in `SPDX` format:\n\n   ```console\n   docker scout sbom --format spdx registry://$ORG/scout-demo-service:attests\n   ```\n\n   That is a lot of process. Let's look at some more useful format options.\n2. Display packages of the image:\n\n   ```console\n   docker scout sbom --format list registry://$ORG/scout-demo-service:attests\n   ```\n\n   ![](./ss/package-list.png)\n3. Display vulnerable packages:\n\n   ```console\n   docker scout cves --format only-packages --only-vuln-packages registry://$ORG/scout-demo-service:attests\n   ```\n\n   ![](./ss/vuln-packages.png)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003eHands-on #4: Getting back into compliance with Docker Scout\u003c/h2\u003e\u003c/summary\u003e\n\n### Reset git repository\n\n```console\ngit reset --hard hands-on-4\n```\n\n### Explore policy\n\nUp to now, we've focused on single images. Now let's see how policy highlights\nconcerns across all our images.\n\n1. Build and push both images in the app.\n\n   ```console\n   ( cd frontend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service:4 \\\n       --sbom=generator=docker/scout-sbom-indexer \\\n       --provenance=mode=max --push . )\n   ```\n\n   ```console\n   ( cd backend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service-back:4 \\\n       --sbom=generator=docker/scout-sbom-indexer \\\n       --provenance=mode=max --push . )\n   ```\n\n2. View policy status for a single image using the CLI\n\n   ```console\n   docker scout policy $ORG/scout-demo-service-back:4\n   ```\n\n   ![scout policy backend](./ss/policy-backend.png)\n\n3. Go to https://scout.docker.com and click on \"Policies EA\" at the top\n\n   ![scout policy web site](./ss/policy.png)\n\n4. Explore the \"Critical and high vulnerabilities with fixes\" policy and view the details\n   on the `$ORG/scout-demo-service`\n\n### Improve policy compliance\n\n1. From looking through the layers before, we know how to fix that. Let's update the base image\n   in [`frontend/Dockerfile`](frontend/Dockerfile):\n\n   ```dockerfile\n   FROM alpine:3.18\n   ```\n\n2. Now rebuild, incrementing the tag\n\n   ```console\n   ( cd frontend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service:4.1 \\\n       --sbom=generator=docker/scout-sbom-indexer \\\n       --provenance=mode=max --load . )\n   ```\n\n3. Note we did not push the image in the previous step. Entirely locally, we can see if we have\n   improve policy compliance using the `compare` command we used previously when focusing on\n   fixing vulnerabilities\n\n   ```console\n   docker scout compare $ORG/scout-demo-service:4.1 --to $ORG/scout-demo-service:4\n   ```\n\n   ![scout policy compare 0](./ss/policy-compare-0.png)\n   ![scout policy compare 1](./ss/policy-compare-1.png)\n\n   Scrolling past the Overview to the Policies section of the output, you can see you improved\n   two policies without pushing images or running CI.\n\n4. We see from the above command that while we are now compliant with the \"All critical\n   vulnerabilities\", we are still not in compliance with the \"Critical and high\n   vulnerabilities with fixes\" policy, there are still two high vulnerabilities. From our first\n   hands-on earlier today, we know how to fix that too. Update the express dependency in\n   [`frontend/package.json`](frontend/package.json) to version 4.17.3 and rebuild the image.\n\n   ```console\n   ( cd frontend \u0026\u0026 \\\n     docker build -t $ORG/scout-demo-service:4.2 \\\n       --sbom=generator=docker/scout-sbom-indexer \\\n       --provenance=mode=max --load . )\n   ```\n\n5. Run the `compare` command again to see if we are fully compliant\n\n   ```console\n   docker scout compare $ORG/scout-demo-service:4.2 --to $ORG/scout-demo-service:4\n   ```\n\n6. That did the trick, so push the image\n\n   ```console\n   docker push $ORG/scout-demo-service:4.2\n   ```\n\n7. Go to https://scout.docker.com\n\n   ![scout policy web fix](./ss/policy-fix.png)\n\n### Extra Image\n\nRepeat the above steps for the `$ORG/scout-demo-service-back` image (or any other image you have).\n\n\u003c/details\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocker%2Fdc23-secure-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocker%2Fdc23-secure-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocker%2Fdc23-secure-workshop/lists"}