Docker Content Trust: How Container Signing Protects Users from Downloading Compromised Code

As Docker adoption explodes, malicious actors are increasingly focusing on container attacks.  IDN Contributing Editor David Bisson reviews some of the best ways to protect your code – and your organization.

Tags: attacks, code signing, container trust, Docker, DCT, hacker, security, trust,

Digital attackers have a habit of using malicious container images to target organizations.

Back in March 2019, for instance, a major security provider witnessed malicious actors using a community-contributed container image published on Docker Hub to drop two payloads. A cryptocurrency miner that connected to a mining pool and a shell script that retrieved networking tools for the purpose of moving laterally to other potential targets.


It was more than a year later when the firm detected something similar when threat actors uploaded two malicious images containing cryptominers to Docker Hub.


In its analysis of the attack, the security firm found that the attackers had labeled their images “alpine” and “alpine2” after the popular base Docker image Alpine Linux in an attempt to trick developers into using them.


These incidents highlight the widespread issue of trust when it comes to container security.

As reported by Container Journal, a 2019 study found that 40% of customers’ container images had originated from public sources. That’s a problem given the study’s finding that just one percent of Docker Hub images had received certification as “trustworthy” or “legitimate.” Without those guarantees, organizations are more at risk of using a publicly sourced image that increases their risk by exposing them to malware and other digital threats.

Code Signing as a Possible Answer

In light of the increase in such incidents, developers need to cultivate trust by making sure their customers are pulling legitimate containers that don’t suffer from malicious code. One of the ways to do that is to use code signing.


As noted by Keyfactor, code signing involves the use of a digital certificate to prevent unauthorized actors from modifying an application such as a container. Code signing thereby provides high assurance to organizations that the application code is authentic and that a vendor has vetted the code for malicious content. It also testifies to the legitimacy of the container once the developer has packaged the code into one and deployed it to the cloud.

Docker Content Trust: An Example of Container Code Signing at Work

One of the most well-known implementations of using code signing for containers is Docker Content Trust (DCT).


According to Docker’s documentation, DCT enables the publishers of images to sign their container images. It works at the level of the “tag” portion of a container image, or the feature which provides certain information about container images such as OS version and what software update it might have received. Each Docker repository contains a set of keys that publishers can use to sign the tags that they want for a certain image.


That’s not all DCT can do. Consumers can also use DCT to ensure that the images they pull are signed. They can do this by enabling DCT, an action which allows them to pull, run or build with only trust images. Enabling DCT doesn’t allow them to interact with unsigned container images.

Safeguarding the Keys Associated with DCT

When an image publisher first invokes DCT, Docker creates a set of signing keys. This key set consists of the following elements: an offline key that serves as a DCT root, tagging/repository keys for signing tags and self-managed keys like timestamp keys. It’s imperative that developers take the proper steps to protect these keys. If an attacker were to compromise them, they could use them to legitimize malicious code within a container and thereby target their customers.


Per another section of Docker’s documentation, developers can secure the keys using the following security best practices:

  • Choose a passphrase: Developers can protect both their root keys and repository keys by randomly generating a passphrase. This security measure is useful in that it encrypts each of the keys at rest. They should then store them in a password manager.
  • Back up their keys: It’s important that developers don’t lose track of their keys. They can recover a lost repository key, but the same cannot be said about a root key. As such, they might consider backing up their keys to a secure location such as by creating two encrypted USB keys.
  • Use hardware storage and signing: Last but not least, developers can consider using a Yubikey 4 to store and sign with root keys.

Trust: A Single Element of Container Security

Stepping back from the technical details, the big picture reveals that “container trust” is one of the security challenges that organizations must face. But it’s not the only one. StackRox notes that organizations face no less than eight security challenges with respect to their containers including the obstacle of complexity:

Containerized environments have many more components than traditional VMs, including the Kubernetes orchestrator that poses its own set of security challenges. Can you tell which deployments or clusters are affected by a high-severity vulnerability? Are any exposed to the Internet? What’s the blast radius if a given vulnerability is exploited? Is the container running in production or a dev/test environment?

Acknowledging that, organizations need to take the proper steps to safeguard their Docker containers beyond just container trust. They can do so by learning more here at the Dockert Docs page.

David Bisson, Bora

David Bisson is an information security writer and security junkie. He's a contributing editor to Integration Developer News, IBM's Security Intelligence and  Tripwire's The State of Security Blog. David is also  a contributing writer to Bora, specializing  in the digital security space.