Container registry security is easy to overlook. But you fail to secure container registries at your peril.
This is true whether you use containers from public registries, private registries, or both. Your container ecosystem is only as secure as its least secure container — and that container’s security depends, in part, on the registry from which you pulled the original container image.
Why is this true? We’ll explain in this post. But first, a very quick look at some of the basics of containers, registries, and their associated security issues.
Container and Registry Basics: Registries
A container-based application may deploy hundreds or even thousands of identical containers at any given time — if, for example, you are providing the same basic set of services to a large number of individual users.
Each of these containers is an instance of a container image; the image serves as an unchanging (or immutable) template from which to spawn an endless supply of individual container instances.
This means that you need to have continual access to all of the container images which you need for your application. The best way to do this is to store them in a managed collection, with standardized methods of identifying, committing, and pulling individual images. This kind of storage is called a container registry.
Many of the resources which are widely used in container-based applications (including standard Linux distributions and other key open-source applications) have been packaged into container images. These images, along with a wide variety of other images provided by individual developers, are available from public registries, such as Docker Hub (which currently includes more than two million images).
For developers, the quickest and easiest way to incorporate standard open-source components in an application is to pull the appropriate container images from a public registry. When you do this, you are by necessity trusting the registry to maintain at least a basic level of security regarding the contents of the image.
Public registries are convenient, but if you’re a developer, you need to be able to have full control over the container images that you use in production. While you can use a private repository operating as part of a public registry, the best way to securely manage your production container images is to use a private registry.
Private registries can be either hosted or on-premises. In either case, they should allow you to fully control access to containers, and they should include or provide a way to implement adequate security features.
Container and Registry Security Issues
What are the key areas of concern when it comes to container registry security? Among the major security issues which can (and should) be handled, at least in part, at the registry level are:
Individual container images (particularly those from inadequately managed public repositories) may contain malicious code, either by design, by injection, or as a result of inadequate security during development. Needless to say, using an image that has been compromised in this manner places your entire application at risk.
An image may include open source code with known and unpatched vulnerabilities. Even if there is currently no known case of a given exploit being used for malicious purposes, it is important to be aware of the possibility, and you need to be aware of patches when they become available.
If you pull an image which includes older, unpatched code, your application may still be a potential target for attack, even though a patch is available. A patch for a vulnerability is only effective if you use it.
Who has read access to an image? Who has write access? Who can delete or modify an image? In a public repository, access is largely under the control of the repository administrators. If you have a private repository, you need to actively manage access with as much care as you would manage access to key elements of your production code.
Registry Security: Scanning
The best way to detect malicious code and flag known vulnerabilities is by scanning the containers in a registry on a regular basis. Large public registries often include scanning futures. For private registries, you can use third-party scanning services (such as those provided by Twistlock), with integrated features for blocking the use of untrusted images, generating alerts, and detecting potential problems with compliance.
Registry Security: Auditing
In software development, anything that doesn’t change is likely to age very quickly. This applies to container images as much as it applies to any other development resource, and since images are designed to be immutable, an outdated container image may continue to produce equally outdated container instances on an indefinite basis.
When this happens, older vulnerabilities for which there are already patches may continue to be present in your application until you update the container images which contain them.
For adequate security, a registry should include a way of auditing container images for outdated code and known vulnerabilities and identifying outdated containers based on the audit results.
Registry Security: Access Control
The third key component of container registry security that you need to look for is access control. While public registries have their own access policies, a private repository hosted by a public registry (such as Docker Hub) will provide you with at least basic control over access.
A private registry should give you fine-grained, role-based access control, allowing you to precisely define the conditions under which access is allowed to each role. This kind of granularity is a necessity for production, but it is also important across the development cycle.
Getting Serious About Container Registry Security
The bottom line, then, is that if you are serious about the security of your application, you need to take container security seriously, and that means in turn that you need to be equally serious about container repository security.
The good news is that container registry security is a practical and attainable goal; you can have a truly secure container repository, and you should not settle for anything less.