What is container security?
Containers are units of software that allows you to deploy applications as stand-alone, self-sufficient packages isolated from other activity on a machine. Containers are similar to virtual machines (VMs), but do not run an entire operating system. Instead, they share access to the operating system (OS) kernel, which makes them faster and more lightweight than VMs.
Container security requires a different approach compared to security in traditional environments. Containers need a continuous security strategy integrated into the entire software development lifecycle (SDLC). This means securing the build pipeline, container images, container host machines, container runtimes (such as Docker or containerd), container platforms and orchestrators (such as Kubernetes), and application layers.
Due to the complexity and dynamic nature of a containerized environment, container security must be fully automated. An important step to automating security and embedding it into all stages of the SDLC is to implement security controls as part of the continuous delivery lifecycle used to build and release containerized applications.
In this article:
The Need for Container Security
Container adoption has grown exponentially in the past decade. Containers are widely used as lightweight building blocks in software projects, and are highly convenient because they contain everything needed to run an application—code, runtime, tools, libraries, and configurations. A container runs consistently every time regardless of the environment on the host machine, is highly portable, and uses fewer resources compared to VMs.
Container engines like Docker and container orchestrators like Kubernetes include some basic security controls, but they are not secure by default, and hardening container runtimes and orchestrators can be complex.
Containerized application development also includes a large number of third-party software components that can be vulnerable, making it critical to scan container images at all stages of development. If there are vulnerabilities in the container images, they are inherited by all containers deployed from the image.
Another attack surface is running containers, which are vulnerable to attacks that bypass the isolation between the container and the host. This allows attackers to “break out” of a container, compromise the host, and gain unauthorized access to other containers.
As containers and orchestrators enter the mainstream and are used to run production applications and mission-critical systems, container security is becoming an essential component of any organization’s cybersecurity strategy.
Container Security Challenges and Risks
Here are some of the critical challenges facing organizations that aim to secure container infrastructure.
Everything Is Distributed
The complexity of containerized environments and microservices makes security more difficult to manage. In a traditional monolithic application infrastructure, the entire application runs on the same server. However, in microservices architectures, communication between different parts of an application occurs over a wider network. APIs and backend services are deployed in containers on different hosts, and each application component frequently accesses other components to do its job.
To ensure the system is secure, each component should be secured on its own, and components should authenticate all requests, including internal ones, using a zero trust approach. In addition, management components such as the Kubernetes control plane, service meshes, and container networking software should support observability and enable modern security practices such as microsegmentation.
Network Security Concerns
In a traditional architecture, network security relied on IP addresses. However, in a containerized world, workloads are ephemeral and have dynamically assigned IP addresses, making them more difficult to secure.
Network segmentation and dynamic access controls are critical to prevent lateral movement in case a container is compromised, while ensuring containers can communicate with legitimate components.
Implementing segmentation in a cloud native environment requires an identity-based model that understands workloads at the microservices level, and is able to isolate specific applications or microservices. This means security policies are independent of IP addresses, and continue to function as the application scales up and down, fails and recovers, and even as it is migrated between on-premise and cloud environments.
Related content: Read more in our guide to container isolation
Security incidents will inevitably happen. When an attacker penetrates a containerized environment, containers can expand the blast radius of a breach. Many production environments have multiple containers, applications, and services running on the host. If one container is compromised, all containers and the underlying host can be compromised too. Any container or container image that is not configured securely can have ripple effects through the entire environment.
In the early days of containers, it was common for containerized environments to fail compliance audits. This was the result of a lack of security planning in early stages of container development. Organizations applied security considerations only at the end of the development lifecycle, when containers were deployed to production.
Today it is understood that organizations must “shift left” container security to promote security and properly handle compliance concerns. If an organization is subject to compliance standards—such as PCI DSS, GDPR, HIPAA, and SOC 2—it should identify compliance requirements and build them into containerized environments from day one. It is also important to automate compliance checks and audit reporting as much as possible to reduce overhead.
Organizations should also implement container- and Kubernetes-specific standards that apply to all organizations, such as Docker and Kubernetes CIS benchmarks and NIST SP 800-190.
Related content: Read our guide to container compliance
Key Components of a Container Security Architecture
Container security spans five core areas: container development, container registries, container runtime environments, container orchestration, and the underlying architecture and network.
Related content: Read our guide to containerized architecture
Container Development (IDE and Source Code)
All software development projects must avoid poorly written or malicious code. The same applies to container development, where bad code presents a security vulnerability if it reaches the production environment, exposing the application to attack.
Container Build Environment (CI/CD)
The container build environment must include automated tests to ensure that container images do not include outdated or insecure libraries or open source components. The continuous integration / continuous delivery (CI/CD) infrastructure itself must also be secured to avoid supply chain attacks. Unauthorized access to build or deployment systems could cause threat actors to inject malicious components into the container environment.
A container registry is a repository that stores container images. Registries are central to container security because they allow development teams to secure and store container images while scanning them for vulnerabilities. Organizations should treat images as artifacts to ensure their immutability and prevent the introduction of untested or insecure configuration changes into the production environment. This approach also allows organizations to replace or roll back high-risk containers quickly.
Learn more in our detailed guide to container image repositories
Container Runtime Environments
Releasing a container into a runtime environment presents several new security risks. Organizations must implement security policies to govern container behavior at runtime, ensuring administrators receive alerts when a container violates a policy. Administrators must also monitor and manage the resources used by containers to ensure the technology stack is not vulnerable to attack.
Learn more in our detailed guide to container runtime
The container orchestration environment, usually Kubernetes, is one of the most crucial components of container security. Container orchestration tools help manage complex container environments, allowing teams to predictably run and scale their environments. However, the complexity of a container environment can make it an attractive target for attackers, who can exploit misconfigurations to compromise nodes or other infrastructure elements. By compromising a single node, attackers can gain access to additional nodes or even compromise the entire cluster.
The final component is the server and network infrastructure that supports the entire operation. Containers require an operating system on a server or virtual machine to operate, and this infrastructure layer presents an additional opportunity for attack.
Security vulnerabilities can affect underlying infrastructure and operating systems such as Linux or Windows servers, virtualized operating systems, cloud provider infrastructure, and network devices. An especially high-risk object is any device that manages the container environment. An attack on an organization’s underlying infrastructure can neutralize the container system running on that infrastructure.
Types of Container Security Solutions
Here are some useful types of tools for securing container environments and applications.
Container Monitoring Solutions
A container monitoring solution allows security teams to track an application’s performance. The ephemeral nature of containers makes them complex and thus harder to monitor than a traditional application that runs on VMs or physical servers. Monitoring tools can collect and analyze performance metrics at scale across large containerized environments, even as workloads and clusters scale up and down.
Containerized applications impact the business processes, so it is essential to ensure their health. Application performance monitoring allows the organization to keep track of its container-based applications and infrastructure and ensure they remain optimal. Continuous monitoring is crucial for maintaining peak performance, enabling DevOps and security teams to detect and resolve issues proactively.
Some tools also monitor historical data or CPU usage to help analysts identify trends that may cause recurring bottlenecks or other issues. These metrics are useful for forecasting resource needs accurately and can inform resource allocation and deployments. It is important to monitor the entire container environment to minimize production-level risks.
A container scanning or image scanning tool scans containers and related components to identify security threats and detect vulnerabilities. Scanning is a crucial part of container security, making this the most important tool for many security and DevOps teams dealing with containerized workflows.
Container images are available from diverse sources, so maintaining trust in each container image is essential. Container scanning allows teams to understand a container or container image’s components and associated risks.
Trivy is a popular, open source container scanning tool that makes it easy to scan vulnerabilities in containers, Kubernetes clusters, and infrastructure as code (IaC) templates.
A container networking tool provides a virtualized, well-defined network to facilitate connectivity between containers. An internal virtualized network enables communication and integration between container-based applications and components. Organizations can create multiple networks to isolate the regions around each container or set of containers, enabling independent communication between multiple containers.
Container networking solutions are useful for increasing an application’s data accessibility and scalability. They offer a high level of security and service discovery capabilities—this technology powers microservices architectures using interconnected container-based applications.
6 Container Security Best Practices
1. Securing Images
Containers are created from container images, and inherit all the elements, good and bad, that exist in those images. This makes it important to restrict potentially malicious activity in container images, whether developed in-house by an organization or sourced from an external container registry.
Learn more in our detailed guide to container images
An image typically contains application code, libraries, tools, dependencies and other files needed to make an application run. All tools and libraries within an image are a potential threat. To reduce the attack surface, include only the application code and essential dependency in a container image. Remove any tools or libraries, even common ones like sed or awk, if they are not absolutely needed.
Most images are created from “base images”. It is important to use a trusted image provider. Anyone can publish images to Docker Hub. Prefer to use Docker Official Images, which are vetted by Docker experts or official images provided and signed by software vendors. Always scan base images, even if they come from a trusted source, because in some cases even Docker Official Images can be outdated and no longer maintained.
Finally, just like containers should not run as root on the host, applications within a container image should not be granted root access to their container. Create a dedicated user account for each application and run it under this account. This is easy to define in a Dockerfile.
2. Securing Registries
Many organizations maintain a private container registry. It is important to apply security controls to the container registry, to protect images from tampering and ensure the integrity of the development process.
Here are several ways to improve security of container registries:
- Establish strict access control—define who can post new images, delete and modify existing images. Periodically evaluate how many people have access to the registry, remove unused accounts and revoke unneeded permissions.
- Sign images—an important security measure is to sign images. Signed images can be traced back to the signer, meaning they are difficult to tamper with or replace with a compromised image. Docker provides Notary, an open source tool for image signing. A newer option for image signing is Cosign, part of the Sigstore project.
- Scan images—when storing images in the registry, scan them for vulnerabilities. It is not enough to scan images once—images that were at one point safe can become a threat. New vulnerabilities are discovered all the time, components can go out of date, and images might be compromised by malicious insider or accidental update. To address these issues, frequently scan all images stored in the registry.
3. Securing Deployment
When deploying containers, the most important thing is to ensure the target environment is secure. This includes several aspects:
- Hardening the underlying operating system containers run on.
- Setting up virtual private cloud (VPC), security groups, and firewall rules.
- Restricting access to container resources to a limited group of named administrator accounts.
- When using container orchestrators like Kubernetes, restricting API access using role-based access control (RBAC) and hardening Kubernetes manifests.
Immutability is crucial to secure container deployments. Container images are designed to be immutable, meaning a container cannot be changed while it is running. This ensures that the image as approved has not been modified. If it’s not possible to update a running container, it is easy to identify suspicious activity, because anything not included in the original image can be deemed suspicious. Immutability makes for deterministic security – any container that is modified can automatically be considered compromised.
When using immutable deployments, there is no SSH access to the host. This is good for security, but requires a solid strategy for container observability to enable monitoring and troubleshooting.
4. Securing Runtime
Threats can arise during normal container operations. Even when an organization appropriately protects containers in earlier stages of development, it must have a strategy for detecting and mitigating threats at runtime, when containers are running in production environments.
Restricting container communications
Containers are often used to deploy components of microservices applications. Each application component might connect to multiple other components and external services, increasing the attack surface.
It is important to segment the network to isolate containers that have sensitive workloads or data. Remember the principle of least privilege and only allow connections between containers if they are actually needed.
It is critical to expose only the port that the application serves and nothing else, both on containers and container hosts. SSH is the only exception, but should also be closely controlled and monitored. Also, when ports are opened, they should preferably communicate over transport layer security (TLS) to ensure traffic is encrypted.
Avoid bind-mounted storage volumes. Prefer to use volumes, and carefully manage them to protect their data. Volumes should preferably be read only, and creation and updates of storage volumes should be carefully controlled. The physical device or cloud storage service that manages container storage should be carefully protected as well.
Ensuring only safe images run
Even if all images are scanned to and ensure they are secure, there is always the possibility that another, unsafe image will be the one actually running in a production environment. To prevent this, use tools to verify that running containers are using safe container images sourced from an approved registry. Also leverage container image signing to verify the source and integrity of images.
5. Managing Secrets
Make sure that secrets (such as access credentials to integrated systems) are never stored in plaintext within a container. It is critical to have a system to manage secrets and pass them every time each container is started.
Container orchestrators have built-in secret management. It is also possible to use other systems, such as cloud provider secret management tools or open source solutions such as Vault. An advantage to using cloud provider secret management is that they provide out-of-the-box user access controls for secrets related to cloud identity management. Whatever tool is used, ensure its settings are configured to use encryption, as encryption is usually not the default.
Other important secret management practices:
- Regularly rotate keys—this means creating a new value for the key and discarding the old one. The longer a secret is kept, the more likely it will be leaked. Rotating the key reduces the value an attacker can gain and limits the damage caused by compromise.
- Use the volume mount method—in this approach, the code reads the secret value from a file in a known location. Most orchestrators support this method of passing secrets to containers.
Related content: Read our guides to:
6. Adopting Zero Trust Principles
Zero trust is a security approach that requires verification of every user and resource, eliminating implicit trust. Zero trust policies validate entities for every computing session and activity. A zero trust architecture continually validates every user and asset connecting to the network, controlling and monitoring access.
Containerized systems can incorporate zero trust policies to secure communication within clusters and between containers. Zero trust requires authentication every time a container accesses a service. This strategy prevents attackers from moving between containers and helps contain breaches.
Every container server must have a certificate establishing the root of trust, verifying that all configuration and code changes have administrator authorization. The server certificate allows the system to hash all code and infrastructure changes cryptographically. Any container on a shared operating system must be sandboxed in a virtual network or machine. Organizations can implement IAM and PKI tools to manage zero trust policies.
These security measures collectively protect cloud-based container environments, ensuring that containers only communicate with authorized services. This approach also supports multi-cloud deployments, with the underlying infrastructure enforcing container security controls.
Holistic Container Security with Aqua
Aqua provides a Cloud Native Application Protection Platform (CNAPP) that secures cloud native, serverless, and container technologies. Aqua offers end-to-end security for containerized applications, and protects you throughout the full lifecycle of your CI/CD and DevOps pipeline: from the point where you shift left, through to runtime controls, container-level firewalls, audit, and compliance.
Continuous Image Assurance
Aqua scans container images for malware, vulnerabilities, embedded secrets, configuration issues and OSS licensing. You can develop policies that outline, for example, which images can run on your container hosts. Aqua’s vulnerabilities database, founded on a continuously updated data stream, is aggregated from several sources and consolidated to make sure only the latest data is used, promoting accuracy and limiting false positives and negligible CVEs.
Aqua offers Trivy, an open source Kubernetes security scanning tool, which now provides multiple new capabilities:
- Scanning IaC templates for security vulnerabilities
- Kubernetes operator that can automatically trigger scans in response to changes to cluster state
- Automated generation of software bills of materials (SBOMs)
- Detection of sensitive data like hard-coded secrets in code and containers
- Docker Desktop integration making it possible to scan container images directly from Docker Dashboard
Solutions like Aqua’s Dynamic Threat Analysis allow protection against advanced and evasive security threats, including supply chain attacks. The industry’s first container sandbox solution, Aqua DTA dynamically assesses the risks of container images by running them in an isolated sandbox to monitor runtime behavior before they hit the production environment.
Runtime Security for Containers
Aqua protects containerized applications at runtime, ensuring container immutability and prohibiting changes to running containers, isolating the container from the host via custom machine-learned SECCOMP profiles. It also ensures least privileges for files, executables and OS resources using a machine-learned behavioral profile, and manages network connections with a container firewall.
To enforce immutability of container workloads, Aqua enables drift prevention at runtime. This capability deterministically prohibits any changes to the image after it is instantiated into a container. By identifying and blocking anomalous behavior in running containers, Aqua helps ensure that your workloads are protected from runtime attacks, zero-day exploits, and internal threats.
Aqua further enhances securing containers as follows:
- Event logging and reporting—granular audit trails of access activity, scan container commands, events, and coverage, container activity, system events, and secrets activity.
- CIS certified benchmark checks—assess node configuration against container runtime and K8s CIS benchmarks with scheduled reporting and testing or Aqua OSS tools.
- Global compliance templates—pre-defined compliance policies meet security standards such as HIPPA, CIS, PCI, and NIST.
- Full user accountability—uses granular user accountability and monitored super-user permissions.
- “Thin OS” host compliance—monitor and scan host for malware, vulnerabilities, login activity, and to identify scan images kept on hosts.
- Compliance enforcement controls—only images and workloads that pass compliance checks can run in your environment.
Aqua’s container firewall lets you visualize network connections, develop rules based on application services, and map legitimate connections automatically. Only whitelisted connections will be allowed, both within a container cluster, and also between clusters.
Store your credentials as secrets, don’t leave them in your source code. Aqua securely transfers secrets to containers at runtime, encrypted at rest and in transit, and places them in memory with no persistence on disk, so they are only visible to the relevant container. Integrate Aqua’s solution with your current enterprise vault, including CyberArk, Hashicorp, AWS KMS or Azure Vault. You can revoke, update, and rotate secrets without restarting containers.