DevOps Tips

How to verify your downloads in Docker builds

This article is focussed on how to ensure that downloads via `curl` or `wget` are being verified correctly and provides our solution for checking if you forgot to verify signatures.

Albert Heinle
Written by
Albert Heinle

The official method if a signed signature is available

We recently published a blog article called “Creating a Dockerfile? These are 7 things you should not forget!”. One of the feedback items was to go into detail with more examples on each individual recommendation. This article is focussed on how to ensure that downloads via `curl` or `wget` are being verified correctly.

General principle and some slight variations

Larger projects use GNUPG to sign the files they are offering to the internet. There are different ways to go about it. The most common way is a combination of 4 files, out of which one is optional.

  1. The file(s) to download itself(themselves). Let us call it abc.tar.gz
  2. A file specifying an expected hash code, usually done using SHA512. Let us call this one abc.tar.gz.sha512
  3. A file with a signature using either a key available in a public repository, or in the KEYS file in item 4. This file usually ends in .asc. Let us call it abc.tar.gz.asc
  4. An optional KEYS file, which contains the public keys of the signer.

The signature file of the third item either signs the file specifying the hashcodes of item 2. or the downloaded files themselves. Both approaches are seen across different open source projects.

One needs to start by importing the KEYS file by running


gpg --import KEYS

If it is a file stored in a public repository, you can receive it using


gpg --recv-keys 

The KEYS file or the KEY-ID are usually found on the project’s website.

The verification of the checksums is usually done using


sha512sum -c abc.tar.gz.sha512

In some newer projects, the command


gpg --print-md SHA512 abc.tar.gz | diff - abc.tar.gz.sha512

is used, assuming that the output of the final diff command is empty.

Keep in mind that the examples above assume the use of the SHA512 algorithm, but some projects may use other hash algorithms, which are used in similar ways (MD5 and other modes of strengths of the SHA algorithm family).

The signature verification is achieved by

gpg --verify abc.tar.gz.asc


Concrete Example

Say you want to download the source of Python 3.10.5 from here: https://www.python.org/downloads/release/python-3105/

You see on the page that there is a checksum present, and the GPG sig file.

The keys to import and verify are found on this page: https://www.python.org/downloads/

We recommend keeping a hard copy of the signature file. They are small, and in this way, you know you have the correct signature and checksum file for that moment. I.e., if you are building a Docker image, the source tree should look something like this:

Inside the Dockerfile, if you want to download and verify the image, you can do something like this


FROM alpine:3.13.1

RUN apk add --update gnupg
RUN apk add --update wget

# HASH TAKEN FROM THE WEBSITE
ENV EXPECTED_HASH=d87193c077541e22f892ff1353fac76c

RUN mkdir data
COPY data data

# Receiving the keys from the Python maintainer who signed that package
RUN gpg --recv-keys CFDCA245B1043CF2A5F97865FFE87404168BD847

RUN wget -P data https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz

RUN cd data && \
    test "$EXPECTED_HASH" = "$(md5sum Python-3.10.5.tgz | awk '{print $1}')" && \
    gpg --verify Python-3.10.5.tgz.asc

CMD echo “Whatever else you wish to do with your image”

This should be generally embedded into the template we provide within Creating a Dockerfile? These are 7 things you should not forget!” , to ensure that other items are being addressed.

The Unofficial method

If you download a file from an internal server or from a smaller open source project without signature verification, we recommend that you store and keep the hash-sum of the downloaded package which you trust in your Dockerfile, similar to the line above:


ENV EXPECTED_HASH=d87193c077541e22f892ff1353fac76c

In this way, you can detect, using a failure in the build process, if the file has been tampered with. It is not as hardened as using public key methods and signatures, but better than nothing.

Check to see your Docker images are verifying signatures

If you use CoGuard’s open source CLI tool (https://github.com/coguardio/coguard-cli), all your Docker images are scanned for the occurrence of a file download, and one of our checks fails if you did not verify any signature/checksum. In this way, you can ensure that all the Docker images your organization is producing are not mindlessly downloading files without verifying them, which may potentially cause malicious files to be downloaded.

Explore a test environment

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Check out and explore a test environment to run infra audits on sample repositories of web applications and view select reports on CoGuard's interative dashboard today.