Using containerisation
Guidance on how to build and use containerised applications securely.
Page 3 of 4
Running Containers

The steps to running containers securely and protecting them from attack.
Running containers
This guidance is designed to help you to ensure that you protect the containers you run, and the data you expose to your containers.
Containers are very different from virtual machines (VMs). The boundary between the container and the rest of the host is considerably less simple and less robust than the boundary between a VM and its host. This allows the container runtime to monitor and modify a running container, introducing new and innovative ways to run minimised containers.
However, it also increases the chance that a container can attack another container on the same host. There is also a greater chance that a bug or misconfiguration in the container runtime will allow a containerised application to ‘break out’ and gain unauthorised access to the host. All this means that it is important to choose your container runtime carefully and to ensure the container execution environment is configured securely.
1: Secure the container image supply chain
Ensure you have good reason to trust every container image you use.
- Prevent the execution of untrusted container images
- Take care when selecting image versions using mutable tags
- Only use container images from reputable sources
- Verify the origin, authenticity, and integrity of the container images you use
- Protect and authenticate access to the container registries you use
- Store all container images you use in a secured container registry
Just as it’s important to prevent untrusted applications from running on your devices, you should prevent untrusted containers from running. This is particularly important in execution environments where sensitive data and services are used. You should use technical controls to ensure that only trusted containers can run, rather than relying on procedural controls alone.
You should be confident that all the containers you use have been built and configured securely. See Building container images for more details.
Container ecosystems typically allow you to reference a container image by a name (often called a ‘repository’) and a version. The version can be selected with either a cryptographic checksum or a label. A cryptographic checksum will uniquely identify a single version and cannot be changed, whereas a label can often be modified to point to different unique versions over time. Some tools maintain special tags that change whenever an image is updated (often called ‘latest’). When you reference container images, make sure that you get the version you expect. For important workloads, you should prefer specifying the cryptographic checksum so that there is no ambiguity.
When container images are fetched over a network, encryption and integrity checking should be used to ensure that the images are not modified or disclosed in transit. You should also authenticate the container images you run. For example, this could be achieved by checking that the image has a valid cryptographic signature from a trusted source.
You should consider how you protect access to the container registries that host your container images. This includes authenticating the registry so that you cannot accidentally fetch images from an unauthorised registry and preventing attackers from accessing your registry. If you use a container registry in the cloud, see Authenticate service identities and Apply access controls for more information on managing authentication and access control in the cloud.
You should be confident that the container registry you use to store and fetch container images can be trusted. Verifying cryptographic signatures on the container images at runtime prevents a container registry from inserting untrusted data into a container image undetected, but you still rely on the registry not to disclose or delete your container images without your consent.
2: Use appropriate separation
Ensure that running containers are not exposed to unnecessary threats. You should be confident that there is appropriate separation between applications for:
- compute
- networking
- storage
- logical access and identity
You should be confident that one application being compromised does not jeopardise the security of other applications.
We cover these separation mechanisms in more detail in Technically enforced separation in the cloud.
Containers are often run on a machine shared with other processes, such as other containers, to increase resource utilisation. Appropriate separation should be used to protect the application from malicious or compromised processes outside the application, and to reduce the risk of lateral movement if the application is compromised. Note that an application may consist of multiple containers working together.
When multiple applications share a host, suitable compute separation becomes particularly important. You should ensure that there is robust separation between your own workloads and other customers'. You may also want a strong security boundary between each of your applications. As described in Technically enforced separation in the cloud, the kernel-enforced separation typically used by a container runtime is not usually considered enough compute separation to form a strong security boundary.
You should be confident that identity and access controls are appropriately separated between applications. For example, it should not be possible for a container to impersonate other applications running on the same host, or to impersonate the host itself. Similarly, making data and other resources available to one container on a host should not automatically make that data accessible to other containers on the same host.
Network and storage separation are also important to apply correctly but are less likely to differ from non-container environments than compute and logical separation.
3: Secure the execution environment
The container execution environment should make compromise difficult.
- Run containers as a low-privilege user
- Use standard security features for the relevant operating system
- Ensure the container has no access to the host operating system
- Avoid the use of ‘privileged containers’
- Prefer read-only filesystems
- Use container-aware protective monitoring
- Apply network access controls
- Limit interactive access to running containers in production environments
Traditional applications apply a variety of security hardening techniques, such as executing as a low-privilege user, reducing the attack surface of the software in use, and limiting the use of privileged and dangerous OS capabilities. As well as container-specific hardening, you should apply the same hardening techniques to containerised applications that you would to traditional applications.
While some hardening can be configured in the container image at build time, some security features must be applied at runtime. You should identify the security features available to you and ensure that they do not interfere with the correct behaviour of the application.
Privileged containers are a feature in container runtimes that is designed to bypass several of the security controls that provide containerised applications with separation from the host. You should avoid using privileged containers except in the few cases where absolutely necessary. This may be required in some cases, such as when a container is responsible for configuring host networking. You should prefer to configure additional permissions and host accesses granularly, using the appropriate mechanisms provided by the container runtime. Note that here we refer to the ‘privileged container’ feature, rather than the broader concept of containers that fulfil a privileged role in the wider system.
When you perform protective monitoring on containerised workloads, you should ensure that your monitoring tools are aware of how containers work. This allows them to consider additional context like the container’s entry point and the sorts of behaviours that are expected in a containerised workload. For example, containers rarely use command line shells unless the shell is used as the entry point. A shell being invoked during the runtime of a container (particularly after the container has been running for a while) is a sign that the container may have been compromised. This kind of monitoring would not be effective in many other execution environments, which is why it’s important to consider such container-specific factors in your protective monitoring.
Since containers provide a repeatable execution environment, effective process hardening is easier to apply to containers than traditional applications. This is because the hardening configuration can be adjusted, and the container then run to check for compatibility issues. This reduces the time between changes and increases confidence in the correctness of the configuration. You should use this property to help secure your containers.
Containers are well-suited to immutable applications that are replaced with new versions, rather than being updated in place. You should debug and update containers using automated tooling, rather than allowing your personnel interactive access to important containers. See the Cloud platform guidance for more details on this approach.
4: Secure the container runtime
The container runtime should defend the container execution environment. The container runtime should:
- preserve the separation between applications
- make it difficult to escape the container execution environment
- be protected from external attack
A container runtime is used to prepare the execution environment for a container and then to start the container. Container runtimes are also often used to provide debugging features, such as the ability to start a new process in the container, to collect logs, or to inspect the container’s filesystem.
The container runtime must not undermine the separation between applications. For example, the container runtime should not provide the container with access to resources outside its execution environment, such as the host filesystem or network context.
The container runtime often runs with elevated privileges, as these are usually necessary to call the APIs used to prepare and interact with the containers it manages. The container runtime should not provide the container with a way to escalate its privileges or escape the container boundary. For example, the container runtime should not allow the container to start new processes outside the container, or to act as a privileged user.
The container runtime is a security-enforcing function, as it controls what resources and credentials are made available to the container at runtime, so it should not be exposed to attack. A secure container runtime will be well protected from a malicious container and from outside attack. Access to the container runtime should be managed carefully.
Ideally, the container runtime should be used in a way that minimises the impact of its compromise. For example, you should minimise the privileges available to the container runtime. If you orchestrate many containers over a cluster of hosts, you should ensure that one compromised container runtime cannot affect either other hosts and their data or the cluster as a whole.
5: Secure the host operating system
The host operating system should underpin the security of the container execution environment.
- Use a host purpose-built for running containers
- Minimise the contents of the host
- Apply security updates promptly
- Harden the host configuration
Containers include all their software dependencies, except the OS kernel. This presents a great opportunity to use a host OS with very little software, significantly reducing its attack surface. The host should only include the software necessary to run containers and to administrate the host, such as the container runtime and remote management tooling.
As with the containers you run, you should apply security updates promptly to the host OS. This can be either by applying the updates in place, or by replacing the host instance with an updated version. The container runtime is a particularly important component to update promptly, as this will help to mitigate vulnerabilities that affect would otherwise affect your containers. Container ‘break out’ techniques often exploit known vulnerabilities in container runtimes, which makes it even more important to apply security updates promptly.
You should harden the configuration of the host, including configurations specific to container hosts. For example, limit the permissions of the container runtime and the use of highly privileged users.