[Updated post as of October 15, 2020]
At Anchore, we’re fortunate to be part of the journey of many technology teams as they become cloud-native. We would like to share what we know.
Over the past several years, we’ve observed many teams perform microservice application modernization using containers as the basic building blocks. Using Kubernetes, they dynamically orchestrate these software units and optimize their resource utilization. Aside from the adoption of new technologies, we’ve seen cultural transformations as well.
For example, the breaking of organizational silos to provide an environment for “shifting left” with the shared goal of incorporating as much validation as possible before a software release. One specific area of transformation which is fascinating to us here is how cloud-native is modernizing both development and security practices, along with CI/CD and operations workflows.
Below, we discuss how foundational elements of modern container image security, combined with improved development practices, enhance software delivery overall. For the purposes of this blog, we’ll focus mainly on the image build and the surrounding process within the CI stages of the software development lifecycle.
Here is some high-level guidance all technology teams using containers can implement to increase their container image security posture.
- Use minimal base images: Use minimal base images only containing necessary software packages from trusted sources. This will reduce the attack surface of your images, meaning there is less to exploit, and it will make you more confident in your deployment artifacts. To address this, Red Hat introduced Universal Base Images designed for applications that contain their own dependencies. UBIs also undergo regular vulnerability checking and are continuously maintained. Other examples of minimal base images are Distroless images, maintained by Google, and Alpine Linux images.
- Go daemonless: Moving away from the Docker CLI and daemon client/server model and into a “daemonless” fork/exec model provides advantages. Traditionally, with the Docker container platform, image build, registry, and container operations happen through what is known as the daemon. Not only does this create a single point of failure, but Docker operations are conducted by a user with full root authority. More recently, tools such as Podman, Buildah, and Skopeo (we use Skopeo inside of Anchore Engine) were created to address the challenges of building images, working with registries, and running containers. For a bit more information the security benefits of using Podman vs Docker read this article by Dan Walsh.
- Require image signing: Require container images to be signed to verify their authenticity. By doing so you can verify that your images were pushed by the correct party. Image authenticity can be verified with tools such as Notary, and both Podman and Skopeo (discussed above) also provide image signing capabilities. Taking this a step further, you can require that CI tools, repositories, and all other steps in the CI pipeline cryptographically sign every image they process with a software supply chain security framework such as in-toto.
- Inspect deployment artifacts: Inspect container images for vulnerabilities, misconfigurations, credentials, secrets, and bespoke policy rule violations prior to being promoted to a production registry and certainly before deployment. Container analysis tools such as Anchore can perform deep inspection of container images, and provide codified policy enforcement checks which can be customized to fit a variety of compliance standards. Perhaps the largest benefit of adding security testing with gated policy checks earlier in the container lifecycle is that you will spend less time and money fixing issues post-deployment.
- Create and enforce policies: For each of the above, tools selected should have the ability to generate codified rules to enable a policy-driven build and release practice. Once chosen they can be integrated and enforced as checkpoints/quality control gates during the software development process in CI/CD pipelines.
How Improved Development Practices Help
The above can be quite challenging to implement without modernizing development in parallel. One development practice we’ve seen change the way organizations are able to adopt supply chain security in a cloud-native world is GitOps. The declarative constructs of containers and Kubernetes configurations, coupled with infrastructure-as-code tools such as Terraform provide the elements for teams to fully embrace the GitOps methodology. Git now becomes the single source of truth for infrastructure and application configuration, along with policy-as-code documents. This practice allows for improved knowledge sharing, code reviews, and self-service, while at the same time providing a full audit trail to meet compliance requirements.
The key benefit of adopting modern development practices is the ability to deliver secure software faster and more reliably. By shifting as many checks as possible into an automated testing suite as part of CI/CD, issues are caught early, before they ever make their way into a production environment.
Here at Anchore, we’re always interested in finding out more about your cloud-native journey, and how we may be able to help you weave security into your modern workflow.