diff --git a/.github/workflows/link-check.yml b/.github/workflows/link-check.yml
index 82e3b7b..ba62702 100644
--- a/.github/workflows/link-check.yml
+++ b/.github/workflows/link-check.yml
@@ -24,17 +24,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
-
- - uses: actions/cache@v3
+ - uses: actions/setup-node@v4
with:
- path: ~/.npm
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: |
- ${{ runner.os }}-node-
+ node-version: 23
+
+ - uses: actions/checkout@v4
- name: Install Dependencies
- if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
- name: Run link checks
diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml
index ef26eaf..45fa7b5 100644
--- a/.github/workflows/markdownlint.yml
+++ b/.github/workflows/markdownlint.yml
@@ -24,17 +24,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
-
- - uses: actions/cache@v3
+ - uses: actions/setup-node@v4
with:
- path: ~/.npm
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: |
- ${{ runner.os }}-node-
+ node-version: 23
+
+ - uses: actions/checkout@v4
- name: Install Dependencies
- if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
- name: Run Markdownlint
diff --git a/.gitignore b/.gitignore
index 2f472d9..51ddaeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,72 +1,7 @@
-.DS_Store
-
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# TypeScript v1 declaration files
-typings/
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-
-# next.js build output
-.next
-
-# local bundler files
-.bundle
-Gemfile.lock
-vendor
-
-# local Jekyll files
_site
+.sass-cache
+.jekyll-cache
.jekyll-metadata
+vendor
+node_modules
+Gemfile.lock
diff --git a/.markdownlint.json b/.markdownlint.json
index 5b73e20..1dd8622 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -1,6 +1,6 @@
{
"default": true,
"MD013": false,
- "MD041": false,
- "MD045": false
+ "MD033": false,
+ "MD041": false
}
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index aba07f9..49e6f1f 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,6 +1,6 @@
# Contributor Covenant Code of Conduct for the [`project_name`] project
-([Français](#Code-de-conduite-pour-le-projet-nom-du-projet))
+([Français](#code-de-conduite-pour-le-projet-nom-du-projet))
Contributors to repositories hosted in [`project_name`] are expected to follow the Contributor Covenant Code of Conduct, and those working within Government are also expected to follow the Values and Ethics Code for the Public Sector
@@ -65,7 +65,7 @@ This Code of Conduct is also inspired by GDS' `alphagov` [Code of conduct](https
# Code de conduite pour le projet [`nom du projet`]
-([English](#Contributor-Covenant-Code-of-Conduct-for-the-projectname-project))
+([English](#contributor-covenant-code-of-conduct-for-the-project_name-project))
Les contributeurs aux dépôts hébergés dans [`nom du projet`] sont tenus de respecter le Code de conduite du Pacte des contributeurs, et ceux qui travaillent au sein du gouvernement sont également tenus de respecter le Code de valeurs et d'éthique du secteur public.
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..8560923
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,34 @@
+source "https://rubygems.org"
+# Hello! This is where you manage which Jekyll version is used to run.
+# When you want to use a different version, change it below, save the
+# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
+#
+# bundle exec jekyll serve
+#
+# This will help ensure the proper Jekyll version is running.
+# Happy Jekylling!
+#gem "jekyll", "~> 4.3.4"
+# This is the default theme for new Jekyll sites. You may change this to anything you like.
+#gem "jekyll-theme-minimal"
+# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
+# uncomment the line below. To upgrade, run `bundle update github-pages`.
+gem "github-pages", group: :jekyll_plugins
+# If you have any plugins, put them here!
+group :jekyll_plugins do
+ gem "jekyll-feed", "~> 0.12"
+ gem "jekyll-titles-from-headings", "~> 0.5"
+end
+
+# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
+# and associated library.
+platforms :mingw, :x64_mingw, :mswin, :jruby do
+ gem "tzinfo", ">= 1", "< 3"
+ gem "tzinfo-data"
+end
+
+# Performance-booster for watching directories on Windows
+gem "wdm", "~> 0.2", :platforms => [:mingw, :x64_mingw, :mswin]
+
+# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
+# do not have a Java counterpart.
+gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
diff --git a/README.md b/README.md
index 17abf0b..5f991a5 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,13 @@
([Français](#gabarit-pour-dépôts-de-code-source-ouvert-du-gouvernement-du-canada))
-With the introduction of cloud services and the adoption of “continuous deployment” of software services, the movement of applications from one environment to another and within an environment is required to be agile and predictable. Container technology (OS virtualization) enables software to deploy quickly and run predictably when moved from one environment to another. Further, microservices are established when a set of containers work together to compose an application. While this approach improves flexibility and scalability for application development and simplifies functionality, it adds another layer of abstraction that must be secured.
+*Microservices* are established when a set of functional components work together to compose an application. While this approach improves flexibility and scalability for application development and simplifies functionality, it adds another layer of abstraction that must be secured.
-This guidance provides recommendations to secure containers and microservices when deploying Government of Canada (GC) services. It highlights the controls, configuration and tools to secure GC workloads running in containers and orchestrators and recommendations for compliance verification.
+*Container* technology (OS virtualization) enables software to be deployed quickly and run predictably when moved from one environment to another. In modern deployments, containers are often orchestrated by a container orchestration tool, such as Kubernetes (K8s) or a cloud provider, to manage the lifecycle of the containers.
+
+*Microservices* are often deployed in *containers* to take advantage of the benefits of both technologies.
+
+This guidance provides recommendations to secure *containers* and *microservices* when deploying Government of Canada (GC) services. It highlights the controls, configuration and tools to secure GC workloads running in *containers* and orchestrators and recommendations for compliance verification.
## Table of Contents
@@ -19,14 +23,14 @@ This guidance provides recommendations to secure containers and microservices wh
- [2.3 Containers](en/2_Context.md/#23-containers)
- [2.4 Container Security](en/2_Context.md/#24-container-security)
- [2.5 Microservices](en/2_Context.md/#25-microservices)
- - [2.5.1 The Ten Commandments of Microservices](en/2_Context.md/#251-the-ten-commandments-of-microservices)
- - [2.5.2 Service Mesh](en/2_Context.md/#252-service-mesh)
- - [2.6 Functions as a Service](en/2_Context.md/#26-functions-as-a-service)
+ - [2.6 Orchestration](en/2_Context.md/#26-orchestration)
+ - [2.6.1 Service Mesh](en/2_Context.md/#261-service-mesh)
+ - [2.7 Functions as a Service](en/2_Context.md/#26-functions-as-a-service)
- [3. Threat Environment](en/3_Threat-Environment.md)
- [4. Implementation Recommendations](en/4_Implementation-Recommendations.md)
- [4.1 Host Recommendations](en/4_Implementation-Recommendations.md/#41-host-recommendations)
- [4.2 Image Builds](en/4_Implementation-Recommendations.md/#42-image-builds)
- - [4.3 Container Security Brokers](en/4_Implementation-Recommendations.md/#43-container-security-brokers)
+ - [4.3 Container Deployment Security](en/4_Implementation-Recommendations.md/#43-container-deployment-security)
- [4.4 Orchestration - Kubernetes](en/4_Implementation-Recommendations.md/#44-orchestration---kubernetes)
- [5. Additional Microservices and Container Security Guidelines](en/5_Microservice_Security.md)
- [5.1 Securing Platform](en/5_Microservice_Security.md#51-securing-platform)
@@ -39,51 +43,49 @@ This guidance provides recommendations to secure containers and microservices wh
- [5.8 Secrets Management](en/5_Microservice_Security.md#58-secrets-management)
- [5.9 Continuous Integration/Continuous Deployment (CI/CD)](en/5_Microservice_Security.md#59-continuous-integrationcontinuous-deployment-cicd)
- [5.10 Infrastructure as Code](en/5_Microservice_Security.md#510-infrastructure-as-code)
-- [6. References](en/6_References.md)
-
-## List of Tables
-
-- [Table 2‑1 Virtualization and Container Quality Attributes](en/2_Context.md/#23-containers)
## List of Figures
-- [Figure 2‑1 Monolithic versus Microservice \[1\]](en/2_Context.md/#21-definitions)
-- [Figure 2‑2 High-level overview of VM's, containers, and serverless \[3\]](en/2_Context.md/#21-definitions)
-- [Figure 2‑3 Shared Responsibility Model with Containers](en/2_Context.md/#21-definitions)
-- [Figure 2‑4 Container Technologies](en/2_Context.md/#23-containers)
-- [Figure 2‑5 Microservices Architecture (MSA)](en/2_Context.md/#25-microservices)
-- [Figure 2‑6 Example service mesh (CNCF Project Istio) \[12\]](en/2_Context.md/#252-service-mesh)
+- [Figure 2‑1 Monolithic versus Microservice](en/2_Context.md#figure-2-1)
+- [Figure 2‑2 High-level overview of VMs, containers, and serverless](en/2_Context.md#figure-2-2)
+- [Figure 2‑3 Shared Responsibility Model with Containers](en/2_Context.md#figure-2-3)
+- [Figure 2‑4 Container Technologies](en/2_Context.md#figure-2-4)
+- [Figure 2‑5 Microservices Architecture (MSA)](en/2_Context.md#figure-2-5)
+- [Figure 5-1 VMs vs Containers](en/5_Microservice_Security.md#figure-5-1)
+- [Figure 5-2 Kubernetes Attack Surface](en/5_Microservice_Security.md#figure-5-2)
+- [Figure 5-3 RBAC in Kubernetes](en/5_Microservice_Security.md#figure-5-3)
+- [Figure 5-4 Service Mesh](en/5_Microservice_Security.md#figure-5-4)
+- [Figure 5-5 API Gateway with OPA](en/5_Microservice_Security.md#figure-5-5)
+- [Figure 5-6 Securing Container Images](en/5_Microservice_Security.md#figure-5-6)
## List of Abbreviations and Acronyms
| Abbreviation | Definition |
| ------------ | -------------------------------------------------- |
-| CIRT | Computer Incident Response Team |
-| CONOPS | Concept of Operations |
-| CSE | Communications Security Establishment |
-| CS EMP | Cyber Security Event Management Plan |
+| CaaS | Containers as a service |
| CSP | Cloud Service Provider |
-| FedRAMP | Federal Risk and Authorization Management Program |
+| FaaS | Functions as a service |
| GC | Government of Canada |
-| GSRM | Government of Canada Strategic Reference Model |
| IaaS | Infrastructure as a Service |
-| IPC | Information Protection Centre |
+| IaC | Infrastructure as code |
+| IDS | Intrusion Detection System |
| IT | Information Technology |
-| ITSG | Information Technology Security Guidance |
-| LAN | Local Area Network |
+| JSON | JavaScript Object Notation |
+| JWT | JSON Web Tokens |
+| K8s | Kubernetes |
+| MSA | Microservices Architecture |
+| mTLS | Mutual Transport Layer Security |
| NIST | National Institute of Standard and Technology |
-| PAA | Program Alignment Architecture |
+| OAuth | Open Authentication |
+| OS | Operating system |
| PaaS | Platform as a Service |
| PBMM | Protected B, Medium Integrity, Medium Availability |
-| PIA | Privacy Impact Assessment |
-| PoAM | Plan of Actions and Milestones |
-| RACI | Responsible, Accountable, Consulted, Informed |
+| RBAC | Role-base Access Control |
| SaaS | Software as a Service |
-| SDLC | System Development Lifecycle |
-| SLA | Service Level Agreement |
-| SSC | Shared Services Canada |
+| SSH | Secure Shell |
| TBS | Treasury Board of Canada Secretariat |
-| ULL | Unclassified, Low Integrity, Low Availability |
+| TLS | Transport Layer Security |
+| VM | Virtual Machine |
### How to Contribute
diff --git a/SECURITY.md b/SECURITY.md
index 985c1f8..5baaff3 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,4 +1,4 @@
-([Français](#sécurité))
+([Français](#signalement-des-problèmes-de-sécurité))
# Reporting Security Issues
@@ -7,6 +7,8 @@ To report a security issue, email [zztbscybers@tbs-sct.gc.ca](mailto:zztbscybers
The TBS team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
______________________
+([English](#reporting-security-issues))
+
## Signalement des problèmes de sécurité
Pour signaler un problème de sécurité, envoyez un courriel à [zztbscybers@tbs-sct.gc.ca](mailto:zztbscybers@tbs-sct.gc.ca) et ajoutez le mot « SÉCURITÉ » à la ligne d’objet.
diff --git a/_config.yml b/_config.yml
index 26934b8..b930230 100644
--- a/_config.yml
+++ b/_config.yml
@@ -1,4 +1,5 @@
remote_theme: wet-boew/gcweb-jekyll
+title: Guidance on Secure Containers and Microservices
global:
lang: en
defaults:
@@ -6,6 +7,7 @@ defaults:
path: "" # Ensure it's applied to all pages
values:
layout: default
+markdown: gfm
plugins:
- jekyll-titles-from-headings
titles_from_headings:
diff --git a/_layouts/core.html b/_layouts/core.html
new file mode 100644
index 0000000..02cedf7
--- /dev/null
+++ b/_layouts/core.html
@@ -0,0 +1,30 @@
+{%- include variable-core.liquid -%}
+{%- capture page-title -%}
+ {%- if page.title -%}
+ {{ page.title }}
+ {%- else -%}
+ Page untitled
+ {%- endif -%}
+{%- endcapture -%}
+
+
+
+
+{% include license.html %}
+{{ page-title }} - {{ i18nText-siteTitle }}
+
+
+{% include metadata.html %}
+{% include resources-inc/head.html %}
+
+
+{%- if page.archived -%}
+ {% include headers-includes/archive.html %}
+{%- endif -%}
+{% include skiplinks/skiplinks.html %}
+{% include header/header.html %}
+{{ content }}
+{% include footers/footer.html %}
+{% include resources-inc/footer.html %}
+
+
\ No newline at end of file
diff --git a/assets/css/style.scss b/assets/css/style.scss
new file mode 100644
index 0000000..c5eeb90
--- /dev/null
+++ b/assets/css/style.scss
@@ -0,0 +1,41 @@
+---
+---
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-bottom: 2em;
+}
+
+h1, h2, h3 {
+ margin: 1em 0 2em 0 !important;
+}
+
+tbody tr:first-child td {
+ padding-top: 0.8em !important;
+}
+
+th {
+ border-bottom: solid #ddd .18em;
+ padding: 0.3em 0.8em 0.3em 0.2em !important;
+}
+
+td {
+ padding: 0 0.8em 0.6em 0 !important;
+}
+
+td em, td b, td strong {
+ color: #037A8C;
+ background-color: #f9f2f4;
+ border-radius: 0.2em;
+ padding: 2px 4px;
+ font-weight: normal;
+}
+
+p {
+ margin: 1em 0 !important;
+}
+
+img {
+ display: block;
+ clear: both;
+}
\ No newline at end of file
diff --git a/en/1_Introduction.md b/en/1_Introduction.md
index 381f2a0..04b3af4 100644
--- a/en/1_Introduction.md
+++ b/en/1_Introduction.md
@@ -2,9 +2,11 @@
([Back](../README.md))
+> **Note:** Generative artificial intelligence was used in the editing process of this publication in accordance with the FASTER principles outlined in the [Guide on the use of generative artificial intelligence - Canada.ca](https://www.canada.ca/en/government/system/digital-government/digital-government-innovations/responsible-use-ai/guide-use-generative-ai.html#toc-4).
+
## 1.1 Background
-With the introduction of cloud services and the adoption of "continuous deployment" of software services, the movement of applications from one environment to another (Data Centre \<-\> Public Cloud) and within an environment is required to be agile and predictable. Container technology (OS virtualization) enables software to deploy quickly and run predictably when moved from one environment to another. Further, microservices are established when a set of containers work together to compose an application. While this approach improves flexibility and scalability for application development and simplifies functionality, it adds another layer of abstraction that must be secured.
+With the introduction of cloud services and the adoption of "continuous deployment" of software services, the movement of applications from one environment to another (Data Centre ↔ Public Cloud) and within an environment is required to be agile and predictable. Container technology (OS virtualization) enables software to deploy quickly and run predictably when moved from one environment to another. Further, microservices are established when a set of containers work together to compose an application. While this approach improves flexibility and scalability for application development and simplifies functionality, it adds another layer of abstraction that must be secured.
## 1.2 Document Purpose and Scope
@@ -12,18 +14,20 @@ This document provides guidance to developers and operators when deploying appli
## 1.3 Audience
-This document is to be used by developers, operators, business owners, project managers, system and system security practitioners leveraging containers and microservices to deliver GC services.
+This document is to be used by developers, operators, business owners, project managers, system and system security practitioners leveraging containers and microservices to deliver Government of Canada (GC) services.
## 1.4 Document Overview
This document is structured as follows:
-> Section 1 identifies this document and its purpose,
+> [Section 1](#11-background) identifies this document and its purpose,
+>
+> [Section 2](./2_Context.md) provides context, including definitions and scope
>
-> Section 2 provides context, including definitions and scope
+> [Section 3](./3_Threat-Environment.md) introduces the threat environment and common attack vectors in a microservice architecture
>
-> Section 3 introduces the threat environment and common attack vectors in a microservice architecture
+> [Section 4](./4_Implementation-Recommendations.md) provides implementation recommendations to secure containers and microservices, including the hosts, orchestrators and security brokers; and
>
-> Section 4 provides implementation recommendations to secure containers and microservices, including the hosts, orchestrators and security brokers; and
+> [Section 5](./5_Microservice_Security.md) provides additional guidance on securing microservices, including the Kubernetes tenancy, service mesh, and network traffic.
>
-> Section 5 identifies the applicable references cited in this document.
+> [Section 6](./6_References.md) identifies the applicable references cited in this document.
diff --git a/en/2_Context.md b/en/2_Context.md
index 11f5986..3820f57 100644
--- a/en/2_Context.md
+++ b/en/2_Context.md
@@ -4,197 +4,149 @@
## 2.1 Definitions
-Containers and orchestrators support cloud native deployments of distributed systems, often based on microservice architecture as depicted in Figure 2-1.
+Containers and orchestrators support cloud native deployments of distributed systems, often based on microservice architecture as depicted in [Figure 2-1](#figure-2-1).
-![Figure 2-1](../media/image2.png)
-_Figure 2‑1 Monolithic versus Microservice [\[1\]](5_References.md)_
+
-- **Microservices** are applications written as blocks of code and interconnected via API's. Based on architectural principles such as [Domain Driven Design (DDD)](https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture), [12-factor Apps](https://12factor.net/) and Cloud Native Architecture (Infrastructure as code) microservice applications most often use containers, orchestrators and, more recently, functions as a service (serverless).
-- **Containers** are portable environments containing application code, associated libraries and dependencies. Developers use build pipelines to create and deploy containerized applications, test and QA in development environments and ship as services to production using package managers and orchestration tools, such as Kubernetes (both managed and hosted). The primary goal of a container is to provide a standardized set of virtual resources to an application process that are separated from the virtual resources provided to other containers deployed on the same platform. The virtual resources are provided based on container configuration information. Virtual resources can also be shared by groups of containers. This allows a container to be deployed and run on any compatible platform regardless of the underlying operating system.
-- **Serverless**, Functions as a service (FaaS) and event-driven architecture all initially referred to a microservice that is run on a CSP compute engine only when invoked, without any consideration for infrastructure (an allocation of machine resources and run duration dependant on invocation policy). Recently, serverless is also being used to describe a managed container service (CaaS), where the user is not responsible for the host environment where their container runs.
-- **Kubernetes** is an open source container cluster orchestrator that automates the deployment, scaling and management of containerized applications.
-- **Unit of Deployment**: Cloud native applications are often based on a unit of deployment, usually a container, a collection of containers in a kubernetes pod, or an event-driven function. Units of deployment are most often used as a security boundary when implementing policy. Cloud-native applications are generally distributed, elastic and horizontally scalable systems composed of microservices that isolate state in a minimum of stateful components [\[2\]](5_References.md).
+![Figure 2-1](../media/image_1.png)
+_Figure 2‑1 Monolithic versus Microservice_
-![Virtual Machines, Containers, Serverless Architecture](../media/image3.jpeg)
+- **Microservices** are loosely-coupled applications written as blocks of functionality interconnected via lightweight communication protocols, such as RESTful API's.
-_Figure 2‑2 [High-level overview of VM's, containers, and serverless](https://www.cloudops.com/2018/02/serverless-computing-hot-or-not-2/) [\[3\]](5_References.md)_
+ Based on architectural principles such as [Domain Driven Design (DDD)](https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture), [12-factor Apps](https://12factor.net/) and Cloud Native Architecture (Infrastructure as code) microservice applications most often use containers, orchestrators and, more recently, functions as a service (serverless).
+- **Containers** are portable computing environments containing pre-built applications, associated libraries and dependencies, and configuration that keeps them independent from the host environment and other containers.
+- **Serverless computing**, is a managed container service where the user is not responsible for the host environment where their container run, including the orchestration service. Functions as a service (FaaS) are an example of serverless computing.
+- **Kubernetes** is an open source container cluster orchestrator that automates the deployment, scaling, and management of containerized applications.
-Figure 2‑3 below depicts the shared responsibility model and concept of managed and hosted cloud services as it relates to containers. This includes:
+
+
+![Virtual Machines, Containers, Serverless Architecture](../media/image_3.png)
+_Figure 2‑2 High-level overview of VMs, containers, and serverless_
+
+[Figure 2‑3](#figure-2-3) below depicts the shared responsibility model and concept of managed and hosted cloud services as it relates to containers. This includes:
- **Managed** implies the control plane of a service is managed by a third party while the data plane is managed by the GC (a managed service such as Azure Kubernetes Service)
-- **Hosted** means both the control and data planes are managed by the GC, regardless who manage the infrastructure underneath. For example, deploying Kubernetes on EC2 or on-premise compute.
+- **Hosted** means both the control and data planes are managed by the GC, regardless who manages the infrastructure underneath. For example, deploying Kubernetes on EC2 or on-premise servers.
-![Figure 2-3](../media/image4.png)
+
+
+![Figure 2-3](../media/image_4.png)
_Figure 2‑3 Shared Responsibility Model with Containers_
## 2.2 Infrastructure
-Constrainers, kubernetes and (despite the name) serverless, all run on virtual machines or servers. One of the first steps in container infrastructure security is to harden the hosts on which the container runtime resides, including container engines, kubernetes nodes and pods; and serverless functions; based on current GC security best practices. For managed infrastructure or services, security best practices are partially inherited from cloud service providers with the remaining implemented by the tenant on the resource.
+Constrainers, Kubernetes, and serverless computing, all run on virtual machines (VMs) or physical servers. It is important to harden hosts on which the container runtime resides, including container engines, Kubernetes nodes and pods, and serverless functions, based on current GC security best-practices. For managed infrastructure or services, security best-practices are partially inherited from cloud service providers (CSPs) with the remaining implemented by the tenant (GC organization) on the resource, also know as the _**Shared Responsibility Model**_.
## 2.3 Containers
-One of the trends outlined in the in the _Enterprise Security Architecture Description Document Annex E -- Application Security (APP)_ [\[4\]](5_References.md) and the _Enterprise Security Architecture Description Document Annex F -- Compute and Storage Services Security (CSS)_ [\[5\]](5_References.md) is the use of containers.
+The introduction of cloud services and the adoption of "continuous deployment" of software services has resulted in the movement of applications from one environment to another (Data Centre ↔ Public Cloud) and within an environment was required to be agile and predictable. Container technology (OS virtualization) enables software to deploy quickly and run predictably when moved from one environment to another.
-The introduction of cloud services and the adoption of "continuous deployment" of software services has resulted in the movement of applications from one environment to another (Data Centre \<-\> Public Cloud) and within an environment was required to be agile and predictable. Container technology (OS virtualization) enables software to deploy quickly and run predictably when moved from one environment to another.
+
-![Figure 2-4](../media/image5.jpeg)
+![Figure 2-4](../media/image_5.png)
_Figure 2‑4 Container Technologies_
-As depicted in Figure 2‑4 containers sit on top of a physical or virtualized server and its OS. Each container shares the host OS kernel and the OS binaries and libraries. Shared components are read-only, with each container able to be written to through a unique mount. This makes containers exceptionally "light" -- containers can be megabytes in size and take just seconds to start, versus minutes for a VM. Table 2‑1 provides a list of quality attributes associated with virtualization and container technologies in a modern data center environment.
-
-**Table** **2‑1 Virtualization and Container Quality Attributes**
-
-| **Quality Attributes** | **Virtualization Technology** | **Container Technology** |
-| ------------------------- | ------------------------------------- | ----------------------------------------------------- |
-| Technology code base size | 2-3 Gigabytes | 20-90 MB's |
-| Provisioning | 2-3 minutes | 2-3 seconds |
-| Cost | More costly than container technology | Less servers, Less Staff |
-| Resource utilization | High | Low |
-| DevOps Integration | Difficult, time consuming | Easy |
-| Microservices | No advantage | Lightweight containers are suitable for microservices |
-| Continuous Deployment | Difficult, time consuming | Containers deploy in seconds |
-
-The benefits of containers often derive from their speed and lightweight nature; many more containers can be put onto a server than onto a traditional VM. Containers are "shareable" and can be used on a variety of public and private cloud deployments, accelerating DevOps by quickly packaging software services along with their dependencies. Additionally, containers reduce management overhead. Because they share a common operating system, only a single operating system needs care and feeding (bug fixes, patches, etc.). [^1]
-
-VMs and containers differ on quite a few dimensions, but primarily because containers provide a way to virtualize an OS in order for multiple workloads to run on a single OS instance, whereas with VMs, the hardware is being virtualized to run multiple OS instances. Containers' speed, agility and portability make them yet another tool to help streamline software development and continuous deployment. Distinguishing characteristics include;
+As depicted in Figure 2‑4 containers sit on top of a physical or virtualized server and its OS.
-- Virtual machines contain a complete operating system and applications.
-- Virtual machines use hypervisors to share and manage hardware while containers share the kernel of the host OS to access the hardware.
-- Virtual machines have their own kernel and VM's don't use and share the kernel of the host OS, hence VM's are isolated from each other at a deep level.
-- Virtual machines residing on the same server can run different operating systems. One VM can run Windows while the VM next door might be running Ubuntu.
-- Containers are bound by the host OS, containers on the same server use the same OS.
-- Containers are virtualizing the underlying operating system while virtual machines are virtualizing the underlying hardware.
-
-OS containers are virtual environments that share the kernel of the host operating system but provide user space isolation. For all practical purposes, you can think of OS containers as VMs. You can install, configure and run different applications, libraries, etc., just as you would on any OS. Just as a VM, anything running inside a container can only see resources that have been assigned to that container.
-
-OS containers are beneficial when a fleet of identical or different flavors of software distributions are required. Containers are created from templates (or images) that determine the structure and contents of the container. It thus allows you to create containers that have identical environments with the same package versions and configurations across all containers.
+| Benefits | Description |
+| --------------------------- | ----------- |
+| **Agility** | Containers can be deployed quickly and predictably, regardless of the environment. |
+| **Isolation** | Containers are isolated from each other and the host OS. |
+| **Portability** | Containers can be moved from one environment to another. |
+| **Resource Efficiency** | Containers share the host OS kernel and patches/updates, reducing management burden. |
## 2.4 Container Security
-The introduction of container technology adds another layer of abstraction that must be secured. This begins by configuring the container runtime (i.e. docker engine) with specific flags found in the CIS Docker Benchmark where possible. Running these flags harden the Docker engine and kubernetes Master and Workers (API Server and nodes) based on the NIST Special Publication 800-190 [\[6\]](5_References.md). A matrix has been developed that provides a mapping of controls and container components in the _Security Controls Mapping to Docker and Kubernetes_ [\[7\]](5_References.md) document and provides specific flags as well as open-source tools to assist with compliance. Additionally, DevOps and container orchestration services may be compromised providing opportunities for exploitation. Sophisticated attackers will look to exploit new container services and the tools that support those services.
-
-The bulk of vulnerabilities exist within the base operating system. Accordingly, a patch to one base O/S can support as many containers as run on that O/S without impacting the containers. This benefit makes vulnerability management significantly easier in container-based deployments. Since containers themselves are often ephemeral, vulnerabilities found in containers (and images) can be mitigated by replacing with a non-vulnerable container.
-
-The increasing popularity of containers has led to the development of stripped down operating systems that include only the features required to host containers. These include CoreOS, RancherOS, Ubuntu Snappy, VMware Photon, Red Hat Atomic Host, and others. By stripping out unnecessary capabilities, these operating systems have a smaller attack surface and are easier for administrators to maintain and update.
-
-## 2.5 Microservices
-
-The decomposition of applications into discrete services began with Service Oriented Architecture (SOA). Often based on legacy monolithic applications, a SOA-based service typically contains a large amount of tightly coupled code with complex dependencies. The size and complexity requires extensive planning, development, and testing to add and deploy new features. This is counter to the concept of agility. Agility is the ability to rapidly develop and deploy new and updated application functions to meet user expectations. Instead of introducing new and updated functionality once or twice a year, many organizations that embrace the DevOps concept are able to deploy daily. For DevOps to be effective, code must decomposed into small, loosely coupled services, each of which can be developed and maintained by a small, tight-knit, group of developers who have a thorough understanding of the code.
-
-The emerging architectural concept to meet this need is the concept of "microservices" [\[8\]](5_References.md). A system based on the Microservices Architecture (MSA) pattern should be comprised of a set of microservices, each of which has a single responsibility that it should perform it really well. Not all microservices are necessarily small---trying to decompose a service in which the code is both tightly coupled and highly cohesive will do more harm than good---but they each should have a well-defined purpose. To ensure that microservices are as loosely coupled as possible, microservices should not share files or databases -- all sharing of information is via network interfaces. For example, a single microservice may be responsible for a database and receives requests to create, read, update, or delete ("CRUD") data in the database via service requests over the network.
-
-The traditional concept of an "application" may no longer be applicable in an enterprise environment; instead, microservices may be mixed and matched as needed to meet an organization's specific operational and business requirements. A high-level view of the microservice architecture is shown in Figure 2‑5 [\[4\]](5_References.md).
-
-![Figure 2-5](../media/image6.png)
-_Figure 2‑5 Microservices Architecture (MSA)_
-
-With orchestration, a single orchestrator [^2] "conducts" the microservices, telling them what to do and when. Each microservice responds to requests in a synchronous manner and has no knowledge of the larger business process in which it is participating. With choreography, microservices are aware of the business processes of which they are a part. In an event-driven choreography scheme [\[9\]](5_References.md), when a microservice completes a step in a business process, it posts an asynchronous event. At that point, the next microservice in the business process detects the event, performs its step, and posts another event. Both orchestration and choreography allow steps to be performed in parallel. A decentralized asynchronous approach generally provides looser coupling (which better supports small independent DevOps teams) but has poor or no support for transactions. If a transaction cannot be completed for any reason, the microservices must coordinate with each other to identify and resolve any inconsistencies rather than relying on a centralized, synchronous orchestrator to implement a two-phase commit (2PC) protocol [\[10\]](5_References.md). The end user may also be actively involved in ensuring the consistency and integrity of all services and their associated databases. In practice, an MSA-based system is likely use a combination of choreography and orchestration with one or more microservices performing orchestration functions (i.e., there is no dedicated orchestrator typically present in a traditional SOA).
-
-As a relatively new concept, there is no single formal definition of a microservice, but industry consensus is that microservices should be stateless and not share access to persistent data stores. Any required state information is exchanged over the network via APIs, and any access to a shared data store should also be via an API call to the microservice responsible for the data stored.
-
-The proliferation of small services that result from a microservices architecture results in a number of security challenges that must be addressed. These challenges are not fundamentally different from those encountered with a traditional SOA but, as microservices increase the attack surface [^3], any vulnerabilities in the security solution are likely to be amplified. In monolithic and service-oriented architectures, communication among software components is mostly internal. With a microservices architecture, much of this communication is now external using a multitude of potentially vulnerable APIs. Additionally, a microservices deployment is likely to rely on a wider range of operating systems and programming languages, each with its unique set of security vulnerabilities. A final problem is that microservices result in a lot of network traffic and may result in poor response times due to bandwidth constraints and increased latency.
-
-The upside of a microservice approach is that security updates to microservices can be deployed more rapidly than can occur for monolithic services with complex code dependencies. The latter generally need regressive extensive testing prior to being deployed. As release cycles for services are counted in months, rather than days or weeks for microservices, vulnerabilities can remain in the production environment for considerable periods of time. Being small and highly cohesive, microservices are easier to evaluate from a security perspective than monolithic services.
-
-### 2.5.1 The Ten Commandments of Microservices
-
-The following table outlines the ten (10) important guidelines for developing and deploying microservices as defined by the New Stack [\[11\]](5_References.md).
-
-**1** - **Clean Separation of Stateless and Stateful Services**
-
-Applications composed of microservices contain both stateless and stateful services. It is important to understand the constraints and limitations of implementing stateful services. If a service relies on the state, it should be separated into a dedicated container that's easily accessible.
+CIS Docker Benchmark where possible. Running these flags harden the Docker engine and kubernetes Master and Workers (API Server and nodes) based on the [NIST Special Publication 800-190](https://doi.org/10.6028/NIST.SP.800-190). A matrix has been developed that provides a mapping of controls and container components in the [_Security Controls Mapping to Docker and Kubernetes_](https://www.gcpedia.gc.ca/gcwiki/images/4/48/Security_Controls_Mapping_to_Docker_and_Kubernetes.xlsx) document and provides specific flags as well as open-source tools to assist with compliance.
-One of the key advantages of microservices is the ability to scale rapidly. Like other distributed computing architectures, microservices scale better when they are stateless. Within seconds, multiple containers can be launched across multiple hosts. Each container running the service is autonomous and doesn't acknowledge the presence of other services. This makes it possible to precisely scale the required service instead of scaling the VMs. For this pattern to work seamlessly, services should be stateless. Containers are ephemeral and thus, become an ideal choice for microservices.
+Container technology adds complexity but also offers security benefits. The CIS Docker Benchmark provides best practices for hardening Docker and Kubernetes while leveraging tools like Security Controls Mapping document.
-A microservices-based application may contain stateful services in the form of a relational database management system (RDBMS), NoSQL databases, and file systems. They are packaged as containers with unique attributes. Typically, stateful services offload persistence to the host, which makes it difficult to port containers from one host to another. Technologies, such as Flocker and Docker volume plugins, address this problem by creating a separate persistence layer that's not host-dependent.
+It is important to note that attackers may target container orchestration services and vulnerabilities can exist in the base OS.
-Typically, stateful services offload persistence to the host or use highly available cloud data stores to provide a persistence layer. Both approaches introduce complications: offloading to the host makes it difficult to port containers from one host to another, and highly available data stores trade consistency for availability, meaning that we have to design for eventual consistency in our data model.
+| Consideration | Description |
+| ----- | ----------- |
+| **Hardening Docker Engine** | Implement CIS Docker Benchmark flags for improved security.|
+| **Patching Base OS** | Patching the base OS can secure all containers running on it. |
+| **Container-Specific Host OS** | Consider using CoreOS, RancherOS, etc. for smaller attack surface and easier management.|
+| **Immutable Root Filesystems** | Leverage immutable root filesystems for easier rollback and consistent state. |
+| **Signing Images** | Use labels, tags, and not LATEST to ensure image integrity. |
+| **Dockerfile Best Practices** | Use general Dockerfile best practices to reduce image size and complexity. |
+| **Cryptographic Signing** | Use cryptographic signing to ensure image integrity. |
-Technologies, such as Flocker, help address the host portability problem by creating a separate persistence layer that's not host-dependent. The new cloud datastores, such as Redis, Cassandra, and IBM's Cloudant, maximize availability with minimal delay on consistency.
+Container security requires a multi-layered approach, leveraging CIS benchmarks, patching, and container-specific OS features.
-As container technologies evolve, it will become easier to tackle the stateful services problem.
-
-**2** - **Do Not Share Libraries or SDKs**
-
-The premise of microservices is based on autonomous and fine-grained units of code that do one thing and one thing only. This is closely aligned with the principle of "don't repeat yourself" (DRY), which states that every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
-
-Every service is a self-contained unit of OS, runtime, framework, third-party libraries and code. When one or more containers rely on the same library, it may be tempting to share the dependencies by centrally configuring them on the host. This model introduces complexities in the long run. It not only it brings host affinity, but also breaks the CI/CD pipeline. Upgrading the library or SDK might end up breaking a service. Each service should be treated entirely independent of others.
-
-In some scenarios, the commonly used libraries and SDKs can be moved to a dedicated service that can be managed independently, making the service immutable.
-
-**3** - **Avoid Host Affinity**
-
-This point was briefly discussed in the context of shared libraries. No assumptions can be made about the host on which the service would run. The host includes the presence of a directory, IP address, port number, a specific distribution and version of the OS, and availability of specific files, libraries and SDKs.
-
-Each service can be launched on any available host in the cluster that meets the predefined requirements. These requirements are more aligned with the specifications, like the CPU type, storage type, region and availability zone, rather than the software configuration. Services should function independently of the host on which they are deployed.
-
-In case of stateful services, a dedicated persistent (data volume) container should be considered.
-
-**4** - **Focus on Services with One Task in Mind**
-
-Each service must be designed with one task in mind. It may map to one function or a module with a well-defined boundary. This means that there may also be one process per container, but that's not always the case.
-
-Docker encourages the pattern of running one background process/daemon per container. This makes containers fundamentally different from VMs. While a virtual machine may run the whole stack, a container owns a subset of the stack. For example, when refactoring a LAMP web application for microservices, the web tier with Apache runs in a dedicated container while MySQL moves to another container.
-
-Microservices are modular, composable and fine-grained units that do one thing and one thing only.
-
-**5** - **Use a Lightweight Messaging Protocol for Communication**
-
-There is no hard-and-fast rule on how microservices talk to each other. They can use synchronous or asynchronous channels with any protocol that's platform agnostic. Each service implements a simple request and response mechanism. It's common for microservices to expose well-known HTTP endpoints that can be invoked through REST API calls.
-
-While HTTP and REST are preferred for synchronous communication, it's becoming increasingly popular to use asynchronous communication between microservices. Many consider the Advanced Message Queuing Protocol (AMQP) standard as the preferred protocol, in this regard. Developing microservices with an asynchronous communication model, while sometimes a little more complex, can have great advantages in terms of minimizing latency and enabling event-driven interactions with applications.
-
-In the market today, RabbitMQ and Apache Kafka are both commonly used message bus technologies for asynchronous communication between microservices. Also, if the message-passing is done on the same host, then the containers can communicate with each other by way of system calls, as they all share the same kernel.
-
-**6** - **Design a Well-Defined Entry Point and Exit Point**
-
-In most cases, microservices are treated like a black box, with less visibility into the actual implementation. With inconsistent entry points and exit points, it will be a nightmare to develop a composed application.
-
-Similar to the interface definition in COM and CORBA, microservices should expose a well-defined, well-documented contract. This will enable services to seamlessly talk to each other.
+## 2.5 Microservices
-Even if a microservice is not expected to return an explicit value, it may be important to send the success/failure flag. Implementing a single exit point makes it easy to debug and maintain the code.
+For DevOps to be effective, code must decomposed into small, loosely coupled services, each of which can be developed and maintained by a small, tight-knit, group of developers who have a thorough understanding of the code and the domain.
-**7** - **Implement a Self-Registration and Discovery Mechanism**
+A system based on the Microservices Architecture (MSA) pattern should be comprised of a set of microservices, each of which has a single responsibility that it should perform it reliably, and effectively.
-One of the key aspects of microservices is the discovery of a service by the consumer. A central registry is maintained for looking up all available services.
+The following is a summary of the _**10 Microservices Design Principles That Every Developer Should Know**_ [found here](https://www.geeksforgeeks.org/10-microservices-design-principles-that-every-developer-should-know/):
-Each microservice handles registration within the central service registry. They typically register during the startup and periodically update the registry with current information. When the microservice gets terminated, it needs to be unregistered from the registry. The registry plays a critical role in orchestrating microservices.
+| MSA Feature | Description |
+| --- | --- |
+| **Independent and Autonomous Services** | Each microservice operates independently without relying on other services. This allows each service to be developed, tested, and deployed independently without affecting other parts of the system. |
+| **API Aggregation** | Microservices communicate with each other through well-defined APIs. This enables communication between services written in different programming languages. |
+| **Flexibility** | Microservices can be easily changed or adapted to new circumstances or requirements. This makes projects more adaptable to future changes. |
+| **Scalability** | Microservices can be modified to handle increasing or decreasing traffic, data, and complexity without impacting performance. This can be achieved through techniques such as service partitioning, load balancing, horizontal scaling, and caching. |
+| **Constant Monitoring** | Constant monitoring helps to identify and resolve issues quickly in a complex system with multiple microservices. This can be achieved through methods such as logging and metrics, distributed tracing, health checks, and alerting and notifications. |
+| **Failure Isolation/Failure Resilience** | Microservices are designed to minimize the impact of failures. This can be achieved through fault-tolerant approaches, such as redundancy, service separation, graceful degradation, and circuit breakers. |
+| **Realtime Load Balancing** | A load balancer distributes requests across multiple microservices in real-time, ensuring that client requests are handled quickly and efficiently. |
+| **Inclusion of DevSecOps** | DevSecOps promotes communication, collaboration, and automation between development, operations teams, and security teams. This improves the efficiency and effectiveness of the software development process, leading to greater speed, flexibility, and agility. Common DevSecOps tools used with microservices include Docker, Terraform, and Kubernetes. |
+| **Versioning** | Versioning manages changes and updates to services over time. This minimizes disruptions to existing clients and ensures compatibility with the latest technologies. |
+| **Availability** | Microservices are designed to be available 24/7 or for the maximum amount of time possible, minimizing downtime. |
-Consul, etcd and Apache Zookeeper are examples of commonly used registries for microservices. Netflix Eureka is another popular registry that exposes registration APIs to services for registering and unregistering.
+The traditional concept of an "application" may no longer be applicable in an enterprise environment; instead, microservices may be mixed and matched as needed to meet an organization's specific operational and business requirements. A high-level view of the microservice architecture is shown in [Figure 2‑5](#figure-2-5).
-**8** - **Explicitly Check for Rules and Constraints**
+
-During deployment, microservices may need to consider special requirements and constraints that impact performance. For example, the in-memory cache service needs to be on the same host as the web API service. The database microservice may have to be deployed on a host with solid-state drive (SSD) storage. The master and slave containers of the database cannot exist on the same host. These constraints are typically identified during the design of the services.
+![Figure 2-5](../media/image_6.png)
+_Figure 2‑5 Microservices Architecture (MSA)_
-If rules and constraints are not considered by the SysOps team, services may need to raise alerts or log appropriate messages warning about possible implications and side effects. Under extreme conditions, a microservice may have to shut down if the mandatory rule is not respected at deployment
+## 2.6 Orchestration and Choreography
-**9** - **Prefer Polyglot Over Single Stack**
+The following is a set of features of container orchestration and choreography:
-One advantage of using microservices is the ability to choose the best of breed OS, languages, runtimes and libraries. For example, the chat microservice can be implemented in Node.js, exposing the websockets; the web API service can be written in Python and Django; the image manipulation service may be in Java; and the web frontend could be implemented with Ruby on Rails.
+| Feature | Description |
+| --- | --- |
+| **Orchestration** | A central orchestrator directs microservices, dictating their actions and timing. Each microservice functions synchronously, unaware of the broader business process it contributes to. |
+| **Choreography** | In choreography, microservices possess an understanding of the encompassing business processes they participate in. |
+| **Service Mesh** | A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It provides a way to control how different parts of an application share data with one another. |
-As long as each service exposes a well-defined interface that's consistent with other services, it can be implemented using the most optimal technology stack.
+### Challenges
-With Microsoft adding native container support to Windows, it is also possible to mix and match Linux containers with Win32 and .NET containers within the same environment.
+The proliferation of small services that result from a microservices architecture results in a number of security challenges that must be addressed.
-**10** - **Maintain Independent Revisions and Build Environments**
+| Challenge | Description |
+| --- | --- |
+| **Increased Attack Surface** | Microservices increase the attack surface, amplifying any vulnerabilities in the security solution. |
+| **External Communication** | Microservices rely on external communication using a multitude of potentially vulnerable APIs. |
+| **Diverse OSs and Programming Languages** | Microservices deployments rely on a wide range of OSs and programming languages, each with unique security vulnerabilities. |
+| **Network Traffic** | Microservices result in a lot of network traffic, which may result in poor response times due to bandwidth constraints and increased latency. |
-Another benefit of microservices is the ability to code and maintain each service independently.
+### Benefits
-Though each microservice is part of a large, composite application, from a developer standpoint, it is important to treat each service as an independent unit of code. Each service needs to be versioned and maintained separately in the source code control system. This makes it possible to deploy newer versions of services without disrupting the application. CI/CD pipelines should be designed to take advantage of the independent versioning.
+Some upsides of a microservice approach include:
-This mechanism makes it possible to implement blue/green testing of each service before rolling out the production version.
+| Upside | Description |
+| --- | --- |
+| **Rapid Security Updates** | Security updates to microservices can be deployed more rapidly than for monolithic services with complex code dependencies. |
+| **Easier Evaluation** | Microservices are easier to evaluate from a security perspective than monolithic services. |
### 2.5.2 Service Mesh
-Microservices introduce new components, workflow and process into a team, and organizations deploying them soon realize they require new methods and tools for security, observability and management. This most often includes the implementation of a service mesh, with circuit breaking, service registry and discovery; debugging, tracing, logging; metrics collection; authentication; network separation and others. [Istio](https://istio.io/), [Conduit](https://conduit.io/) and/or application platform load balancers (such as [NGINX](https://www.nginx.com/)) implement some or all of these features.
-
-A recent example with Istio deployed as a 'sidecar' in Kubernetes, supporting policy based networking.
-
-![BookInfo-v1-Istio (5).png](../media/image7.png)
+A service mesh is an infrastructure layer in your application that facilitates communication between services. Service meshes provide capabilities like traffic management, resiliency, policy, security, strong identity, and observability to your workloads. Your application is decoupled from these operational capabilities, while the service mesh moves them out of the application layer and down to the infrastructure layer.
-_Figure 2‑6 Example service mesh (CNCF Project Istio) [\[12\]](5_References.md)_
+| Feature | Description |
+| --- | --- |
+| **Circuit Breaking** | Circuit breaking is a design pattern used in modern software development to detect failures and encapsulate the logic of preventing a failure from constantly recurring. |
+| **Service Registry and Discovery** | Service registry and discovery are used to manage the location of services and the ability to discover them. |
+| **Debugging, Tracing, Logging** | Debugging, tracing, and logging are used to monitor and troubleshoot microservices. |
+| **Metrics Collection** | Metrics collection is used to collect and analyze data on the performance of microservices. |
+| **Authentication** | Authentication is used to verify the identity of users and services. |
+| **Network Separation** | Network separation is used to separate the network traffic of different services. |
-Functions of a service mesh:
+Functions of a service mesh include:
- Automatic mutual TLS between services
- Service-level RBAC
@@ -206,25 +158,25 @@ Functions of a service mesh:
## 2.6 Functions as a Service
-Functions as a service (FaaS) sometimes referred to as event-driven architecture or even serverless is a relatively recent architectural principle found in microservices. Initially FaaS was a piece of code uploaded to run on specific CSP compute engines (i.e. AWS Lambda, Azure Functions, etc.) without any consideration for infrastructure. Serverless has evolved to describe managed containers since the build pipeline does not specify or manage the compute where the container runs. Event-driven architectures sometimes trigger a chain of serverless events, all requiring the application of controls to reduce risk.
+Functions as a service (FaaS) sometimes referred to as event-driven architecture or even serverless is a relatively recent architectural principle for serving microservices.
-Since an event-driven instance does not exist until invoked, serverless changes IT management, monitoring and requirements in a number of ways:
+Since an event-driven compute instance, such as in FaaS, does not exist until invoked, it changes IT management, monitoring, and requirements in a number of ways:
-- Security (ensure integrity of code, IAM polices, monitoring, forensics)
-- Build pipelines immature (CI/CD)
+- Security (ensuring integrity of code, IAM polices, monitoring, forensics)
+- Build pipelines (CI/CD)
- Administration (patching, deployment)
- Architecture (new architectural constructs)
-- Lock-in (currently different standards and interoperability between CSP's)
-
-Security for pure serverless functions are mostly centered on the classification of code and IAM policies and protection for data at rest, since the functions are dormant until executed. Once running, the zoning and access controls can be applied by IAM, CSP policy and third party security brokers. As serverless functions mature, they will be able to inherit controls from the CSP compliance reports.
-
-Practical considerations for securing serverless functions while invoked include IAM policies, security groups, use of security brokers (third-party and CSP) and authentication, authorization and integrity checking.
-
-For container-based 'serverless' deploys, container security brokers provide a set of protections for container-as-a-service (CaaS) environments such as Microsoft's Azure Container Instances (ACI), Amazon EC2 Container Service (ECS), Amazon Web Services' Fargate --- through a set of runtime security policies implemented by the CSP or container security brokers.
-Protecting serverless functions and containers in a managed container service requires a security perimeter built by resource group, a container frontend and a 'microenforcer' embedded as an additional layer in the image. The microenforcer accompanies the image during shipping to repositories and third-party hosted environment; and protects the containers upon launch.
+The following are some of the key features of FaaS:
-Overall toolchains for creating and deploying serverless functions are also improving, for example AWS now contains [AWS Serverless Application Repository](https://aws.amazon.com/serverless/serverlessrepo/). Kubernetes always provided a 'serverless' deployment experience and now allows for virtual kubelets for various managed container services.
+| Feature | Description |
+| --- | --- |
+| **Security for Serverless Functions** | Security for serverless functions use centers on code classification, IAM policies, and data-at-rest protection because the functions remain inactive until executed.
Active functions use zoning and access controls implemented through IAM, CSP policy, and external security brokers. As they evolve, serverless functions will receive controls from CSP compliance reports. |
+| **Security for Invoked Serverless Functions** | Securing serverless functions involves considerations such as IAM policies, security groups, third-party and CSP-provided security brokers, and authentication, authorization, and integrity checks. |
+| **Function-Based Serverless Deployment** | Function-based serverless deployments are fully managed by the CSP. Examples include [Azure Functions](https://azure.microsoft.com/en-us/services/functions), [AWS Lambda](https://aws.amazon.com/lambda), and [Google Cloud Functions](https://cloud.google.com/functions). |
+| **Container-Based Serverless Deployments** | Container security brokers offer protections for containers as a service (CaaS) environments. Examples include [Microsoft's Azure Containers Instances (ACI)](https://azure.microsoft.com/en-us/products/container-instances), [AWS Fargate](https://aws.amazon.com/fargate/), and [Google Cloud Run](https://cloud.google.com/run). Protection comes from runtime security policies enforced by either the CSP or container security brokers. |
+| **Securing Functions and Containers in Managed Services** | Safeguarding requires a security perimeter constructed using a resource group, a container frontend, and container image cryptographic signing. |
+| **Toolchains for Serverless Functions** | New capabilities to simplify the FaaS deployment model are being introduced frequently. Testing frameworks, dependency and vulnerability scanning, deployment, and infrastructure as code (IaC) are all part of these toolchains.|
Regardless of deployment method, runtime monitoring is required for:
@@ -232,3 +184,4 @@ Regardless of deployment method, runtime monitoring is required for:
- Remediation of a potential threat, for example, via container isolation on a different network, pausing the container, or restarting it
- Forensics to identify the event, based on detailed logs and the containers' image during the event
- Run-time policies and isolation, limiting what kinds of behaviour are allowed in your environment
+- Vulnerability and dependency scanning, to ensure that the container is not running with known vulnerabilities
diff --git a/en/3_Threat-Environment.md b/en/3_Threat-Environment.md
index 410b5d4..bf48688 100644
--- a/en/3_Threat-Environment.md
+++ b/en/3_Threat-Environment.md
@@ -2,16 +2,26 @@
([Back](../README.md))
-Cloud native applications based on containers and microservices have vulnerability and attack vectors that need to be mitigated. Container and container orchestrators inherit typical IT vulnerabilities as well as introduce some of their own, especially if containers are started with escalated privileges:
+Cloud native applications based on containers and microservices have vulnerability and attack vectors that need to be mitigated. Container and container orchestrators inherit typical IT vulnerabilities as well as introduce some of their own, especially if containers are started with escalated privileges. The following is a list of potential threats to a containerized environment:
-- **Container Compromise**: An application misconfiguration or vulnerability enables the attacker to get into a container to start probing for weaknesses in the network, process controls, or file system. Compromised containers may then contain 'typical' IT vulnerabilities:
- - Application level DDOS and XSS against public facing containers
- - EXEC level download of malware, running a malicious process
- - Scan of other internal systems for weaknesses or sensitive data
- - Breakout and unauthorized access across containers, hosts or data centers
- - Resource hogging to impact or crash other containers
-- **Unauthorized connections between pods**: Compromised containers can attempt to connect with other pods on the same or other hosts to launch an attack.
-- **Data exfiltration from a pod**: Stealing data from a pod; for example reverse shell in a pod for network tunneling to hide confidential data.
-- **Container, Pod or Node compromise**: If the pod host is compromised, a user may escalate to root privilege. An attacker (or developer) can install vulnerable libraries/packages that allow exploits in a container
-- **Resource Compromise**: Attempt to compromise Kubernetes resources such as the API Server or kubelets to disrupt the cluster or gain access to secrets, resources, or containers. Potential kubernetes resources include authorization tokens, identities or secrets that could be used to gain unauthorized access. Bad actors could also disrupt running applications and or try to gain control of the underlying resources used to run containers or privilege escalation (via the kubelet, access to etcd or service tokens).
-- **Attack Kill Chain**: When a series of malicious activities are used together, often within minutes, to achieve the attackers goal [\[13\]](5_References.md).
+| Threat | Description |
+| --- | --- |
+| **Container Compromise** | An attacker can exploit application vulnerabilities or misconfigurations to gain unauthorized access to a container. Once inside, they may:
Launch application-level attacks like DDoS or XSS against public-facing containers.
Execute malicious code or malware.
Scan the network for vulnerabilities and sensitive data.
Break out of the container to access the host system or other containers.
Consume excessive resources to disrupt other containers.
|
+| **Lateral Movement** | Compromised containers can attempt to communicate with other containers or nodes within the cluster to spread the attack. |
+| **Data Exfiltration** | Attackers can steal sensitive data from containers, often using techniques like reverse shells or covert channels. |
+| **Host Compromise** | If the host system is compromised, an attacker can gain access to all containers running on that host, potentially escalating privileges. |
+| **Kubernetes API Server and Kubelet Attacks** | Attackers may target the Kubernetes API server or kubelets to disrupt the cluster or gain unauthorized access to secrets, resources, or containers. |
+| **Supply Chain Attacks** | Malicious actors can introduce vulnerabilities into the software supply chain, compromising images, libraries, or dependencies. |
+
+## Additional Considerations
+
+In addition to the threats listed above, organizations should consider the following security aspects when deploying containerized environments:
+
+| Consideration | Description |
+| --- | --- |
+| **Image Security** | Ensuring the security of container images, including scanning for vulnerabilities and using trusted registries. |
+| **Network Security** | Implementing network segmentation, firewalls, and intrusion detection systems to protect container networks. |
+| **Identity and Access Management** | Controlling access to Kubernetes resources and enforcing least privilege principles. |
+| **Monitoring and Logging** | Continuously monitoring container environments for suspicious activity and maintaining detailed logs for forensic analysis. |
+| **Incident Response Planning** | Developing a robust incident response plan to quickly detect, contain, and remediate security incidents. |
+| **Compliance and Auditing** | Ensuring that containerized environments comply with relevant security standards and regulations and conducting regular audits to verify compliance. |
diff --git a/en/4_Implementation-Recommendations.md b/en/4_Implementation-Recommendations.md
index 9ce1143..2bb566f 100644
--- a/en/4_Implementation-Recommendations.md
+++ b/en/4_Implementation-Recommendations.md
@@ -8,64 +8,86 @@ The following are general recommendations for securing containers and Kubernetes
The following are recommendations for securing the host:
-1. Run docker engine with flags per [CIS Docker Community Edition Benchmark](https://www.cisecurity.org/benchmark/docker/): v1.1.0 and NIST Special Publication 800-190 [\[6\]](5_References.md).
-2. Check for compliance by running [docker-bench](https://github.com/docker/docker-bench-security) against the host. Flags can also be found in the _Security Controls Mapping to Docker and Kubernetes_ document available on GCpedia.
-3. Other high-level recommendations for hosts include:
- - Enabling AppArmour or SeLinux on hosts (per host instructions)
- - OWASP Version control Package testing
- - Vulnerability checking (based on CVE scores, scanned in dev, CI/CD, prod)
- - Control parameters (flags)
- - Use linux namespaces
- - Utilize Seccomp/seccomp-bpf [^4]
- - Configure Cgroups
- - Use R/O Mounts
- - Update host patches
- - Run CIS Benchmark security tests [\[14\]](5_References.md)
+1. Run docker engine with flags per [CIS Docker Community Edition Benchmark](https://www.cisecurity.org/benchmark/docker/) and [NIST Special Publication 800-190](https://doi.org/10.6028/NIST.SP.800-190).
+2. Check for compliance by running tools like [docker-bench](https://github.com/docker/docker-bench-security) against the host. Recommended flags and settings can also be found in the [_Security Controls Mapping to Docker and Kubernetes_](https://www.gcpedia.gc.ca/gcwiki/images/4/48/Security_Controls_Mapping_to_Docker_and_Kubernetes.xlsx) document available on GCpedia.
+
+3. While the benchmarks are the primary reference, consider these additional security best practices:
+
+| Best Practice | Description |
+| --- | --- |
+| **Container Runtime Security** |
Enable security features like [`AppArmor`](https://www.apparmor.net/) or `SELinux` on your containers for additional protection.
|
+| **Software Supply Chain Security** |
Implement vulnerability scanning of container images in development, CI/CD pipelines, and production environments.
Use trusted container registries and consider signing your container images.
|
+| **Network Security** |
Implement network segmentation, firewalls, and intrusion detection systems (IDS) to protect container networks.
|
+| **Least Privilege** |
Enforce the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) by granting containers only the minimum permissions they require to function.
|
+| **Monitoring and Logging** |
Continuously monitor your container environment for suspicious activity and maintain detailed logs for forensic analysis.
|
+
+By embracing established security benchmarks and implementing best practices, you can significantly enhance the security posture of your containerized applications and Kubernetes deployments.
## 4.2 Image Builds
-Containers are comprised of layered images specified in a Dockerfile, which includes a base OS, libraries and dependencies. Since vulnerabilities can be introduced at each layer of the image, containers should be as minimal as possible, with all components from trusted sources (provenance).
+Containers are comprised of layered images specified in a `Dockerfile`, which includes a base OS, libraries, and dependencies. Since vulnerabilities can be introduced at each layer of the image, containers should be as minimal as possible, with all components from trusted sources (provenance).
-This starts by using trusted and optimized images with no (major) CVE vulnerabilities; and using only trusted versions and registries (trusted dependences, signed images, secure and trusted registries). For some builds (i.e. FROM golang), consider a multi-stage build to reduce size, unnecessary libraries and vulnerabilities.
+This starts by using trusted and optimized images with no (major) CVE vulnerabilities; and using only trusted versions and registries (trusted dependencies, signed images, secure and trusted registries). For some builds (i.e. `FROM golang`), consider a multi-stage build to reduce size, unnecessary libraries, and vulnerabilities.
-Organizations should evolve established processes to better fit containerized application build and deployment. A sample of specific image build considerations include:
+Organizations should evolve established processes to better fit containerized application build and deployment.
-- Use a non-root user inside containers
-- Use a minimal Host OS (or multi-stage build)
-- Replace rather than patch containers (immutability)
-- Make the filesystem read-only
-- Use Labels, Tags, (Not LATEST)
-- General Dockerfile best practices (such as specifying commands in the same line to reduce layers in image)
+A sample of specific image build considerations include:
-## 4.3 Container Security Brokers
+| Consideration | Description |
+| --- | --- |
+| **Hardening** |
Harden the Docker engine by implementing CIS Docker Benchmark flags for improved security.
|
+| **Patching Base OS** |
Can secure all containers running on the same host.
|
+| **Container-specific Host OS** |
Consider using a container-specific Host OS like [CoreOS](https://fedoraproject.org/coreos/), [RancherOS](https://rancher.com/docs/os/v1.x/en/), etc. for a smaller attack surface and easier management.
|
+| **Labels, Tags, (Not LATEST)** |
Use labels and tags to identify the image and version.
Use [semantic versioning](https://semver.org/) (e.g. `v1.0.0`).
Don't use `latest`.
|
+| **Cryptographic Signing** |
Use cryptographic signing for image verification.
|
+| **Best Practices** |
Follow general `Dockerfile` best practices (such as specifying commands in the same line to reduce layers in image)
|
-Container security brokers can help automate compliance checking, logging, access control and other functions for each step of the container lifecycle. Container security brokers (CSB) test and verify images, reduce risk exposure; provide trust, integrity, assurance; resource and access control; protect processes and network access and secrets. Container Security Brokers/Firewalls, such as [Cloudvisory](https://www.cloudvisory.com/), [NeuVector](https://neuvector.com/), [Twistlock](https://www.twistlock.com/), [Alcide](https://www.alcide.io/), [Sonatype,](https://www.sonatype.com/) [Aqua](https://www.aquasec.com/) can implement the following configurations [\[15\]](5_References.md) on hosted, managed and even CSP-provided services:
+## 4.3 Container Deployment Security
-- Prevent unknown images (image provenance)
-- Scan images by CVEs and score (blacklist/whitelist)
-- Stop user privilege escalation (run as non-root)
-- Scan for bad config and hard-coded secrets (keys)
-- Stop suspicious processes
-- Control capabilities/image fingerprinting (TLS, trusted images, signing)
-- Enforce network isolation (by policies, namespaces, RBAC, service mesh)
-- Protect the host resources
-- Encrypt sensitive variables
-- Enforce use of automation tools
-- Visibility across the environment (CI/CD embedded testing)
-- Feedback/logging
+Container deployment can introduce security risks if not properly managed. To mitigate these risks, organizations should consider the following best practices:
+
+| Best Practice | Description |
+| --- | --- |
+| **Use a Container Registry** |
Use a private registry to control access to images.
Use a container registry that supports TLS to encrypt data in transit.
Use IAM to control access to the registry.
|
+| **Use Cryptographically Signed Images** |
Use cryptographically signed images to verify the integrity and authenticity of the image.
|
+| **Use CI/CD Pipelines** |
automate the build, test, and deployment of containerized applications.
Scan images for vulnerabilities and secrets.
Use automated testing to validate the functionality of the application.
Use infrastructure as code (IaC) to define the configuration of the containerized application.
Use automation tools to deploy containers to the target environment.
Use version control to manage changes to the configuration files.
|
+| **Use Secrets Management Tools** |
Use secrets management tools to securely store and manage sensitive information like passwords, API keys, and certificates.
|
+| **Use Monitoring and Logging Tools** |
Use monitoring and logging tools to track the performance and security of containerized applications.
|
## 4.4 Orchestration - Kubernetes
-Specific flags for hardening Kubernetes can be found in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/): v1.2.0. Open source tools to verify configuration and compliance to CIS Benchmark include and [kube-bench](https://github.com/aquasecurity/kube-bench) and [kubsec.io](https://kubesec.io/).
+Kubernetes is a popular container orchestration tool that automates the deployment, scaling, and management of containerized applications. Kubernetes provides a rich set of features for securing containerized applications.
+
+The benefits of Kubernetes include:
+
+| Benefit | Description |
+| --- | --- |
+| **Scalability** | Can scale applications horizontally and vertically to meet demand. |
+| **High Availability** | Can automatically restart failed containers and reschedule them on healthy nodes. |
+| **Resource Management** | Can manage resources like CPU and memory to ensure that applications run efficiently. |
+| **Service Discovery** | Provides a built-in service discovery mechanism that allows applications to communicate with each other. |
+| **Load Balancing** | Can distribute incoming traffic across multiple instances of an application to ensure high availability. |
+| **Rolling Updates** | Can perform rolling updates of applications to minimize downtime. |
+| **Monitoring and Logging** | Provides built-in monitoring and logging capabilities to track the performance and security of applications. |
+| **Security** | Provides a rich set of security features to protect containerized applications. |
+| **Portability** | Cloud-agnostic and can run on any cloud provider or on-premises infrastructure. |
+
+Although Kubernetes provides many benefits, it also introduces new security challenges. The configuration and management of Clusters require careful attention to ensure that they are secure.
+
+> **Note:** Where possible, it is recommended to use a managed Kubernetes service from a cloud provider, as they often provide additional security features and manage the underlying infrastructure for you.
+> This eliminates the need to manage the Control plane and ensures that the cluster is always up to date with the latest security patches.
+
+When managing your own Cluster, it is important to follow best practices for securing the cluster. Specific flags for hardening Can be found in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/). Open source tools to verify configuration and compliance to CIS Benchmark include and [kube-bench](https://github.com/aquasecurity/kube-bench) and [kubsec.io](https://kubesec.io/).
-As the number of containers in organizations increases, DevSecOps teams recognizing the need for orchestration and day 2 management are increasingly turning to Kubernetes. High-level recommendations and best practices for securing Kubernetes include:
+Regardless of style (Managed or self-managed), high-level recommendations and best practices for securing Kubernetes include:
-- **TLS Everywhere**: Components and installation methods may enable local ports over HTTPS and administrators should familiarize themselves with the settings of each component to identify potentially unsecured traffic
-- **Identity, authorization and authentication**: Through role-based access control, applying identity and access management and restricted access to elevated privileges; permissions on volumes, networks etc. using role and attribute access control; using and securing 'etcd' for storing secrets; disable legacy authorization; rotate keys. Specific tools include JSON Web Tokens and now [SPIFFE](https://spiffe.io/) (spire)
-- **Kubernetes\' secrets** [\[16\]](5_References.md) **feature** ensures that all sensitive information \-- such as passwords, OAuth tokens and Secure Shell keys \-- are encrypted and made available to each Pod only when they are required for a particular task. The secrets feature uses the principle of least privilege to ensure the sensitive data isn\'t inadvertently shared externally or with a user or application that doesn\'t need access to it.
-- **Logging and telemetry**: Includes audit trail and use of application monitoring tools built for cloud native environments.
-- **Networking**: Use network policies to segment communication between containers or pods: for example to specify with whom a pods or endpoints can communicate. Resources to help implement kubernetes network policy include:
- - [Tutorials and Recipes for Kubernetes Network Policies feature](https://github.com/ahmetb/kubernetes-network-policy-recipes)
- - [Limiting Pod Communication with Network Policies](https://docs.giantswarm.io/guides/limiting-pod-communication-with-network-policies/)
+| Best Practice | Description |
+| --- | --- |
+| **TLS Everywhere** |
Components and installation methods may enable local ports over HTTPS and administrators should familiarize themselves with the settings of each component to identify potentially unsecured traffic.
|
+| **Identity, Authorization, and Authentication** |
Through role-based access control, applying identity and access management and restricted access to elevated privileges.
Permissions on volumes, networks etc. using role and attribute access control.
Using and securing 'etcd' for storing secrets.
Disable legacy authorization.
Rotate keys.
Specific tools include JSON Web Tokens (JWT) and [SPIFFE](https://spiffe.io/) (Spire).
|
+| **TLS Everywhere** |
Components and installation methods may enable local ports over HTTPS and administrators should familiarize themselves with the settings of each component to identify potentially unsecured traffic.
|
+| **Kubernetes Secrets** |
Ensures that all sensitive information -- such as passwords, `Open Authorization (OAuth)` tokens and `Secure Shell (SSH)` keys -- are encrypted and made available to each Pod only when they are required for a particular task.
|
+| **Logging and Telemetry** |
Includes audit trail and use of application monitoring tools built for cloud-native environments.
|
+| **Networking** |
Use network policies to segment communication between containers or pods: for example to specify with whom a pods or endpoints can communicate.
Resources to help implement Kubernetes network policy include:
[AWS - Limit pod traffic with Kubernetes network policies](https://docs.aws.amazon.com/eks/latest/userguide/cni-network-policy.html)
[Azure - Limit pod traffic with Kubernetes network policies](https://docs.microsoft.com/en-us/azure/aks/use-network-policies)
[GCP - Limit pod traffic with Kubernetes network policies](https://cloud.google.com/kubernetes-engine/docs/how-to/network-policy)
|
-Further details can be found in accompanying _GC Guidance for Secure Platform Deployment_ and other resources, such as the Ultimate Guide to Kubernetes Security [\[13\]](5_References.md), kubernetes.io [\[17\]](5_References.md), Exploring Container Security: An Overview [\[18\]](5_References.md) and NIST Special Publication 800-190 Application Container Security Guide [\[6\]](5_References.md).
+Further details can be found in [kubernetes.io](kubernetes.io), and [NIST Special Publication 800-190 Application Container Security Guide](https://doi.org/10.6028/NIST.SP.800-190).
diff --git a/en/5_Microservice_Security.md b/en/5_Microservice_Security.md
index 75049e2..0382938 100644
--- a/en/5_Microservice_Security.md
+++ b/en/5_Microservice_Security.md
@@ -1,17 +1,19 @@
-# 5. Additional Micro-services and Container Security Guidelines
+# 5. Additional Microservices and Container Security Guidelines
([Back](../README.md))
-The following section provides additional guidelines.
+The following section provides additional guidelines to securing your microservices and containers.
+
+There is already several guidance documents on secure application development, secure coding practices, and secure deployment practices. This document will focus on the specific security considerations for microservices and containers.
## 5.1 Securing Platform
### Multi-Tenancy
-Multi-tenancy within a single Kubernetes (K8S) cluster is one of the key
+Multi-tenancy within a single Kubernetes cluster is one of the key
drivers for digging into the security implications of different
deployment patterns. The most secure approach is to only deploy a single
-application per K8S cluster, but this becomes very inefficient in terms
+application per K8s cluster, but this becomes very inefficient in terms
of resource usage and operational maintenance of the utilized
infrastructure.
@@ -20,1480 +22,329 @@ for isolating and separating workloads, as well as best practices when
establishing your application architecture.
To get started, it is worth briefly covering the difference between a
-container runtime and traditional VM based workload isolation, as it
-illustrates the importance of some of the concepts we will cover.
-
-#### Hard Workload Isolation
-
-The most fundamental difference between containers and virtual machines
-(VMs) is related to the host, or kernel environment in which they run.
-Each VM runs its own guest operating system and as such, has its own
-kernel. In contrast, a container shares the underlying operating
-system's kernel with all of the other containers on that host.
-
-The differences between containers and VMs is well documented on the
-internet, so I am not going to rehash everything here. As a simple
-illustration, the following diagram shows the components of an
-application as it relates to either VMs or containers.
-
-![The image depicts a comparison between two sets of
-application components: VMs, and Containers. Both diagrams
- start with a large rectangle at the bottom labeleled 'Infrastructure'.
- Then, above that,a smaller rectangle labelled 'Hypervisor' on the VMs side,
- and 'Operating system' on the Containers side. Then, above that on the
- Containers side is a 'Container Engine', and then multiple sets of smaller
- rectangles above that for Bins/Lib 1 to n and above each one of those,
- corresponding 'App' 1 to n. That completes the Containers side.
- On the VMs side, instead of the Container Engine, there is 'Guest OS' 1 to
- n, and then the rest of the diagram above that is the same as the one for
- Containers, with 'Bins/Lib' and 'App' 1 to n.](../media/image_13.png)
-
-Ref:
-[https://blog.netapp.com/blogs/containers-vs-vms/](https://blog.netapp.com/blogs/containers-vs-vms/)
-
-In general, containers are preferred for their fast start and recycle
-time, and lower memory footprint on the physical host, allowing for more
-workloads to be run on the same physical infrastructure. Additionally,
-there have been massive amounts of work put into container lifecycle and
-scheduling technologies, such as Kubernetes, which make containers very
-attractive to application owners. The container landscape has exploded
-in the last few years, making for a vibrant ecosystem of vendors and
-open source technologies, all working to improve the life of developers
-and operators.
-
-In contrast, VMs follow more traditional rules as it comes to automation
-and lifecycle management, but offers security realms that are more
-widely understood.
-
-Running workloads in VMs provides the most isolation from an application
-perspective, but with a thoughtful approach, you can achieve similar
-isolation in containers through scheduling techniques, covered below.
-
-This is an area of the market which has been moving very quickly,
-exploring paths to bring together the speed of containers with the
-isolation of VMs.
-
-In addition to handling container workload isolation via scheduling and
-placement rules, a lot of innovation is currently happening around
-kernel isolation inside a container. Some technologies to watch as a way
-to illustrate the diversity of approach are; [Clear
-containers](https://lwn.net/Articles/644675/),
-[unikernels](http://unikernel.org/), [gVisor](https://gvisor.dev/),
-[KubeVirt](https://kubevirt.io/), [libvirt](https://libvirt.org/),
-[Nabla Containers](https://nabla-containers.github.io/),
-[Ignite](https://ignite.readthedocs.io/en/stable/), and MicroVMs. Ensure
-you understand the speed/isolation tradeoffs of the technologies you
-choose.
-
-In this document we'll focus on the isolation properties of the
-commonly deployed combination of docker/containerd and Kubernetes.
-
-#### Soft Workload Isolation
-
-Kubernetes provides an isolation mechanism called
-"[namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)",
-which provides basic workload separation. Namespaces allow you, through
-[resource quotas](https://kubernetes.io/docs/concepts/policy/resource-quotas/), to
-divide up the available resources in a cluster into the different user
-groups.
-
-Essentially, namespaces are a user access boundary which ensures that
-users are only able to operate on the resources within their namespace.
-This alone does not isolate workloads from each other on the physical
-hosts, only the user's ability to access the running workloads in the
-cluster. Two workloads running in different namespaces can, and will,
-run on the same physical host, the main functionality that namespaces
-offer is the ability to define the group of users who have access to
-view/modify those workloads.
-
-#### Possible Attack Vectors
-
-With traditional architectures, the attack vectors tended to be limited
-to the VMs and the services provided by those VMs. When working with
-micro-services and containers, there are additional layers of attack
-surface which are important to understand. Kubernetes offers the ability
-to distribute workloads across multiple nodes, while also offering
-platform level services such as namespace isolation and role based
-access control (RBAC). In addition, Kubernetes enables the use of a wide
-range of ecosystem provided services, such as ingress, storage,
-certificate management, service mesh, and so on. While it is important
-to understand the attack vectors associated with these ecosystem
-services, in this context, we will focus mainly on the platform
-architecture and the attack vectors associated with it.
-
-Kubernetes organizes the nodes it manages into clusters. Each node has a
-kubelet service which manages the registration of the node with the
-Kubernetes API service as well as ensuring that the pods scheduled on
-the node are healthy. The Kubernetes API service is one of the services
-which are core to the functionality of the Kubernetes control plane, as
-it manages the configurations associated with constructs such as pods,
-services, replication controllers, and so on. The Kubernetes API service
-essentially represents the shared state of the objects managed by the
-platform. While the API service represents the state, the etcd service
-is the actual storage mechanism where that state is stored and
-maintained. I am not going to get into the finer points of the
-architecture, but suffice it to say that there is a control plane which
-represents the deployed objects and the rules for how they are
-implemented on the physical infrastructure. The kubelet service runs
-locally on each node and interacts with the API service to ensure that
-objects delegated to its node are functioning correctly.
-
-Workloads running in Kubernetes are organized in Pods. Inside a pod, you
-can have one or more related containers running. The container houses
-the actual application code which delivers the expected business logic.
-Pods are organized in namespaces for separation.
-
-Now that you have a basic understanding of how the different components
-fit together, the following diagram illustrates some areas which should
-be reviewed to ensure the different components of the architecture are
-protected appropriately. Throughout this document we will introduce
-different ways to manage application scheduling and isolation to help
-you understand what placement rules your application should take into
-consideration.
-
-![The image contains an outer rectangle labelled 'Cluster', with two
-rectangles inside that, each called 'Node'. The first Node contains a
-three-dimensional disc, or low cylinder, labelled 'etcd', and a dashed-border rectangle
-labelled 'Control-plane components'. There are arrows pointing to each
-object, with additional messaging attached to each arrow: 'Access to machines/VMs' points to Node; 'Access via Kubernetes API or Proxy' points to 'Control-plane components'; 'Access to etcd API' points to 'etcd'; and 'Intercept/modify/inject control-plane traffic' points to the inside of the Control-plane components. All of the above arrows are black, except the Intercept/modify/inject arrow, which is red.
-The second Node contains a rectangle labelled 'Kubelet', and another rectangle
- labelled 'Pod'. Inside the Pod is a 'Container' rectangle, and inside that,
- an 'Application' rectangle. These objects have arromediaws as well: - 'Access via Kuelet API' is a black arrow pointing at the Kubelet rectangle; - a red arrow points from Application to some text: 'Escape container to host through vulnerability or volume mount';- another red arrow points from 'Intercept/modify/inject application traffic' to Application; and - a final, black, arrow points from 'Exploit vulnerability in application code' to Application.](../media/image_2.png) ds
-
-### Workload Scheduling & Placement
-
-Containers have dependencies among themselves, dependencies to nodes,
-and resource demands, and all of that changes over time too. The
-resources available on a cluster also vary over time, through shrinking
-or extending the cluster, or by having it consumed by already placed
-containers. The way we place containers impacts the availability,
-performance, and capacity of the distributed systems as well. This
-section covers the scheduling considerations when a workload is
-scheduled on a node and how Kubernetes manage it.
-
-#### Taints & Toleration
-
-**Taints and toleration are used to ensure that pods are not scheduled
-onto inappropriate nodes.**
+container runtime and traditional VM based workload isolation.
-One of the most common examples is to ensure that user workloads are not
-scheduled on the 'master' nodes. Taints are applied at the node level
-and the pod scheduling (toleration) will respect the applied taints.
-Taints are essentially the opposite of an affinity rule.
+### Workload Isolation
-There are a number of built in taints which are available out of the
-box.
+The following table lists the different considerations when it comes to workload isolation in containers and VMs.
-| **Key** | **Description** |
+| Consideration | Description |
| --- | --- |
-| node.kubernetes.io/not-ready | Node is not ready. This corresponds to the NodeCondition Ready being `False`. |
-| node.kubernetes.io/unreachable | Node is unreachable from the node controller. This corresponds to the NodeCondition Ready being `Unknown`. |
-| node.kubernetes.io/out-of-disk | Node becomes out of disk. |
-| node.kubernetes.io/memory-pressure | Node has memory pressure. |
-| node.kubernetes.io/disk-pressure | Node has disk pressure. |
-| node.kubernetes.io/network-unavailable | Node's network is unavailable. |
-| node.kubernetes.io/unschedulable | Node is unschedulable. |
-| node.cloudprovider.kubernetes.io/uninitialized | When the kubelet is started with "external" cloud provider, this taint is set on a node to mark it as unusable. After a controller from the cloud-controller-manager initializes this node, the kubelet removes this taint. |
+| **Hard Isolation** | Traditional VMs offer strong, "hard" isolation due to their separate kernels.|
+| **Soft Isolation** | Containers provide "soft" isolation using mechanisms like Kubernetes namespaces. |
-Reference the documentation for more detail on [taints and toleration](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/).
+The most fundamental difference between containers and virtual machines (VMs) is related to the host, or kernel environment in which they run.
+Each VM runs its own guest OS and as such, has its own kernel. In contrast, a container shares the underlying operating system's kernel with all of the other containers on that host.
-#### Affinity & Anti-Affinity
+As a simple illustration, the following diagram shows the components of an application as it relates to either VMs or containers.
-##### Pod Affinity/Anti-Affinity
+
-***You should be using Pod Affinity when you are asking the question:
-"Should I run this Pod in the same place as this other Pod?"***
+![The image depicts a comparison between two sets of application components: VMs, and Containers. Both diagrams start with a large rectangle at the bottom labelled 'Infrastructure'.
+Then, above that,a smaller rectangle labelled 'Hypervisor' on the VMs side,
+and 'OS' on the Containers side. Then, above that on the Containers side is a 'Container Engine', and then multiple sets of smaller rectangles above that for Bins/Lib 1 to n and above each one of those, corresponding 'App' 1 to n. That completes the Containers side.
+On the VMs side, instead of the Container Engine, there is 'Guest OS' 1 to n, and then the rest of the diagram above that is the same as the one for Containers, with 'Bins/Lib' and 'App' 1 to n.](../media/image_10.png)
+_Figure 5-1 - VMs vs Containers_
-Pod Affinity/Anti-Affinity enables you to restrict which nodes your pod
-can be scheduled to through the pod specification file. In this case
-scheduling will be based on pods that are already running on the node,
-rather than based on labels on the nodes. This mechanism enables you to
-manage the risk of two pods running on the same physical host. There are
-two enforcement levels for this mechanism; "preferred" and
-"required". As the names suggest, required will force the application
-of the rule, while preferred will only attempt to make it so.
-Additionally, you can use both required and preferred rules together, in
-which case the node must match the required rules prior to the preferred
-rules being evaluated.
+#### Hard Isolation
-##### Node Affinity/Anti-Affinity
+Key points to consider when it comes to hard isolation:
-***You should be using Node Affinity when you are asking the question:
-"Should I run this Pod on this Node?"***
-
-[Node Affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)
-can be used to segregate workloads to designated nodes to ensure
-sensitive data can be limited to a subset of the physical hardware. This
-can be important due to the fact that namespaces are virtual
-segmentation as the different containers are essentially processor
-sharing within the same kernel. Node Affinity is a way to ensure that
-you have kernel separation between specific workloads.
-
-Node Anti-Affinity can be used to provide high availability to a
-workload by ensuring that the workload is spread across physical
-infrastructure. This ensures that if a single physical host fails in
-some way, the workload uptime is not impacted.
-
-### RBAC
-
-#### Cluster Authorization
-
-The access controls are implemented on the Kubernetes API layer
-(`kube-apiserver`). When an API request comes in, the authorization
-permissions will be checked to see whether the user has access to be
-able to execute this command.
-
-There are two different layers which RBAC can be applied to.
+| Consideration | Description |
+| --- | --- |
+| **Strong Isolation** | VMs provide strong isolation by running separate guest OS and kernels, offering well-understood security realms.|
+| **Resource Sharing** | Containers share the host OS kernel, enabling faster startup, lower memory footprint, and efficient resource usage. |
-Roles and RoleBindings are associated with namespaces, while ClusterRole
-and ClusterRoleBindings are associated with clusters.
+#### Soft Isolation
-Role and ClusterRole behave the same, but in different contexts. A role
-defines the rules associated with that role. For simplicity, I will
-simply refer to roles to represent this functionality unless specificity
-is required.
+Key points to consider when it comes to soft isolation:
-Roles are additive, so the resulting permissions are based on the
-unioning of the rules associated with the roles.
+| Consideration | Description |
+| --- | --- |
+| **Namespace** |
Kubernetes namespaces provide basic workload separation through resource quotas and user access boundaries.
|
+| **Isolation** |
Namespaces provide a level of isolation, but they are not as strong as VMs.
Namespaces do not isolate workloads on physical hosts; workloads in different namespaces can run on the same host.
|
-RoleBinding and ClusterRoleBinding behave the same, but in different
-contexts. A RoleBinding associates a user with a role and a context
-(namespace or cluster).
+#### Attack Surface
-![The image depicts two rectangles, one labelled 'Namespace', containing a
-'Role' rectangle pointing to a 'RoleBinding' rectangle, and the other labelled
-'Cluster', containing a 'ClusterRole' rectangle pointing to a 'ClusterRoleBinding'
-rectangle.](../media/image_8.png)
+The attack surface of a container is the sum of all the different points where an attacker could potentially exploit the container. The attack surface includes the container image, the container runtime, the host OS, the container network, and the Kubernetes API server.
-### Service Mesh
+Consider security implications of:
-A service mesh is a programmable framework that allows you to observe,
-secure, and connect micro-services. It doesn't establish connectivity
-between micro-services, but instead has policies and controls that are
-applied on top of an existing network to govern how micro-services
-interact. Generally a service mesh is agnostic to the language of the
-application and can be applied to existing applications usually with
-little to no code changes.
+| Consideration | Description |
+| --- | --- |
+| **Kubernetes Platform Architecture** | nodes, kubelet service, API service, etcd service, control plane. |
+| **Workload Organization** | Pods, containers, namespaces. |
+| **Ecosystem Services** | ingress, storage, certificate management, service mesh. |
-A service mesh is a security layer which is enforced closer to the
-application layer. A service mesh essentially creates a Zero Trust
-network implementation where you manage your security posture based on
-the application architecture.
+
-A Service Mesh is the result of the natural evolution in implementing
-the Single Responsibility Principle in the micro-services architecture.
-It offloads some platform-related activities (such as mTLS enforcement,
-JWT validation) from the applications.
+![The image contains an outer rectangle labelled 'Cluster', with two
+rectangles inside that, each called 'Node'. The first Node contains a
+three-dimensional disc, or low cylinder, labelled 'etcd', and a dashed-border rectangle labelled 'Control-plane components'. There are arrows pointing to each
+object, with additional messaging attached to each arrow: 'Access to host/VM' points to Node; 'Access via Kubernetes API or Proxy' points to 'Control-plane components'; 'Access to etcd API' points to 'etcd'; and 'Intercept/modify/inject control-plane traffic' points to the inside of the Control-plane components. All of the above arrows are black, except the Intercept/modify/inject arrow, which is red.
+The second Node contains a rectangle labelled 'Kubelet', and another rectangle
+labelled 'Pod'. Inside the Pod is a 'Container' circle, and inside that, an 'App' rectangle. These objects have arrows as well: - 'Access via kubelet API' is a black arrow pointing at the Kubelet rectangle; - a red arrow points from App to some text: 'Escape container to host through vulnerability or volume mount';- another red arrow points from 'Intercept/modify/inject application traffic' to App; and - a final, black, arrow points from 'Exploit vulnerabilities in code' to Application.](../media/image_2.png)
+_Figure 5-2 - Kubernetes Attack Surface_
-The most widely recognized service mesh for Kubernetes is
-[Istio](https://istio.io/), but it is by no means the only option.
-[Linkerd](https://linkerd.io/), [Consul Connect](https://www.consul.io/docs/connect/index.html),
-[Maesh](https://containo.us/maesh/) and many more are available with
-slight modifications to the implementation, but generally offering the
-same security principles. I will speak generally about service meshes,
-but keep in mind that not every service mesh implements the same set of
-features, so please verify which service mesh is the best fit for you
-based on the features you care about. Following is a list of behaviors
-commonly found in a service mesh implementation:
+### Workload Scheduling & Placement
-- Traffic shaping with dynamic routing controls between services
+Containers can have dependencies among themselves, dependencies to nodes, and resource demands, that can also change over time. The resources available on a cluster also vary over time, through shrinking or extending the cluster, or by having it consumed by already placed containers. The way we place containers impacts the availability, performance, and capacity of the distributed systems as well. This section covers the scheduling considerations when a workload is scheduled on a node and how Kubernetes manage it.
-- Resiliency support for service communication such as circuit breakers, timeouts, and retries
+The following table is a list of considerations when it comes to workload scheduling and placement in Kubernetes.
-- Observability of traffic between services
+| Consideration | Description |
+| --- | --- |
+| **Taints and Tolerations** |
Taints and tolerations are used to control which pods can be scheduled on which nodes.
Use taints and tolerations to prevent pods from running on unsuitable nodes (e.g., user workloads on master nodes).
|
+| **Pod Affinity/Anti-Affinity** |
Pod affinity and anti-affinity allow you to constrain which nodes your pod is eligible to be scheduled based on labels on pods that are already running on the node.
|
+| **Node Affinity/Anti-Affinity** |
Node affinity and anti-affinity allow you to specific nodes or ensure distribution for high availability.
|
+| **Built-in vs Custom** |
Utilize built-in taints or define custom taints based on node conditions like readiness, resource pressure, or schedulability.
|
-- Tracing of communication flows
+### Role-Based Access Control (RBAC)
-- Secure communication between services
+#### Kubernetes Cluster Authorization
-Many service mesh implementations have the same general reference
-architecture. A service mesh will have a control plane to program the
-mesh, and client-side proxies in the data plane which handles all
-incoming and outgoing traffic to that pod and validates security
-conformance with the control plane. The control plane is responsible to
-transfer configurations to the proxies in their native format.
+Access controls are implemented on the Kubernetes API layer (`kube-apiserver`). When an API request comes in, the authorization permissions will be checked to see whether the user has access to be able to execute this command.
-![](../media/image_12.png)
+| Consideration | Description |
+| --- | --- |
+| **Role-Based Access Control (RBAC)** |
A method of regulating access to computer or network resources based on the roles of individual users within an organization.
Implement access controls at the Kubernetes API layer to govern user permissions for actions and resources.
|
+| **Roles and Binding** |
A role is a set of permissions that define the actions that a user is allowed to perform.
`RoleBindings` grant those permissions to the users.
Utilize Roles and RoleBindings for namespace-specific access, and `ClusterRoles` and `ClusterRoleBindings` for cluster-wide access.
|
-### Access Control and Policy Enforcement
+
-Access control policies evolve as the business requirements change --
-so, every time we have to change our access control policies, changing
-the micro-service code is not a good practice.
+![The image depicts two rectangles, one labelled `Namespace`, containing a `Role` rectangle pointing to a `RoleBinding` rectangle, and the other labelled
+`Cluster`, containing a `ClusterRole` rectangle pointing to a `ClusterRoleBinding` rectangle.](../media/image_8.png)
+_Figure 5-3 - RBAC in Kubernetes_
-Open Policy Agent (OPA) is a lightweight general-purpose policy engine
-that has no dependency on micro-services. You can use OPA to externalize
-access control policies and define fine-grained access control policies
-and enforce those policies at different places in a micro-services
-deployment.
+### Service Mesh
-OPA is capable of defining policies which govern a wide range of actions
-and compliance controls across the entire Kubernetes ecosystem. OPA
-casts a wider net than the deprecated Istio Mixer project, which focused
-primarily on policies around traffic management. There are a number of
-policy management tools in the Kubernetes ecosystem, however most of
-them only focus on a subset of the functionality. OPA has quickly become
-the default tooling for managing policies in a Kubernetes ecosystem, but
-it is by no means the only option.
+A service mesh is a programmable framework that allows you to observe, secure, and connect microservices. It doesn't establish connectivity between microservices, but instead has policies and controls that are applied on top of an existing network to govern how microservices interact. Generally a service mesh is agnostic to the language of the application and can be applied to existing applications usually with little to no code changes.
-With OPA, you define rules that govern how your system should behave.
-These rules exist to answer questions like:
+Features of a service mesh include:
-- Can user X call operation Y on resource Z?
+| Feature | Description |
+| --- | --- |
+| **Traffic Management** |
Can control the flow of traffic between services, including routing, load balancing, and retries.
Enhance security through a programmable framework that governs microservice interactions.
|
+| **Zero Trust** |
Implement Zero Trust network principles with policy-based security controls.
|
+| **Separate Planes** |
Consider service meshes for features such as traffic shaping, resiliency, observability, and secure communication.
|
-- What clusters should workload W be deployed to?
+
-- What tags must be set on resource R before it\'s created?
+![Figure 5-4](../media/image_9.png)
+_Figure 5-4 - Service Mesh_
-Services integrate with OPA by executing queries when policy decisions
-are needed. When you query OPA for a policy decision, OPA evaluates the
-rules and data (which you give it) to produce an answer. The policy
-decision is sent back as the result of the query. For example, in a
-simple API authorization use case:
+### Access Control and Policy Enforcement
-- You write rules that allow (or deny) access to your service APIs.
+Access control policies evolve as the business requirements change -- tying the access control policies to the micro-service code is a bad practice.
-- Your service queries OPA when it receives API requests.
+The following table lists the considerations when it comes to access control and policy enforcement:
-- OPA returns allow (or deny) decisions to your service.
+| Consideration | Description |
+| --- | --- |
+| **Open Policy Agent (OPA)** |
OPA is a general-purpose policy engine that can be used to enforce policies across the Kubernetes ecosystem.
Use OPA to externalize and enforce fine-grained access control policies across the Kubernetes ecosystem.
|
+| **Policy Enforcement** |
Define policies for API authorization, workload deployment restrictions, resource tagging, and other compliance controls.
|
+| **API Gateway** |
API gateways can be used to enforce policies at the API gateway level.
Integrate OPA with API gateways for policy enforcement at the edge.
|
+| **Cloud IAM** |
Use cloud IAM to manage access to cloud resources and services when deploying microservices on cloud platforms.
Use service or machine accounts to authenticate and authorize services to access cloud resources.
|
-- Your service enforces the decisions by accepting or rejecting requests accordingly.
+Policy enforcement systems could be integrated with API gateways to enforce the policies at the API gateway level. The following figure illustrates the sequence of events that happens when an API gateway intercepts client requests to apply authorization policies using OPA.
-Policy enforcement systems could be integrated with API gateways to
-enforce the policies at the API gateway level. The following figure
-illustrates the sequence of events that happens when an API gateway
-intercepts client requests to apply authorization policies using OPA.
+
-![](../media/image_5.png)
+![A diagram illustrating a microservice architecture with an API gateway and OPA engine for authorization. It shows the flow of a client request through the gateway, which sends an authorization request to the OPA engine. The OPA engine evaluates policies and sends an allow/deny response back to the gateway. The gateway then either terminates the request or forwards it to the microservice.](../media/image_7.png)
+_Figure 5-5 - API Gateway with OPA_
## 5.2 Securing Container Runtime
In order to run containers securely, we aim to do the following:
-- Use least privilege to carry out the task at hand.
-
-- Enforce resource allocation
-
-- Limit communication between applications, and to and from the outside world, to a defined and deterministic set of connections.
+1. Use least privilege to carry out the task at hand.
+2. Enforce resource allocation
+3. Limit communication between applications, and to and from the outside world, to a defined and deterministic set of connections.
### Least-Privilege Security Settings
-#### Say No to Root
-
-According to the principle of least privilege, it would make sense to
-run a container as a non-root user. There are however some exceptions:
-
-- Your container needs to modify the host system; for example, modifying the kernel's configuration.
-
-- The container needs to bind to privileged ports on the node (below 1024 --- for example, nginx serving on port 80). In practice, this can be by-and-large avoided through port mappings and the service abstraction in Kubernetes.
-
-- Installing software into a container at runtime: traditional package management systems might require root to function or store files in a certain location with a different user ID than the user executing the program. This approach is generally considered bad practice since any code installed at runtime has not been scanned for vulnerabilities or other policy requirements.
+Least privilege is a security concept that requires that every module or program in a computer system be granted the least amount of privilege needed to fulfill its function. This helps to reduce the potential attack surface of the system.
-#### Use a read-only root filesystem
+The following table lists the considerations when it comes to least-privilege security settings in containers:
-A common attack pattern in a compromised container is for attackers to
-write an executable file that they will then run. If your application
-code doesn't need to be able to write into the filesystem inside the
-container, the `readOnlyRootFilesystem` setting prevents that approach.
-
-#### Limiting host volume mounts
-
-Certain sensitive directories should not be mounted from the host into a
-container without very good reason, as a compromised container (or just
-buggy code) could lead to undesired changes on the host. The
-`allowedHostPaths` parameter in `PodSecurityPolicy` allows you to limit what
-can be mounted and therefore made accessible to the container.
-
-#### Disallow privileged access
-
-Unless your container has a particular need for privileged Linux
-capabilities, privileged and `allowPrivilegeEscalation` should be false.
-Privileged access within a container is effectively the same as root
-access on the host.
-
-#### Restrict System Calls
-
-System calls can be very powerful, so they should be used with care.
-About a third of the system calls used in containers are unnecessary.
-
-For instance, a popular system call is `Ptrace`. With it, one process can
-be used to control another, as well as change the memory. The call is
-largely used to debug code. If it were left in a container and the
-container were compromised, it would be a jackpot for an attacker.
-
-Docker has done creating seccomp security profiles that address the
-system call problem. Secure computing mode (seccomp) is a Linux kernel
-feature. You can use it to restrict the actions available within the
-container. You can use this feature to restrict your application's
-access. In Kubernetes, the use of seccomp profiles in pods can be
-controlled via
-[annotations](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp)
-on the `PodSecurityPolicy`.
+| Consideration | Description |
+| --- | --- |
+| **Avoid Root** | Run containers as non-root users unless specific privileges are required (e.g., modifying the host system, binding to privileged ports) |
+| **Read-Only Root Filesystem** | Prevent attackers from writing executable files by setting the root filesystem as read-only, unless write access is essential. |
+| **Limit Host Volume Mounts** | Restrict the ability to mount sensitive host directories into containers to prevent unintended modifications. |
+| **Disable Privileged Access** | Set `privileged` and `allowPrivilegeEscalation` to _**false**_ unless specifically required. |
+| **Restrict System Calls** | Use [`seccomp`](https://www.bing.com/ck/a?!&&p=9acbba49cc8936509ee03e13e8b9bf37593a0902f2fe56133188b3acf0f02e3cJmltdHM9MTczMTQ1NjAwMA&ptn=3&ver=2&hsh=4&fclid=048693a4-15f3-6fbd-0106-80d9147f6e25&psq=seccomp&u=a1aHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvdHV0b3JpYWxzL3NlY3VyaXR5L3NlY2NvbXAv&ntb=1) profiles to limit system calls available within containers, minimizing potential attack vectors.|
### Resource Usage
-Containers have multiple dimensions at runtime, such as a memory usage
-dimension, a CPU usage dimension, and other resource consumption
-dimensions.
+Containers have multiple dimensions at runtime, such as:
-![](../media/image_10.png)
+- memory usage,
+- CPU usage, and
+- other resource consumption dimensions.
-Every container must declare its resource requirements and pass that
-information to the platform. These requirements are important
-information that affects how Kubernetes allocates workloads, and how
-those workloads are treated and prioritized when resources become
-constrained or while scaling up or down. In addition to passing the
-resource requirements of the container, it is also important that the
-application stay confined to the indicated resource requirements. If the
-application stays confined, the platform is less likely to consider it
-for termination and migration when resource starvation occurs.
+The following table lists the considerations when it comes to resource usage in containers:
-### Network Policies
-
-Network Policies enable us to restrict the networking configuration
-associated with pods. By default, Kubernetes has an allow-all policy,
-and does not restrict the ability for pods to communicate with each
-other. You can use network policies to restrict pod-to-pod communication
-within Kubernetes. Additionally, you can restrict access to pods from
-the outside world. These policies allow for layer 3 network segmentation
-of pods.
-
-Network policies can be used for a number of purposes. For example,
-separating workloads so they are not able to communicate with each
-other. Isolating production namespaces from dev/test/staging namespaces.
-Whitelisting or blocking incoming or outgoing network traffic to a
-workload.
-
-Network Policies can be used to ensure a secure multi-tenant cluster.
-When applied properly, Pods and Services in a given namespace cannot
-access other Pods or Services in a different namespace.
-
-While network policies can absolutely improve the security of a
-Kubernetes cluster, it does have some limitations as well which should
-be considered.
-
-- Kubernetes network policies are applied to the pod ports, not to the service ports.
-
-- Network policies must be updated if the container port changes.
+| Consideration | Description |
+| --- | --- |
+| **Define the Required Resources** | Define and enforce resource requirements (CPU, memory) for each container to ensure predictable resource allocation and prevent resource starvation.|
-- Kubernetes network policies can not generate traffic logs, which can make it difficult to perform security analysis.
+### Network Policies
-- Kubernetes network policies don't allow you to specify a FQDN for egress traffic.
+The following table lists the considerations when it comes to network policies in containers:
-Due to some of these limitations, a new security approach has been
-developed called a Service Mesh. There are a number of available service
-meshes available today, but the general principles will be covered in
-the next section.
+| Consideration | Description |
+| --- | --- |
+| **"Layer 3" Network segmentation** | Restrict pod-to-pod communication and external access using network policies to enhance security and implement network segmentation. |
+| **Set Limits** | Consider network policy limitations (pod port focus, service port changes, logging capabilities, FQDN support). |
+| **Default Allow-All Policy** | By default, Kubernetes has an allow-all policy, and does not restrict the ability for pods to communicate with each other. |
## 5.3 Securing Traffic
-In an ideal world, the micro-services developer should only worry about
-the business functionality of a micro-service, and the rest should be
-handled by specialized components with less hassle. The API Gateway and
-Service Mesh are two architectural patterns that help us reach there.
+Microservices developer should focus on the business functionality of a microservice, and the management of other concerns like security, observability, and resiliency should be handled by specialized components.
+The [`API Gateway`](https://microservices.io/patterns/apigateway.html) and [`Service Mesh`](#service-mesh) are two architectural patterns that help us achieve this goal.
-The API Gateway pattern is mostly about edge security, while the Service
-Mesh pattern deals with service-to-service security. Or in other words
-the API Gateway deals with north/south traffic, while the Service Mesh
-deals with east/west traffic.
-
-### Securing North-South Traffic
+### North-South Traffic
North-South traffic indicates any traffic caused by the communication
between the client/consumer applications and the APIs. To secure the
north-south traffic, an API gateway is typically deployed at the edge of
a network.
-An API gateway is an API management tool that sits between a client and
-a collection of backend services at the edge of the network. The API
-gateway is the only entry point to micro-services for requests
-originating from outside. It selectively exposes the micro-services as
-APIs to the client applications, screens all incoming requests and
-authenticates/authorizes them. When the security screening at the edge
-is done, the end-user context is passed across to the upstream
-micro-services.
-
-API gateway also enables the organization to
-
-- decouple the security from the micro-services. API gateway intercepts all the requests coming to a micro-service, talks to the respective authorization and dispatches only the legitimate requests to the upstream micro-services. Otherwise, it returns back an error message to the client application. This principle also allows the teams to change the authorization framework without any micro-service code change.
-
-- protect APIs from overuse, so you use the rate limiting and the request throttling.
-
-- understand how people use APIs, so you've added analytics and monitoring tools.
-
-- monetized APIs and connect them to a billing system.
-
-- hide the details of API implementation from the external users
-
-There are a lot of commercial and open source solutions that support
-these features, such as Tyk, Kong, Ambassador.
-
-To authenticate the end users and authorize them the access, OAuth 2.0
-is the best security protocol. At the edge, security is all about
-granting controlled access to resources. And if security is all about
-granting access to your resources, you need to figure out **who** wants
-access to your resources, for **what** purpose, and for **how long**.
-
-- Who: Ensure that only permitted entities are granted access to your resources.
-
-- What purpose: Ensure that the permitted entities can perform only what they're allowed to perform on your resources.
-
-- How long: Ensure that access is granted for only the desired period.
-
-In the case that the organization is not ready to adapt API Gateways,
-apps could be directly integrated with OAuth2 provider either
-programmatically using the 3rd party libraries or on Kubernetes by
-deploying [OAuth2 proxy](https://github.com/pusher/oauth2_proxy). In the
-case of Oauth2 proxy, an additional pod is deployed alongside the
-application pod that is responsible to handle the authentication
-requests. This later approach does not need any application code change.
+| Consideration | Description |
+| --- | --- |
+| **North-South Traffic (Client-API Communication)** |
Deploy API gateways at the network edge to secure and manage incoming requests to microservices.
Implement authentication and authorization using protocols like OAuth 2.0 to control access to resources.
Consider API gateways for features like rate limiting, request throttling, analytics, and API monetization
|
-### Securing East-West Traffic
+### East-West Traffic
East-West traffic indicates the inter-micro-service communications.
-Securing this type of traffic has two main aspects:
-
-**Peer authentication** is used for service-to-service authentication to
-verify the client making the connection. Mutual TLS helps clients and
-servers identify themselves to each other through TLS certificates. It
-also protects communications between two parties for confidentiality and
-integrity.
-
-**Request authentication** is used for end-user authentication to verify
-the credential attached to the request. This is used when a request is
-made from the client to the server on behalf of the end users. In a
-services architecture, the typical way for services to communicate
-end-user or origin identity (the user logged in) is passing identity
-tokens like JSON Web Tokens (JWT). These tokens are given out to
-represent an authenticated user and the claims that user has.
-
-A common way to enforce mTLS and JWT verification is through a Service
-Mesh pattern. A Service Mesh is an architectural pattern, which
-highlights the need of decoupling security, observability, routing
-control and resiliency from the micro-services implementation. For more
-information, please refer to the Service Mesh section.
-
-### Securing Asynchronous Traffic
-
-Event-driven systems rely on data streams and the propagation of events
-in a system. For asynchronous events, we can build reactive
-micro-services, which are capable of reacting to events that occur in a
-system. The recipient micro-services are attentive to events that occur
-in the system and act accordingly based on the type of event that
-occurs.
-
-Asynchronous communication can happen over any kind of messaging system,
-such as RabbitMQ, Kafka, ActiveMQ, or Google Pub/Sub. The traffic
-between the message broker and the micro-services need to be secured. To
-do so:
-
-**Use TLS** to encrypt data in transit between the micro-services and the
-message broker.
-
-**Use mTLS** to control which micro-services are permitted to connect to
-the message broker and to authenticate the clients connecting to it.
-
-**Define ACLs** to enforce authorization. ACLs permit or deny various
-micro-services performing different types of actions on the message
-broker resources such as topics and queues.
-
-## 5.4 Secure Coding Practices
-
-### Crypto Libraries
-
-Don't write your own crypto code!
-
-Most of the time, when it comes to security you shouldn\'t try to roll
-your own new solutions and algorithms unless you've got strong and
-specific reasons to, and you've got people skilled enough to create
-something nearly as good as the open source tools already available
-(tools that have been heavily battle tested by the community).
-
-In most cases, you should use
-[NaCl](http://nacl.cr.yp.to/index.html)/[libsodium](https://download.libsodium.org/doc/)
-for encryption. It's been around for several and it's fast, easy to
-use, and secure. While the original implementation of NaCl is written in
-C, it also supports C++ and Python. And thanks to the libsodium fork,
-several adapters for other languages like PHP, Javascript, and Go are
-available.
-
-If you're working with Java or C#, your best bet is to go with [Bouncy Castle](https://www.bouncycastle.org/).
-
-### Protect Production Branch
-
-There are different ways to implement a branching strategy. What is
-important is to make sure that only the verified commits are merged into
-the git branch that presents the production environment. The commits
-that are merged into the production branch must be fully tested (from
-unit tests at the bottom of the testing stack to the end-to-end tests on
-top of the stack) before they are merged into the production.
-
-### API Security
-
-Modern API-based applications are very different. More and more, the UI
-uses APIs to send and receive the data from the backend servers to
-provide the functions of the application. It is now the clients that do
-the rendering and maintain the state.
-
-By nature, APIs expose application logic and sensitive data such as
-Personally Identifiable Information (PII) and because of this have
-increasingly become a target for attackers.
-
-The changes in the industry mentioned above have resulted in OWASP
-launching a separate project dedicated purely on API security. Now, the
-OWASP API Security Top 10 project focuses specifically on the top ten
-vulnerabilities in API security.
-
-Ref:
-[https://owasp.org/www-project-api-security/](https://owasp.org/www-project-api-security/)
-
-#### Object Level Authorization
-
-Object level authorization is an access control mechanism that is
-usually implemented at the code level to validate that data being
-accessed is owned by by current authenticated user
-
-Every API endpoint that receives an ID of an object, and performs any
-type of action on the object, should implement object level
-authorization checks. The checks should validate that the logged-in user
-does have access to perform the requested action on the requested
-object.
-
-- Implement a proper authorization mechanism that relies on the user policies and hierarchy.
-
-- Use an authorization mechanism to check if the logged-in user has access to perform the requested action on the record in every function that uses an input from the client to access a record in the database.
-
-- Prefer random and unpredictable values as GUIDs for records' IDs to prevent easy enumeration of records.
-
-- Write tests to evaluate the authorization mechanism. Do not deploy vulnerable changes that break the tests.
-
-#### User Authentication
-
-Authentication endpoints and flows are assets that need to be protected.
-"Forgot password / reset password" should be treated the same way as
-authentication mechanisms. APIs endpoints that are responsible for
-authentication must be treated differently from regular endpoints and
-implement extra layers of protection
-
-An API is vulnerable if it:
-
-- Permits [credential stuffing](https://www.owasp.org/index.php/Credential_stuffing) whereby the attacker has a list of valid usernames and passwords.
-
-- Permits attackers to perform a brute force attack on the same user account, without presenting captcha/account lockout mechanism.
-
-- Permits weak passwords.
-
-- Sends sensitive authentication details, such as auth tokens and passwords in the URL.
-
-- Doesn't validate the authenticity of tokens.
-
-- Accepts unsigned/weakly signed JWT tokens ("alg":"none") doesn't validate their expiration date.
-
-- Uses plain text, encrypted, or weakly hashed passwords.
-
-- Uses weak encryption keys.
-
-#### Data Exposure
-
-APIs rely on clients to perform the data filtering. Since APIs are used
-as data sources, sometimes developers try to implement them in a generic
-way without thinking about the sensitivity of the exposed data.
-Excessive Data Exposure commonly leads to exposure of sensitive data.
-
-- Never rely on the client side to filter sensitive data.
-
-- Review the responses from the API to make sure they contain only legitimate data.
-
-- Backend engineers should always ask themselves "who is the consumer of the data?" before exposing a new API endpoint.
-
-- Avoid using generic methods such as `to_json()` and `to_string()`. Instead, cherry-pick specific properties you really want to return
-
-- Classify sensitive and personally identifiable information (PII) that your application stores and works with, reviewing all API calls returning such information to see if these responses pose a security issue.
-
-- Implement a schema-based response validation mechanism as an extra layer of security. As part of this mechanism define and enforce data returned by all API methods, including errors.
-
-#### Resource and Rate Limiting
-
-API requests consume resources such as network, CPU, memory, and
-storage. The amount of resources required to satisfy a request greatly
-depends on the user input and endpoint business logic. Also, consider
-the fact that requests from multiple API clients compete for resources.
-It's common to find APIs that do not implement rate limiting or APIs
-where limits are not properly set.
-
-- Docker makes it easy to limit [memory](https://docs.docker.com/config/containers/resource_constraints/#memory), [CPU](https://docs.docker.com/config/containers/resource_constraints/#cpu), [number of restarts](https://docs.docker.com/engine/reference/commandline/run/#restart-policies---restart), [file descriptors, and processes](https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container---ulimit).
-
-- Implement a limit on how often a client can call the API within a defined timeframe.
-
-- Notify the client when the limit is exceeded by providing the limit number and the time at which the limit will be reset.
-
-- Add proper server-side validation for query string and request body parameters, specifically the one that controls the number of records to be returned in the response.
-
-- Define and enforce maximum size of data on all incoming parameters and payloads such as maximum length for strings and maximum number of elements in arrays.
-
-#### Function Level Authorization
-
-Some micro-services expose administrative APIs that could be exploited by
-the attackers. The attackers send legitimate API calls to the API
-endpoint that they should not have access to.
-
-Your application should have a consistent and easy to analyze
-authorization module that is invoked from all your micro-services.
-Frequently, such protection is provided by one or more components
-external to the application code.
-
-- The enforcement mechanism(s) should deny all access by default, requiring explicit grants to specific roles for access to every function.
-
-- Make sure that all of your administrative controllers inherit from an administrative abstract controller that implements authorization checks based on the user's group/role.
-
-- Make sure that administrative functions inside a regular controller implements authorization checks based on the user's group and role.
-
-#### Mass Assignment
-
-Modern frameworks encourage developers to use functions that
-automatically bind input from the client into code variables and
-internal objects. Attackers can use this methodology to update or
-overwrite sensitive object's properties that the developers never
-intended to expose. Exploitation may lead to privilege escalation, data
-tampering, bypass of security mechanisms, and more.
-
-- If possible, avoid using functions that automatically bind a client's input into code variables or internal objects.
-
-- Whitelist only the properties that should be updated by the client.
-
-- Use built-in features to blacklist properties that should not be accessed by clients.
-
-- If applicable, explicitly define and enforce schemas for the input data payloads.
-
-Many frameworks offer their own mechanisms for trying to address these
-types of issues. For example, [Ruby on Rails offers Strong Parameters](https://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters)
-to help developers mitigate some of these risks. Be sure to find and
-follow the best practices for your chosen frameworks.
-
-#### Security Misconfiguration
-
-Security misconfiguration can happen at any level of the API stack, from
-the network level to the application level. Security misconfigurations
-can not only expose sensitive user data, but also system details that
-may lead to full server compromise.
-
-The API might be vulnerable if:
-
-1. Appropriate security hardening is missing across any part of the application stack, or if it has improperly configured permissions on cloud services.
-
-2. The latest security patches are missing, or the systems are out of date.
-
-3. Unnecessary features are enabled (e.g., HTTP verbs).
-
-4. Transport Layer Security (TLS) is missing.
-
-5. Security directives are not sent to clients (e.g., [Security Headers](https://www.owasp.org/index.php/OWASP_Secure_Headers_Project)).
-
-6. A Cross-Origin Resource Sharing (CORS) policy is missing or improperly set.
-
-7. Error messages include stack traces, or other sensitive information is exposed.
-
-The API life cycle should include:
-
-- A repeatable hardening process leading to fast and easy deployment of a properly locked down environment.
-
-- A task to review and update configurations across the entire API stack. The review should include: orchestration files, API components, and cloud services (e.g., S3 bucket permissions).
-
-- A secure communication channel for all API interactions access to static assets (e.g., images).
-
-- An automated process to continuously assess the effectiveness of the configuration and settings in all environments.
-
-Furthermore:
-
-- To prevent exception traces and other valuable information from being sent back to attackers, if applicable, define and enforce all API response payload schemas including error responses.
-- Ensure API can only be accessed by the specified HTTP verbs. All other HTTP verbs should be disabled (e.g. HEAD).
+Securing this type of traffic has three aspects:
-- APIs expecting to be accessed from browser-based clients (e.g., WebApp front-end) served from separate origins should implement a proper Cross-Origin Resource Sharing (CORS) policy.
-
-#### Injection
-
-Injection flaws are very common and are often found in SQL, LDAP, or
-NoSQL queries, OS commands, XML parsers, and ORM. These flaws are easy
-to discover when reviewing the source code. Attackers can use scanners
-and fuzzers. Injection can lead to information disclosure and data loss.
-It may also lead to DoS, or complete host takeover.
-
-Preventing injection requires keeping data separate from commands and
-queries.
-
-- Perform data validation using a single, trustworthy, and actively maintained library.
-
-- Validate, filter, and sanitize all client-provided data, or other data coming from integrated systems.
-
-- Special characters should be escaped using the specific syntax for the target interpreter.
-
-- Prefer a safe API that provides a parameterized interface.
-
-- Always limit the number of returned records to prevent mass disclosure in case of injection.
-
-- Validate incoming data using sufficient filters to only allow valid values for each input parameter.
-
-- Define data types and strict patterns for all string parameters.
-
-#### Improper Asset Management
-
-Lack of APIs inventory and deprecation strategies leads to running
-unpatched APIs, resulting in leakage of sensitive data. Attackers may
-gain access to sensitive data, or even take over the server through old,
-unpatched API versions connected to the same database.
-
-- Inventory all API hosts and document important aspects of each one of them, focusing on the API environment (e.g., production, staging, test, development), who should have network access to the host (e.g., public, internal, partners) and the API version.
-
-- Inventory integrated services and documents important aspects such as their role in the system, what data is exchanged (data flow), and its sensitivity.
-
-- Document all aspects of your API such as authentication, errors, redirects, rate limiting, cross-origin resource sharing (CORS) policy and endpoints, including their parameters, requests, and responses.
-
-- Generate documentation automatically by adopting open standards. Include the documentation build in your CI/CD pipeline.
-
-- Make API documentation available to those authorized to use the API.
-
-- Use external protection measures such as API security firewalls for all exposed versions of your APIs, not just for the current production version.
-
-- Avoid using production data with non-production API deployments. If this is unavoidable, these endpoints should get the same security treatment as the production ones.
-
-- When newer versions of APIs include security improvements, perform risk analysis to make the decision of the mitigation actions required for the older version: for example, whether it is possible to backport the improvements without breaking API compatibility or you need to take the older version out quickly and force all clients to move to the latest version.
-
-#### Insufficient Logging and Monitoring
-
-Without logging and monitoring, or with insufficient logging and
-monitoring, it is almost impossible to track suspicious activities and
-respond to them in a timely fashion. Without visibility over on-going
-malicious activities, attackers have plenty of time to fully compromise
-systems.
-
-- Log all failed authentication attempts, denied access, and input validation errors.
-
-- Logs should be written using a format suited to be consumed by a log management solution, and should include enough detail to identify the malicious actor.
-
-- Logs should be handled as sensitive data, and their integrity should be guaranteed at rest and transit.
-
-- Configure a monitoring system to continuously monitor the infrastructure, network, and the API functioning.
-
-- When appropriate, consider using a Security Information and Event Management (SIEM) system to aggregate and manage logs from all components of the API stack and hosts.
-
- - The role of a SIEM in this case is mainly for active threat detection and analysis, but many SIEMs cover a much wider range of features such as blocking and auditing. A few examples of solutions which fit into this category are Sysdig and Rapid7.
-
- - When consolidating large amounts of log data into a single system, it is important to consider that passing log data over the public internet will get very expensive. It is recommended to keep the log data within the same cloud ecosystem as the workloads, or ensure that you have a direct connect to a remote location which can handle the amount of log traffic without incurring excessive data transfer costs.
-
-- Configure custom dashboards and alerts, enabling suspicious activities to be detected and responded to earlier.
-
-#### Error Handling
-
-Improper handling of errors can introduce a variety of security problems
-for a web site. The most common problem is when detailed internal error
-messages such as stack traces, database dumps, and error codes are
-displayed to the user (hacker). These messages reveal implementation
-details that should never be revealed. Such details can provide hackers
-important clues on potential flaws in the site and such messages are
-also disturbing to normal users.
-
-The errors must be handled according to a well thought out scheme that
-will provide a meaningful error message to the user, diagnostic
-information to the site maintainers, and no useful information to an
-attacker. Error handling should not focus solely on input provided by
-the user, but should also include any errors that can be generated by
-internal components such as system calls, database queries, or any other
-internal functions.
-
-Ensure that the site is built to gracefully handle all possible errors.
-When errors occur, the site should respond with a specifically designed
-result that is helpful to the user without revealing unnecessary
-internal details.
-
-### Single Page Application
+| Consideration | Description |
+| --- | --- |
+| **East-West Traffic (Inter-Microservice Communication)** |
Implement mutual TLS (mTLS) to secure communication between microservices.
Use JWT tokens for for request authentication to verify end-user identities and claims.
Leverage [service meshes](#service-mesh) for decoupling security, observability, routing control, and resiliency from microservices implementation.
|
-Single Page Applications (SPAs) as the latest evolution in web
-application design. With SPAs, the single HTML page is broken up into
-sections and JavaScript code running in the web browser calls various
-APIs on a server that return data. The JavaScript libraries then take
-this data and update the HTML on the page according to the presentation
-logic the developer coded into the application.
+### Event-Driven Systems
-Compared to a traditional Web, App, DB model, the SPA model forces you
-to account for application APIs being publicly exposed, instead of being
-internal to the server side architecture. Because more of the APIs are
-exposed to the client instead of just between two tiers of an
-application architecture, there is an additional attack surface being
-introduced that should be recognized.
+Event-driven systems rely on data streams and the propagation of events to trigger actions. These systems are composed of event producers, event consumers, and event brokers.
-SPAs are responsive and easy to deploy. However, they impose new
-security risks.
+The following table lists the considerations when it comes to securing event-driven systems:
-1. SPAs are causing many companies to publish public APIs for the first time, or to increase the number of publicly exposed APIs which must be protected from unauthorized access.
+| Consideration | Description |
+| --- | --- |
+| **Message broker** | Secure event traffic between microservices using message brokers like
[Kafka](https://kafka.apache.org/)
[Google Pub/Sub](https://cloud.google.com/pubsub)
[Azure Service Bus](https://azure.microsoft.com/en-ca/services/service-bus/)
[AWS SNS](https://aws.amazon.com/sns/)
|
+| **Transport Layer Security** | Use TLS/mTLS to encrypt data in transit between microservices and the message broker.|
+| **Control access** | Use `IAM` to control which microservices are permitted to connect to the message broker and to authenticate the clients connecting to it.|
+| **Access Control Lists (ACLs)**| ACLs permit or deny various micro-services performing different types of actions on the message broker resources such as topics and queues. |
-2. Cross Site Scripting (XSS) Attacks -- occur when a vulnerable application allows arbitrary javascript code to be injected and executed on your page. This often occurs through the form fields on the page.
+## 5.4 Secure Coding Practices
-To resolve these issues:
+Secure coding practices are a set of guidelines and best practices that help developers write secure code. The Government of Canada provides guidance on secure coding practices in the [Secure Coding Practices Guide - on GCPedia](https://www.gcpedia.gc.ca/gcwiki/images/0/0c/Guidance_for_Secure_Application_Development.pdf), which are base in large part on the [OWASP Top 10](https://owasp.org/Top10/).
-1. Use SSL and OAuth 2 tokens (with the expiry policy) to protect your APIs and the data in transit
+In addition to the `Secure Coding Practices Guide`, the following list should be considered when developing microservices:
-2. Continuously checking your frontend code for security vulnerabilities. Scanning of frontend dependencies is done by default by the JavaScript package manager npm, anda tool such as OWASP ZAP is excellent for inspecting the communication the frontend has with the api for unsafe practices.
+| Consideration | Description |
+| --- | --- |
+| **Crypto Libraries** |
Don't write your own crypto code! Use well-known and tested libraries.
|
+| **Data in Transit** |
Use SSL and OAuth tokens to protect your APIs and the data in transit.
Use mutual TLS (mTLS) for secure communication between microservices.
|
+| **Protect Production Branch** |
Only verified commits should be merged into the production branch.
Use _branch protection rules_ to prevent unauthorized changes to the production branch.
|
+| **Secrets Management** |
Never hard-code secrets in your code.
Use a secret management tool to store and retrieve secrets.
|
+| **Input Validation** |
Always validate input data to prevent injection attacks.
|
+| **Error Handling** |
Implement proper error handling to prevent information leakage.
|
+| **Logging** |
Implement proper logging to help with debugging and auditing.
|
+| **Dependency Management** |
Keep your dependencies up to date to avoid vulnerabilities.
|
+| **Secure Configuration** |
Ensure that your configuration is secure and does not expose sensitive information.
|
## 5.5 Architecting Your Application for Cloud
-In this section, we highlight some principles to build cloud-native
-applications. The purpose of these principles is to help you create
-scalable, resilient and portable micro-services that could be easily
-deployed and monitored on the Cloud.
-
-### Single Concern Principle
-
-This principle dictates that every container should address a single
-concern and do it well. If you need to address multiple concerns, you
-can use patterns such as sidecar and init-containers.
-
-![](../media/image_9.png)
-
-The main motivation for this principle is container image reuse and
-replaceability. If you create a container that addresses a single
-concern, and it does it in a feature-complete way, the chances are
-higher that the container image will be reused in the future.
-
-### Immutable Container Images
-
-One of the principles of Docker containers is that an image is immutable
---- once built, it's unchangeable, and if you want to make changes,
-you'll get a new image as a result.
-
-Immutable principle of images enables the team to create an image once
-and reuse it multiple times in different environments.
-
-![](../media/image_4.png)
-
-The immutable principle of the images also implies that the image should
-not contain any environment-specific configuration. Ideally, the
-application code is stored in a git repo while a separate repo is used
-to maintain the configurations. This approach ensures that the sensitive
-configuration information is not leaked unintentionally. It also
-simplifies the access control over the repositories: dev team has only
-access to the code repo while the devSecOps team is granted the access
-to the config repositories.
-
-### Self-Contained Image
-
-One factor of 12-factor app manifesto is to define and isolate the
-dependencies. For the docker images, this means that a container should
-contain the containerized application as well as everything it needs to
-run it such as the language runtime, the application platform and other
-dependencies. The container images should ideally be as minimal as
-possible and should not include software or technologies which are not
-needed to run the application. Ideally, you are not using a large
-distribution, such as Ubuntu, as they increase the attack surface as
-well as slow down your CI/CD pipelines due to the large size of the
-image. If you are able to use a bare bones container image, such as
-Scratch or Alpine as your base image, it will limit the attack surface
-and speed up your build pipelines.
-
-If you are building your container images with your CI/CD pipeline, it
-is recommended that the build tools are not in your final image.
-Instead, you should build the application artifacts in a build image and
-then copy those application artifacts into a minimal image for your
-release artifact. An example of this approach can be reviewed in this
-[blog post](https://medium.com/@chemidy/create-the-smallest-and-secured-golang-docker-image-based-on-scratch-4752223b7324).
-
-![](../media/image_3.png)
-
-The only exceptions are things such as configurations and secrets, which
-vary between different environments and must be provided at runtime; for
-example, through Kubernetes ConfigMap.
-
-### Lifecycle Conformance
-
-This principle dictates that your application should have a way to read
-the events coming from the platform. Moreover, the container should
-react to those events.
-
-There are all kinds of events coming from the managing platform that are
-intended to help you manage the lifecycle of your container. It is up to
-your application to decide which events to handle and whether to react
-to those events or not. For example, any application that requires a
-clean shutdown process needs to catch signal: terminate (SIGTERM)
-messages and shut down as quickly as possible. This is to avoid the
-forceful shutdown through a signal: kill (SIGKILL) that follows a
-SIGTERM.
-
-There are also other events, such as PostStart and PreStop, that might
-be significant to your application life-cycle management. For example,
-some applications need to warm up before service requests and some need
-to release resources before shutting down cleanly.
-
-![](../media/image_1.png)
-
-### Process Disposability
-
-Pods are volatile and they can be killed and spun up quite often. This
-means that containerized applications must be stateless and externalize
-their state to a persistent data store that is accessible by all
-containers.
-
-To maximize the robustness and the resiliency of the system, it is
-important that the containers have a fast startup. To shorten the
-startup time, the amount of work on the container startup should be
-minimized. Moreover, the docker images must be kept small by using the
-container-optimized images, such as Alpine, as the base image. This
-reduces container size, build time, and networking time when copying
-container images. Additionally, small containers reduce the attack
-surfaces and expose less vulnerabilities.
-
-## 5.6 Securing Container Images
-
-### Scan Images for Vulnerabilities
-
-The software that you run in your Kubernetes cluster gets there in the
-form of container images. It is recommended to check that your images:
-
-1. Don't include known critical vulnerabilities
-
-2. Are the images you intended to use, and haven't been manipulated or replaced by a third party
-
-3. Meet other image policy requirements your organization might have in place
-
-4. Has only packages that are absolutely necessary. The small container images reduce the attack surface and are faster to startup.
-
-To detect vulnerabilities, you need to use a container image scanner.
-The basic function of a container image scanner is to inspect the
-packages included in an image, and report on any known vulnerabilities
-included in those packages.
-
-To ensure that you're not running vulnerable code in your deployment,
-you should scan any third-party container images as well as the ones
-built by your own organization. Your CI pipeline should include policies
-that flag images with issues discovered by security scans so that your
-team can take appropriate action to address those issues sooner rather
-than later. New vulnerabilities continue to be found in existing
-software, so it's important to rescan your images on a regular basis.
-
-Advanced solutions may also use dynamic admission control to ensure that
-images are deployed only if they have been scanned, and the scan was
-successful. From Kubernetes 1.9, dynamic admission controllers allow for
-flexible, extensible mechanisms for making checks before allowing a
-resource to be deployed to a cluster.
-
-Image scanning can be integrated into the CI/CD pipeline to automate the
-process of rejecting images based on scanning for known vulnerabilities.
-However, this is not a comprehensive solution and should be used in
-conjunction with other security scanning practices. For example, it is a
-good practice to periodically scan images in the container registry as
-this type of scanning can incorporate more recent known issues which may
-have become apparent after the CI process has completed. Additionally,
-there are a number of different types of scans which can be run on
-images in the image registry which can check for more than just
-vulnerabilities, such as compliance or open source license violations.
-It is best to have a defense in depth strategy when it comes to securing
-container images.
-
-![](../media/image_14.png)
-
-### Patch Container Image
-
-Once you have discovered a vulnerable container image, you need to
-update the container to use a fixed version of the package.
-
-True to the philosophy of treating container images as immutable,
-"patching" in a container deployment is building a new image, and then
-deploying the containers based on that new image. The build is typically
-automated through a continuous integration (CI) pipeline.
-
-### Container Image Storage
+The purpose of this section is to outline aspects of scalable, resilient, and portable microservices to facilitate them being deployed and monitored to the Cloud.
-It is recommended to store your images in a private registry which is
-protected by credentials and is not exposed to the internet. This will
-give you greater control over who has access to your images. 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.
+The following principles are recommended:
-Additionally, by referencing images from a private repository, you are
-able to minimize the impact of public images changing and breaking your
-security model or CI/CD workflow. If you depend on a public image and it
-is removed, your application can not be deployed again until a
-replacement is found. If you pull the public images to the private
-repository, in addition to security validation, you are also able to
-ensure that your application can always be deployed.
-
-### Image Signing
-
-Image signing also provides a means of validating where a container
-image came from, checking that the image has not been tampered with, and
-setting policies to determine which validated images you will allow to
-be pulled to your systems. Several projects aim to help with the problem
-of ensuring the provenance of the application software running in a
-deployment:
-
-- The TUF project, and its implementation Notary, use signing to ensure the integrity of an image---that is, to make sure that the image retrieved from a registry at deployment time is the correct version as signed by a trusted authority. The Portieris admission controller can prevent images from being deployed if they don't have a valid Notary signature.
-
-- Grafeas is another approach to storing and assuring image metadata, including signatures to validate image integrity.
+| Principle | Description |
+| --- | --- |
+| **Single Concern** |
Containers should address a single concern and do it well.
Use patterns like [sidecar](https://learn.microsoft.com/en-us/azure/architecture/patterns/sidecar) and [init-containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) to address multiple concerns.
This promotes reusability and replaceability
|
+| **Immutable Container Images** |
Container images should be immutable and not contain any environment-specific configuration.
Separate application code from configuration.
|
+| **Self-Contained Image** |
Container images should be self-contained and not rely on external dependencies.
Minimize the attack surface by using minimal images.
|
+| **Lifecycle Conformance** |
React to lifecycle events like readiness, liveness, and termination.
|
+| **Process Disposability** |
Containers should be stateless and externalize state to a persistent data store.
Minimize startup time by reducing the amount of work done on container startup.
|
-- The in-toto project provides a framework to protect the integrity of the components installed into an image, and the tests they have passed.
+## 5.6 Securing Container Images
-- Commercial security solutions can also add validation that the image being deployed is a precisely approved version that matches your policies.
+The following table provides a list of considerations when it comes to securing container images:
-### Container Registry Scanning
+| Consideration | Description |
+| --- | --- |
+| **Image Signing** |
Use image signing to validate the provenance of the application software running in a deployment.
For self-managed containers use a tool such as [Sigstore](https://github.com/sigstore/cosign), [Notary](https://github.com/notaryproject/notaryproject#the-notary-v2-journey), or [Docker Content Trust](https://docs.docker.com/engine/security/trust/) to store and assure image metadata.
For cloud-hosted images, see your cloud provider's documentation for signing images.
|
+| **Software Bill of Materials (SBOM)** |
Include a software bill of materials (SBOM) with your container image to provide transparency into the components and dependencies of the image.
|
+| **Scan Images for Vulnerabilities** |
Use a container image scanner to inspect packages and report on known vulnerabilities.
Scan third-party container images as well as the ones built by your organization.
Re-scan images on a regular basis to detect new vulnerabilities.
|
+| **Patch Container Image** |
Update the container to use a repaired version of the package, when a vulnerable package is discovered.
Automate the build process through a CI pipeline.
|
+| **Container Image Storage** |
Store images in a private registry that is protected by credentials and not exposed to the internet.
Minimize the impact of public images changing by referencing images from a private repository.
|
-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).
+The following figure illustrates the system components, activities, and artifacts involved in securing container images.
-A registry scanner can scan new images and periodically scan existing
-images to identify potential vulnerabilities, generate alerts and block
-the use of untrusted images and assist you in maintaining a secure and
-high-quality collection of images.
+
-For adequate security, a registry should also include a way of auditing
-container images for outdated code and known vulnerabilities and
-identifying outdated containers based on the audit results.
+![A diagram illustrating a container security pipeline. It shows the flow of activities and artifacts between system components: CI/CD services, container registry, and various security tools. The pipeline includes stages for building, scanning, patching, storing, and signing container images, as well as generating Software Bill of Materials (SBOMs).](../media/image_11.png)
+_Figure 5-6 - Securing Container Images_
## 5.7 Observability
-### Health Check and Auto Healing
-
-The application should expose APIs for the runtime environment to
-observe the container health and act accordingly. This API could be used
-by Liveness/Readiness probes of Kubernetes to make a service more robust
-and more resilient, by reducing operational issues and improving the
-quality of service.
-
-In practical terms, at a very minimum, your containerized application
-must provide APIs for health checks---liveness and readiness. Kubernetes
-uses liveness probes to know when to restart a container. If a container
-is unresponsive---perhaps the application is deadlocked due to a
-multi-threading defect---restarting the container can make the
-application more available, despite the defect.
-
-Kubernetes uses *readiness* probes to decide when the container is
-available for accepting traffic. The readiness probe is used to control
-which pods are used as the backends for a service. A pod is considered
-ready when all of its containers are ready.
-
-![](../media/image_7.png)
-
-### Logging
-
-Application and systems logs can help you understand what is happening
-inside your cluster. The logs are particularly useful for debugging
-problems and monitoring cluster activity. The easiest logging method for
-containerized applications is to write to the standard output and
-standard error streams.
-
-The native functionality provided by a container engine is usually not
-enough for a complete logging solution. For example, if a container
-crashes, a pod is evicted, or a node dies, you'll usually still want to
-access your application's logs. As such, logs should have a separate
-storage and lifecycle independent of nodes, pods, or containers. This
-concept is called *cluster-level-logging*. Cluster-level logging
-requires a separate backend to store, analyze, and query logs.
-Kubernetes provides no native storage solution for log data, but you can
-integrate many existing logging solutions (such as ELK, Graylog, etc)
-into your Kubernetes cluster.
-
-The logging is a platform concern, not a developer one; we recommend not
-to use libraries inside the micro-services to programmatically ship logs
-to a backend logging solution.
-
-### Monitoring and Custom Metrics
-
-The observability metrics should be used that give the operations team
-the ability to determine if the production deployment is functioning
-correctly. It's important to note that monitoring in this section does
-not include system metrics (i.e. cpu, memory, disk monitoring). While
-these metrics are important, they do not specifically point to an issue
-with the deployed application/service. The important elements to catch
-in application monitoring are:
-
-- Is the application down?
+Observability is a measure of how well internal states of a system can be inferred from knowledge of its external outputs. In the context of microservices, observability is the ability to understand the internal state of the system by observing the outputs of its components. Observability is a key requirement for microservices, as it allows you to monitor, debug, and optimize your services.
-- Are there performance issues with the newly deployed application?
+The following table lists the considerations when it comes to observability in microservices:
-- Is there high latency?
-
-- Are there application errors?
-
-- What is your team's ability to deliver software changes?
-
-Typical metrics that are important in this context are:
-
-- up/down status of service
-
-- Throughput of application and how much it deviates from "normal"
-
-- HTTP or application errors (4xx, 5xx)
-
-- Latency of application and how much it deviates from "normal"
-
-- How many deployments are failing/succeeding
-
-- How long builds are taking
-
-### Tracing
-
-One of the biggest challenges with micro-services is the observability in
-a distributed system. Tools such as Jaeger, which implements the
-Opentracing standard, provides cluster users the ability to view, for
-each transaction, the latency encountered on every instrumented
-application or service (e.g. database, queue, ingress) including
-"databags" that can be defined by a developer for troubleshooting
-purposes.
-
-Tracing defines a *trace* which represents the life of a request in a
-distributed system. A *trace* is composed of one or multiple *spans*,
-which represents an individual unit of work (e.g. do a database lookup
-using a SELECT statement). A global ID is assigned to a trace and is
-propagated to each of the spans that make up the *trace*. This allows a
-tracing system, like Jaeger, to enable a detailed view of issues and
-latency if ever an issue is detected. The following image shows these
-concepts visually:
-
-![](../media/image_6.png)
+| Consideration | Description |
+| --- | --- |
+| **Health Check and Auto Healing** |
Expose APIs for the runtime environment to observe the container health and act accordingly.
Use _liveness_ and _readiness_ probes to make a service more robust and resilient.
|
+| **Logging** |
Write logs to standard output and standard error streams.
Use a separate storage and lifecycle for logs.
|
+| **Monitoring and Custom Metrics** |
Use observability metrics to determine if the production deployment is functioning correctly.
Monitor application health, performance, and availability.
|
+| **Tracing** |
Use tracing to view the latency encountered on every instrumented application or service.
Implement a trace that represents the life of a request in a distributed system.
|
+| **Anomaly Detection** |
Use AI-supported tools to detect anomalies in the system.
Use anomaly detection to identify performance issues and security threats.
|
## 5.8 Secrets Management
-Secrets management is a critical component of container security. A
-secret, in the context of containers, is any information that will put
-your organization, customer or application at risk if exposed to an
-unauthorized person or entity. This includes API keys, ssh keys,
-passwords, etc.
-
-Micro-services brings with it a host of security and secrets management
-challenges.
-
-- Each micro-service has its own database and credentials, thereby increasing the number of secrets to be managed.
-
-- Several developers & operators and applications have access to the database, thus making certificate management, credential storage, API keys etc. extremely difficult to manage.
-
-- With automated micro-service deployment, there are additional credentials for creation of resources (mostly in cloud), access to code and artifact repository, machine credentials to install components, etc.
-
-There is a need for secrets to be managed centrally for an application
-architecture so the micro-services model can effectively manage secrets
-and handle security breaches by adhering to these must-dos:
+Secrets management is a critical component of container security. A secret, in the context of containers, is any information that will put your organization, customer or application at risk if exposed to an unauthorized person or entity. This includes API keys, ssh keys, passwords, etc.
-- Secure storage of various type of secrets (API Token, Keys, Certificates, username & passwords) at rest
+The following table lists the considerations when it comes to secrets management in microservices:
-- Reliable API based access to secrets
-
-- Dynamic secret distribution for automated encryption and authentication of keys
-
-- Full Audit of access to secrets.
-
-- Multi-level role based access to secrets
-
-- Centralized revocation of secrets and redistribution\
-
-![](../media/image_11.png)
-
-Kubernetes offers the **Secret** object to solve some of these
-challenges. It provides basic security capabilities such as:
-
-- Enabling encryption at rest
-
-- Defining authorization policies
-
-- White listing access to specific container instances
-
-The Kubernetes project however
-[documented](https://kubernetes.io/docs/concepts/configuration/secret/#security-properties)
-several security risks affecting the built-in Kubernetes secrets
-mechanism, which users should pay attention to:
-
-- Securing etcd --- secret data is stored in etcd. By default, etcd data is not encrypted and neither are your secrets. You should enable encryption at rest, limit access to etcd to admin users only, and safely dispose of disks where etcd data was formerly stored.
-
-- Users who consume a secret can see its value---any user who creates a pod that uses a secret has access to that secret, even if the API Server policy does not allow the user to view the secret.
-
-- Root exploit --- anyone with root access on any node can read any secret, because they can impersonate the kubelet. Kubernetes does not currently send secrets on a "need to know" basis; it exposes secrets to anyone on any node with root access.
+| Consideration | Description |
+| --- | --- |
+| **Secure Storage** |
Store secrets in a secure location that is encrypted at rest.
Use a **secret management tool** to store and retrieve secrets.
|
+| **Dynamic Secret Distribution** |
Use dynamic secrets to automate encryption and authentication of keys.
|
+| **Access Control** |
Implement multi-level role-based access to secrets.
|
+| **Audit** |
Log all access to secrets.
|
+| **Secret Rotation** |
Rotate secrets frequently to reduce the risk of compromise.
|
### Secret Management Tools
-Here are some popular tools that can help you achieve better security
-and usability for secrets. Their primary value is that they provide a
-centralized, robust mechanism for encrypting secrets and granting access
-to secrets. All these tools support Kubernetes, but they are not
-purpose-built for container workloads.
-
Secret management solutions fall into two broad categories:
-- Cloud provider tools --- including [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/), [Google Cloud Platform KMS](https://cloud.google.com/kms/) and [Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/)---help encrypt secrets within each cloud environment, automatically rotate secret values, manage access to secrets with policies, and perform central auditing of secrets.
-
-- Open source tools --- [Hashicorp Vault](https://www.vaultproject.io/) provides secrets management and data protection, with advanced features like dynamic secrets, namespaces, leases, and revocation for secrets data. Other options are [CyberArk](https://www.conjur.org/) (with an open source version called [Conjur](https://www.conjur.org/)) and [Confidant](https://lyft.github.io/confidant/).
-
-To keep your micro-services secrets safe without compromising on security
-and automation
-
-- A secrets hierarchy design should address secrets isolation per application, environment and a fail-proof revocation of secrets when required.
-
-- Access policies and role-based mappings need to be built to support emergencies by making them version controlled and automated.
-
-### Secret Rotation
-
-Secrets that stay the same for a long period of time are more likely to
-be compromised. As more users get access to a secret, it's possible that
-someone has mishandled and leaked it to an unauthorized entity. Secrets
-can be leaked through logs and cache data. They could be shared for
-debugging purposes and not changed or revoked once the debugging is
-complete. They could be cracked by hackers. For all these reasons,
-secrets should be rotated frequently.
-
-### Automate Password Creation
-
-The way passwords and access keys are created is vital to their
-security. Humans manually creating passwords is a recipe for disaster.
-According to Troy Hunt, [85% of passwords are insecure](https://www.troyhunt.com/86-of-passwords-are-terrible-and-other-statistics/).
-The only way to combat bad passwords is to use automated
-machine-generated passwords that are unique and can't be easily cracked.
-Today, most secrets management tools have automated password generation
-as a default feature.
+| Category | Tools |
+| --- | --- |
+| **Cloud Provider Tools** |
|
## 5.9 Continuous Integration/Continuous Deployment (CI/CD)
-### Commit Signing
-
-When you sign a Git commit, you can prove that the code you submitted
-came from you and wasn\'t altered while you were transferring it. You
-also can prove that you submitted the code and not someone else. It
-helps protect you from an attacker who might otherwise inject malicious
-code into your codebase.
-
-### Last Password Protection
-
-Secret management solutions (such as HashiCorp Vault) are reliable tools
-that could be used to store the application secrets. These tools,
-however, need your application to use an authentication mechanism (such
-as certificate) to prove its identity to the secret server. The
-authentication secrets (which is often called the last password) should
-be managed outside of the secret management solutions and be protected.
-The last passwords are often managed manually in the CI/CD tool.
-Therefore, it is important to secure your CI/CD variables and allow a
-few people to have access to them.
-
-### Integrate Security Testing in Pipeline
-
-DevSecOps is the process of integrating security into the entire
-application development process --- when there's an ideal opportunity to
-fortify your app from the inside out against potential threats.
-
-Testing applications in development for potential vulnerabilities is a
-critical element of DevSecOps, as it allows you to identify security
-flaws before they can be exploited. The security testing could be done
-on different levels:
-
-#### Code
-
-##### Static Code Analysis
-
-Static code analysis is a method of code debugging without executing the
-code itself (without running the program). Static analysis can help to
-check if the code adheres to industry best practices and prevent
-malpractices.
-
-##### Dynamic Analysis
-
-Dynamic code analysis is a software testing mechanism that evaluates a
-program during real-time execution. Unlike static code analysis, the
-software needs to be run and used either by a human or by automated
-scripts for tools to be able to perform dynamic code analysis.
-
-##### Third-Party Dependencies
-
-Third-party dependencies make up 80% of the code you deploy to
-production. Many of the libraries we use to develop software depend on
-other libraries. Transitive dependencies lead to a (sometimes) large
-chain of dependencies, some of which might have security
-vulnerabilities.
-
-You can use a scanning program on your source code repository to
-identify vulnerable dependencies. You should scan for vulnerabilities in
-your deployment pipeline, in your primary line of code, in released
-versions of code, and in new code contributions.
-
-Source code scanning can be handled in a number of ways.
-[Github offers some basic security scanning](https://github.com/features/security),
-such as dependency and credential scanning, which can help catch some
-security concerns. Additionally, many languages provide different levels
-of scanning which can be added to your CI process to ensure you are
-taking advantage of the features they make available. For example,
-Python offers the `pipenv check` command, and Ruby offers the `bundle audit`
-command. It is recommended to take a defense in depth approach
-when it comes to securing your source code and the resulting images used
-for deployments.
+Your CI/CD pipeline plays a pivotal role in securing your microservices. The following table lists the considerations when it comes to CI/CD security:
-#### Configuration
-
-##### Images
-
-A good practice is to use automation to scan all images before they are
-stored in a container registry, flagging any images that fail the scan.
-Docker also offers Linter to check Dockerfile syntax and best practice.
-
-##### Kubernetes
-
-There are tools (such as `kube-bench` and `kube-hunter`) that enable the
-DevOps team to verify whether Kubernetes is deployed securely by running
-some checks.
-
-##### Manifests and Templates
-
-Sensitive information should not be stored in pod-type YAML resources
-(deployments, pods, sets, etc.), and sensitive configmaps and secrets
-should be encrypted with tools such as helm secret plugin,
-[git-crypt](https://github.com/AGWA/git-crypt), [sealed secrets](https://github.com/bitnami-labs/sealed-secrets), or
-[cloud provider KMS](https://cloud.google.com/kms/).
-
-Static analysis of YAML configuration can be used to establish a
-baseline for runtime security. [kubesec](https://kubesec.io/) generates
-risk scores for resources.
-
-## 5.10 Infrastructure as Code
-
-Configuration management refers to the process by which all
-configurations of your project are stored, retrieved, uniquely
-identified, and modified.
-
-A configuration is any item that needs to be configured and managed in
-order for the project to be successful. This includes Source code,
-scripts, test data, infrastructure and application configuration,
-libraries, packages, documentation, firewall rules, ...
-
-- Anything that is human readable goes in to the source code repository
-
-- All machine files go in to the artifact repository (binaries, docker images, RPM packages)
-
-Infrastructure as Code (IaC) aims to define the desired state of a
-system as facts, not instructions. With your infra declared as states,
-the infra team is able to version control the system states in Git, and
-you have a single source of truth. This simplifies the auditability of
-changes. All changes to the environments could be audited and tracked by
-looking into the SCM history. Traditionally, IaC is the practice of
-automating the infrastructure required to run your application stack
-through the use of tools such as Terraform, and potentially doing
-configuration management on the deployed infrastructure (VMs) using
-tools such as Ansible.
-
-Configuration Management ensures that the environment provisioning is
-reproducible and traceable. It also enables the team to spin up an
-environment automatically, and makes it easy to roll back to the
-previous version in the case of disaster.
-
-With systems able to be fully described in code and placed under version
-control, systems can be built that continually update themselves to
-reflect the contents of a source code repository. Known as GitOps, this
-approach originally focused on application lifecycle management, but
-projects like Crossplane and Google's Config Connector are applying this
-methodology to the fundamental architecture supporting the application
-deployment.
-
-## References
+| Consideration | Description |
+| --- | --- |
+| **Code Commit Signing** | Sign your commits to prove that the code you submitted came from you and wasn't altered while you were transferring it. |
+| **Use Machine-to-Machine (M2M) Authentication** | Secure access between your CI/CD pipeline and your secret manager, using M2M authentication such as OAuth 2.0. |
+| **Integrate Security Testing in Pipeline** | Integrate security testing into your CI/CD pipeline to identify security flaws before they can be exploited.|
+| **Code analysis and scanning**| Use static code analysis, dynamic analysis, and third-party dependency scanning to identify vulnerabilities. |
-[https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf)
+## 5.10 Infrastructure as Code (IaC)
-[https://owasp.org/](https://owasp.org/)
+Infrastructure as Code (IaC) is the process of managing and provisioning compute infrastructure through machine-readable definition files rather than physically configuring the hardware or by using interactive configuration tools.
-[https://www.redhat.com/en/resources/cloud-native-container-design-whitepaper](https://www.redhat.com/en/resources/cloud-native-container-design-whitepaper)
+The following table lists the considerations when it comes to IaC security:
-[https://www.weave.works/technologies/gitops/](https://www.weave.works/technologies/gitops/)
+| Consideration | Description |
+| --- | --- |
+| **Use IaC Tools** |
Use IaC tools like [Terraform](https://terraform.io/), [OpenTofu](https://opentofu.org/), [Ansible](https://www.ansible.com/), [Azure Resource Manager](https://azure.microsoft.com/en-ca/get-started/azure-portal/resource-manager), [AWS CloudFormation](https://docs.aws.amazon.com/cloudformation/), or [GCP Deployment Manager](https://cloud.google.com/deployment-manager/docs/) to automate the provisioning of infrastructure.
Use IaC tools to define and manage infrastructure in a declarative manner.
|
+| **Secure IaC Configuration** |
Secure your IaC configuration files by using version control, access control, and encryption.
Use a secret management tool to store and retrieve secrets.
|
+| **Automate Security Compliance** |
Automate security compliance checks in your IaC pipeline to ensure that your infrastructure is secure.