UNCLASSIFIED - NO CUI

Skip to content
Snippets Groups Projects
Commit c685c193 authored by Michael McLeroy's avatar Michael McLeroy
Browse files

SKIP UPGRADE Bugs n docs

parent 52d1b0b7
No related branches found
No related tags found
1 merge request!9SKIP UPGRADE Bugs n docs
Showing
with 233 additions and 445 deletions
...@@ -2,6 +2,38 @@ ...@@ -2,6 +2,38 @@
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [1.0.0-bb.6] - 2022-03-02
### Changed
- Added `localhost/*` as another acceptable default AppArmor profile
- Updated metadata in `Chart.yaml`
- Fixed typo for `restrict-capabilities` action in `values.yaml`
- Fixed `disallow-default-namespace` to allow blank namespace in pod controller template, but require pod controller to have a namespace.
- Fixed `restrict-host-path` to ignore pods with no volumes
- Fixed `require-non-root-group` exclusions indentions
- Fixed `disallow-deprecated-apis` matching to work with exclusions
- Updated `disallow-deprecated-apis` with Kubernetes 1.26 deprecations
- Updated `require-requests-equal-limits` to work with Kyverno 1.6.0
- Add `system:service-account-issuer-discovery` to the exclusion list for `disallow-rbac-on-default-serviceaccounts`. Clusters allow service accounts access to discovery.
- Fixed `disallow-rbac-on-default-serviceaccounts` to ignore role bindings without a subject.
- Fixed `require-non-root-user` to allow either `runAsNonRoot: true` or `runAsUser: >0`.
- Fixed `disallow-tolerations` to check pod controllers
- Renamed `require-ro-host-path` to `restrict-host-path-write` and added an `allow` list for paths
- Renamed `restrict-host-path` to `restrict-host-path-mount` to distinguish from `restrict-host-path-write`
- Increased memory allocation for `wait-for-ready` job to avoid OOM errors
- Renamed `disallow-subpath-volumes` to `disallow-shared-subpath-volume-writes` to clarify functionality.
- Fixed `disallow-shared-subpath-volume-writes` to narrow conditions specific to vulnerability
- Fixed `helpers.tpl` match and exclusion to handle `any` and `all` permutations
### Added
- `wait.sh` added to pipeline to wait for all policies to be ready before running helm test
### Removed
- `disallow-host-path` policy overlapped `restrict-volume-types` policy and was removed
## [1.0.0-bb.5] - 2022-02-03 ## [1.0.0-bb.5] - 2022-02-03
### Changed ### Changed
......
...@@ -5,7 +5,8 @@ This repository uses the following conventions: ...@@ -5,7 +5,8 @@ This repository uses the following conventions:
* [Semantic Versioning](https://semver.org/) * [Semantic Versioning](https://semver.org/)
* [Keep a Changelog](https://keepachangelog.com/) * [Keep a Changelog](https://keepachangelog.com/)
* [Conventional Commits](https://www.conventionalcommits.org/) * [Conventional Commits](https://www.conventionalcommits.org/)
* [Cypress](https://www.cypress.io) or shell scripts for testing * [Policy Naming Guide](./docs/naming.md)
* Scripted framework for testing. See the [Testing Documentation](./docs/testing.md) for details.
Development requires the following tools Development requires the following tools
...@@ -20,7 +21,7 @@ To contribute a change: ...@@ -20,7 +21,7 @@ To contribute a change:
1. Label the issue with `status::doing` 1. Label the issue with `status::doing`
1. Create a branch in the repository using your issue number as a prefix 1. Create a branch in the repository using your issue number as a prefix
1. Make changes in code and push to your branch 1. Make changes in code and push to your branch
1. Write tests using [cypress](https://www.cypress.io) and/or shell scripts to cover your changes. 1. Write test cases by following the [testing documentation](docs/testing.md).
1. Make commits using the [Conventional Commits](https://www.conventionalcommits.org/) format 1. Make commits using the [Conventional Commits](https://www.conventionalcommits.org/) format
1. Update `CHANGELOG.md` using the [Keep a Changelog](https://keepachangelog.com) format 1. Update `CHANGELOG.md` using the [Keep a Changelog](https://keepachangelog.com) format
1. Open a merge request into the `main` branch 1. Open a merge request into the `main` branch
......
This diff is collapsed.
apiVersion: v2
name: bigbang-kyverno-policies
description: BigBang compatible Helm chart for Kyverno Policies
type: application
version: 0.1.0
appVersion: 0.1.0
# Big Bang compatible Helm chart
This helm chart deploys Kyverno Policies using the same methods and values as Big Bang.
## Prerequisites
- Kubernetes cluster matching [Big Bang's Prerequisites](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/tree/master/docs/guides/prerequisites)
- [FluxCD](https://fluxcd.io/) running in the cluster
- The [Big Bang git repository](https://repo1.dso.mil/platform-one/big-bang/bigbang) cloned into `~/bigbang`
- [Helm](https://helm.sh/docs/intro/install/)
- [Kyverno](https://kyverno.io) installed on the cluster
## Usage
### Installation
1. Install Big Bang
`helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang ~/bigbang/chart`
1. Install this chart
`helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-kyvernopolicies bigbang`
### Removal
`helm delete -n bigbang bigbang-kyvernopolicies`
{{- define "imagePullSecret" }}
{{- if .Values.registryCredentials -}}
{{- $credType := typeOf .Values.registryCredentials -}}
{{- /* If we have a list, embed that here directly. This allows for complex configuration from configmap, downward API, etc. */ -}}
{{- if eq $credType "[]interface {}" -}}
{{- include "multipleCreds" . | b64enc }}
{{- else if eq $credType "map[string]interface {}" }}
{{- /* If we have a map, treat those as key-value pairs. */ -}}
{{- if and .Values.registryCredentials.username .Values.registryCredentials.password }}
{{- with .Values.registryCredentials }}
{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }}
{{- end }}
{{- end }}
{{- end -}}
{{- end }}
{{- end }}
{{- define "multipleCreds" -}}
{
"auths": {
{{- range $i, $m := .Values.registryCredentials }}
{{- /* Only create entry if resulting entry is valid */}}
{{- if and $m.registry $m.username $m.password }}
{{- if $i }},{{ end }}
"{{ $m.registry }}": {
"username": "{{ $m.username }}",
"password": "{{ $m.password }}",
"email": "{{ $m.email | default "" }}",
"auth": "{{ printf "%s:%s" $m.username $m.password | b64enc }}"
}
{{- end }}
{{- end }}
}
}
{{- end }}
{{/*
Build the appropriate spec.ref.{} given git branch, commit values
*/}}
{{- define "validRef" -}}
{{- if .commit -}}
{{- if not .branch -}}
{{- fail "A valid branch is required when a commit is specified!" -}}
{{- end -}}
branch: {{ .branch | quote }}
commit: {{ .commit }}
{{- else if .semver -}}
semver: {{ .semver | quote }}
{{- else if .tag -}}
tag: {{ .tag }}
{{- else -}}
branch: {{ .branch | quote }}
{{- end -}}
{{- end -}}
{{/*
Build the appropriate git credentials secret for private git repositories
*/}}
{{- define "gitCreds" -}}
{{- if .Values.git.existingSecret -}}
secretRef:
name: {{ .Values.git.existingSecret }}
{{- else if coalesce .Values.git.credentials.username .Values.git.credentials.password .Values.git.credentials.caFile .Values.git.credentials.privateKey .Values.git.credentials.publicKey .Values.git.credentials.knownHosts "" -}}
{{- /* Input validation happens in git-credentials.yaml template */ -}}
secretRef:
name: {{ $.Release.Name }}-git-credentials
{{- end -}}
{{- end -}}
{{/*
Build common set of file extensions to include/exclude
*/}}
{{- define "gitIgnore" -}}
ignore: |
# exclude file extensions
/**/*.md
/**/*.txt
/**/*.sh
!/chart/tests/scripts/*.sh
{{- end -}}
{{/*
Common labels for all objects
*/}}
{{- define "commonLabels" -}}
app.kubernetes.io/instance: "{{ .Release.Name }}"
app.kubernetes.io/version: "{{ .Chart.Version }}"
app.kubernetes.io/part-of: "bigbang"
app.kubernetes.io/managed-by: "flux"
{{- end -}}
{{- define "values-secret" -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ .root.Release.Name }}-{{ .name }}-values
namespace: {{ .root.Release.Namespace }}
type: generic
stringData:
common: |
defaults: {{- toYaml .defaults | nindent 4 }}
overlays: |
{{- toYaml .package.values | nindent 4 }}
{{- end -}}
{{/*
bigbang.addValueIfSet can be used to nil check parameters before adding them to the values.
Expects a list with the following params:
* [0] - (string) <yaml_key_to_add>
* [1] - (interface{}) <value_to_check>
No output is generated if <value> is undefined, however, explicitly set empty values
(i.e. `username=""`) will be passed along. All string fields will be quoted.
Example command:
- `{{ (list "name" .username) | include "bigbang.addValueIfSet" }}`
* When `username: Aniken`
-> `name: "Aniken"`
* When `username: ""`
-> `name: ""`
* When username is not defined
-> no output
*/}}
{{- define "bigbang.addValueIfSet" -}}
{{- $key := (index . 0) }}
{{- $value := (index . 1) }}
{{- /*If the value is explicitly set (even if it's empty)*/}}
{{- if not (kindIs "invalid" $value) }}
{{- /*Handle strings*/}}
{{- if kindIs "string" $value }}
{{- printf "\n%s" $key }}: {{ $value | quote }}
{{- /*Hanldle slices*/}}
{{- else if kindIs "slice" $value }}
{{- printf "\n%s" $key }}:
{{- range $value }}
{{- if kindIs "string" . }}
{{- printf "\n - %s" (. | quote) }}
{{- else }}
{{- printf "\n - %v" . }}
{{- end }}
{{- end }}
{{- /*Handle other types (no quotes)*/}}
{{- else }}
{{- printf "\n%s" $key }}: {{ $value }}
{{- end }}
{{- end }}
{{- end -}}
{{- $pkg := "kyvernopolicies" }}
{{- if (get .Values $pkg).enabled }}
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: {{ $pkg }}
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ $pkg }}
{{- include "commonLabels" . | nindent 4}}
spec:
interval: {{ .Values.flux.interval }}
url: {{ (get .Values $pkg).git.repo }}
ref:
{{- include "validRef" (get .Values $pkg).git | nindent 4 }}
{{ include "gitIgnore" . }}
{{- include "gitCreds" . | nindent 2 }}
{{- end }}
\ No newline at end of file
{{- $pkg := "kyvernopolicies" }}
{{- $fluxSettings := merge (get .Values $pkg).flux .Values.flux -}}
{{- if (get .Values $pkg).enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: {{ $pkg }}
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ $pkg }}
{{- include "commonLabels" . | nindent 4}}
spec:
targetNamespace: kyverno
chart:
spec:
chart: {{ (get .Values $pkg).git.path }}
interval: 5m
sourceRef:
kind: GitRepository
name: {{ $pkg }}
namespace: {{ .Release.Namespace }}
{{- toYaml $fluxSettings | nindent 2 }}
{{- if (get .Values $pkg).postRenderers }}
postRenderers:
{{ toYaml (get .Values $pkg).postRenderers | nindent 4 }}
{{- end }}
valuesFrom:
- name: {{ .Release.Name }}-{{ $pkg }}-values
kind: Secret
valuesKey: "common"
- name: {{ .Release.Name }}-{{ $pkg }}-values
kind: Secret
valuesKey: "defaults"
- name: {{ .Release.Name }}-{{ $pkg }}-values
kind: Secret
valuesKey: "overlays"
{{- end }}
{{- $pkg := "kyvernopolicies" }}
{{- define "bigbang.defaults.kyvernopolicies" -}}
{{- end }}
{{- if (get .Values $pkg).enabled }}
{{- include "values-secret" (dict "root" $ "package" (get .Values $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }}
{{- end }}
kyverno:
enabled: true
git:
repo: https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/kyverno
branch: initial
path: chart
flux: {}
kyvernopolicies:
enabled: true
git:
repo: https://repo1.dso.mil/platform-one/big-bang/apps/sandbox/kyverno-policies
branch: initial
path: chart
flux: {}
# Network Policies
networkPolicies:
enabled: false
# Istio
istio:
enabled: true
# Gatekeeper
gatekeeper:
enabled: false
clusterAuditor:
enabled: false
# Logging
eckoperator:
enabled: false
logging:
enabled: false
fluentbit:
enabled: false
# Monitoring
monitoring:
enabled: true
# Other Tools
jaeger:
enabled: false
kiali:
enabled: false
twistlock:
enabled: false
\ No newline at end of file
apiVersion: v1 apiVersion: v2
name: kyverno-policies name: kyverno-policies
version: 1.0.0-bb.5 version: 1.0.0-bb.6
appVersion: 1.0.0
icon: https://github.com/kyverno/kyverno/raw/main/img/logo.png icon: https://github.com/kyverno/kyverno/raw/main/img/logo.png
description: Collection of Kyverno security and best-practice policies for Kyverno description: Collection of Kyverno security and best-practice policies for Kyverno
keywords: keywords:
- kubernetes - kyverno
- nirmata - nirmata
- policy agent - policy agent
- validating webhook - policies
- admissions controller
home: https://kyverno.io/policies/ home: https://kyverno.io/policies/
sources: sources:
- https://github.com/kyverno/policies - https://github.com/kyverno/policies
engine: gotpl
kubeVersion: ">=1.10.0-0"
dependencies: dependencies:
- name: gluon - name: gluon
version: 0.2.5 version: 0.2.5
repository: oci://registry.dso.mil/platform-one/big-bang/apps/library-charts/gluon repository: oci://registry.dso.mil/platform-one/big-bang/apps/library-charts/gluon
\ No newline at end of file annotations:
bigbang.dev/applicationVersions: |
- Kyverno Policies: 1.0.0
\ No newline at end of file
...@@ -45,41 +45,58 @@ webhookTimeoutSeconds: {{ $webhookTimeoutSeconds }} ...@@ -45,41 +45,58 @@ webhookTimeoutSeconds: {{ $webhookTimeoutSeconds }}
{{/* Match key/value. Expects name of policy in .name and default kind in .kind as a list */}} {{/* Match key/value. Expects name of policy in .name and default kind in .kind as a list */}}
{{- define "kyverno-policies.match" -}} {{- define "kyverno-policies.match" -}}
{{- $policyMatch := (dig .name "match" nil .Values.policies) -}} {{- $policyMatch := (dig .name "match" nil .Values.policies) -}}
{{- if not (kindIs "map" $policyMatch) -}}
{{- $policyMatch = (dict "any" $policyMatch) -}}
{{- end -}}
match: match:
{{- if $policyMatch -}} all:
{{- toYaml $policyMatch | nindent 2 -}}
{{- else }}
any:
- resources: - resources:
kinds: kinds:
{{- toYaml .kinds | nindent 6 -}} {{- toYaml .kinds | nindent 6 -}}
{{- end -}} {{- if $policyMatch }}
{{- if $policyMatch.all }}
{{- toYaml $policyMatch.all | nindent 2 }}
{{- end }}
{{- if $policyMatch.any }}
any:
{{- toYaml $policyMatch.any | nindent 2 }}
{{- end }}
{{- end }}
{{- end -}} {{- end -}}
{{/* Exclude key/value. Expects name of policy in .name */}} {{/* Exclude key/value. Expects name of policy in .name */}}
{{- define "kyverno-policies.exclude" -}} {{- define "kyverno-policies.exclude" -}}
{{- $globalExclude := .Values.exclude -}} {{- $globalExclude := .Values.exclude -}}
{{- $policyExclude := (dig .name "exclude" nil .Values.policies) -}} {{- if not (kindIs "map" $globalExclude) -}}
{{- if or $globalExclude $policyExclude }} {{- $globalExclude = (dict "any" $globalExclude) -}}
{{- end -}}
{{- $policyExclude := (dig .name "exclude" nil .Values.policies) -}}
{{- if not (kindIs "map" $policyExclude) -}}
{{- $policyExclude := (dict "any" $policyExclude) -}}
{{- end -}}
{{- if or $globalExclude $policyExclude }}
exclude: exclude:
{{- if or $globalExclude.all $policyExclude.all }}
all:
{{- if $globalExclude.all }}
{{- toYaml $globalExclude.all | nindent 2 }}
{{- end }}
{{- if $policyExclude.all }}
{{- toYaml $policyExclude.all | nindent 2 }}
{{- end }}
{{- end }}
{{- if or $globalExclude.any $policyExclude.any }}
any: any:
{{- if $globalExclude -}} {{- if $globalExclude.any }}
{{- if kindIs "map" $globalExclude -}} {{- toYaml $globalExclude.any | nindent 2 }}
{{- toYaml $globalExclude.any | nindent 2 -}} {{- end }}
{{- else -}} {{- if $policyExclude.any }}
{{- toYaml $globalExclude | nindent 2 -}} {{- toYaml $policyExclude.any | nindent 2 }}
{{- end -}} {{- end }}
{{- end -}} {{- end }}
{{- if $policyExclude -}}
{{- if kindIs "map" $policyExclude -}}
{{- toYaml $policyExclude.any | nindent 2 -}}
{{- else -}}
{{- toYaml $policyExclude | nindent 2 -}}
{{- end -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- end -}}
{{/* Add context for configMap to rule. Expects name of policy in .name */}} {{/* Add context for configMap to rule. Expects name of policy in .name */}}
{{- define "kyverno-policies.context" -}} {{- define "kyverno-policies.context" -}}
......
...@@ -8,13 +8,15 @@ metadata: ...@@ -8,13 +8,15 @@ metadata:
policies.kyverno.io/title: Disallow Default Namespace policies.kyverno.io/title: Disallow Default Namespace
policies.kyverno.io/category: Best Practices (Security) policies.kyverno.io/category: Best Practices (Security)
policies.kyverno.io/severity: {{ default "low" (dig $name "severity" nil .Values.policies) }} policies.kyverno.io/severity: {{ default "low" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/subject: Pod policies.kyverno.io/subject: Pod, Deployment, StatefulSet, DaemonSet, Jobs, CronJobs
policies.kyverno.io/description: >- policies.kyverno.io/description: >-
Kubernetes Namespaces are an optional feature that provide a way to segment and Kubernetes Namespaces are an optional feature that provide a way to segment and
isolate cluster resources across multiple applications and users. As a best isolate cluster resources across multiple applications and users. As a best
practice, workloads should be isolated with Namespaces. Namespaces should be required practice, workloads should be isolated with Namespaces. Namespaces should be required
and the default (empty) Namespace should not be used. This policy validates that Pods and the default (empty) Namespace should not be used. This policy validates that resources
specify a Namespace name other than `default`. specify a Namespace name other than `default`.
# Pods will be deployed in same namespace as Pod controller if not specified in template
pod-policies.kyverno.io/autogen-controllers: none
labels: {{- include "kyverno-policies.labels" . | nindent 4 }} labels: {{- include "kyverno-policies.labels" . | nindent 4 }}
spec: spec:
{{- include "kyverno-policies.webhookTimeoutSeconds" (merge (dict "name" $name) .) | indent 2 }} {{- include "kyverno-policies.webhookTimeoutSeconds" (merge (dict "name" $name) .) | indent 2 }}
...@@ -22,7 +24,7 @@ spec: ...@@ -22,7 +24,7 @@ spec:
rules: rules:
- name: validate-namespace - name: validate-namespace
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }} {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod")) .) | nindent 4 }} {{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod" "Deployment" "StatefulSet" "DaemonSet" "Job" "CronJob")) .) | nindent 4 }}
validate: validate:
message: "Using 'default' namespace is not allowed." message: "Using 'default' namespace is not allowed."
pattern: pattern:
...@@ -30,7 +32,7 @@ spec: ...@@ -30,7 +32,7 @@ spec:
namespace: "!default" namespace: "!default"
- name: require-namespace - name: require-namespace
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }} {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod")) .) | nindent 4 }} {{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod" "Deployment" "StatefulSet" "DaemonSet" "Job" "CronJob")) .) | nindent 4 }}
validate: validate:
message: "A namespace is required." message: "A namespace is required."
pattern: pattern:
......
...@@ -21,56 +21,68 @@ spec: ...@@ -21,56 +21,68 @@ spec:
validationFailureAction: {{ default (dig $name "validationFailureAction" nil .Values.policies) .Values.validationFailureAction }} validationFailureAction: {{ default (dig $name "validationFailureAction" nil .Values.policies) .Values.validationFailureAction }}
rules: rules:
- name: validate-v1-22-removals - name: validate-v1-22-removals
{{- include "kyverno-policies.context" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }} {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
match: match:
resources: any:
kinds: - resources:
- admissionregistration.k8s.io/v1beta1/ValidatingWebhookConfiguration kinds:
- admissionregistration.k8s.io/v1beta1/MutatingWebhookConfiguration - admissionregistration.k8s.io/v1beta1/ValidatingWebhookConfiguration
- apiextensions.k8s.io/v1beta1/CustomResourceDefinition - admissionregistration.k8s.io/v1beta1/MutatingWebhookConfiguration
- apiregistration.k8s.io/v1beta1/APIService - apiextensions.k8s.io/v1beta1/CustomResourceDefinition
- authentication.k8s.io/v1beta1/TokenReview - apiregistration.k8s.io/v1beta1/APIService
- authorization.k8s.io/v1beta1/SubjectAccessReview - authentication.k8s.io/v1beta1/TokenReview
- authorization.k8s.io/v1beta1/LocalSubjectAccessReview - authorization.k8s.io/v1beta1/SubjectAccessReview
- authorization.k8s.io/v1beta1/SelfSubjectAccessReview - authorization.k8s.io/v1beta1/LocalSubjectAccessReview
- certificates.k8s.io/v1beta1/CertificateSigningRequest - authorization.k8s.io/v1beta1/SelfSubjectAccessReview
- coordination.k8s.io/v1beta1/Lease - certificates.k8s.io/v1beta1/CertificateSigningRequest
- extensions/v1beta1/Ingress - coordination.k8s.io/v1beta1/Lease
- networking.k8s.io/v1beta1/Ingress - extensions/v1beta1/Ingress
- networking.k8s.io/v1beta1/IngressClass - networking.k8s.io/v1beta1/Ingress
- rbac.authorization.k8s.io/v1beta1/ClusterRole - networking.k8s.io/v1beta1/IngressClass
- rbac.authorization.k8s.io/v1beta1/ClusterRoleBinding - rbac.authorization.k8s.io/v1beta1/ClusterRole
- rbac.authorization.k8s.io/v1beta1/Role - rbac.authorization.k8s.io/v1beta1/ClusterRoleBinding
- rbac.authorization.k8s.io/v1beta1/RoleBinding - rbac.authorization.k8s.io/v1beta1/Role
- scheduling.k8s.io/v1beta1/PriorityClass - rbac.authorization.k8s.io/v1beta1/RoleBinding
- storage.k8s.io/v1beta1/CSIDriver - scheduling.k8s.io/v1beta1/PriorityClass
- storage.k8s.io/v1beta1/CSINode - storage.k8s.io/v1beta1/CSIDriver
- storage.k8s.io/v1beta1/StorageClass - storage.k8s.io/v1beta1/CSINode
- storage.k8s.io/v1beta1/VolumeAttachment - storage.k8s.io/v1beta1/StorageClass
- storage.k8s.io/v1beta1/VolumeAttachment
validate: validate:
message: >- message: >-
{{ "{{" }} request.object.apiVersion {{ "}}" }}/{{ "{{" }} request.object.kind {{ "}}" }} is deprecated and will be removed in v1.22. {{ "{{" }} request.object.apiVersion {{ "}}" }}/{{ "{{" }} request.object.kind {{ "}}" }} is deprecated and will be removed in v1.22.
See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/ See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/
deny: {{ "{}" }} deny: {{ "{}" }}
- name: validate-v1-25-removals - name: validate-v1-25-removals
{{- include "kyverno-policies.context" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }} {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
match: match:
resources: any:
kinds: - resources:
- batch/v1beta1/CronJob kinds:
- discovery.k8s.io/v1beta1/EndpointSlice - batch/v1beta1/CronJob
- events.k8s.io/v1beta1/Event - discovery.k8s.io/v1beta1/EndpointSlice
- policy/v1beta1/PodDisruptionBudget - events.k8s.io/v1beta1/Event
- policy/v1beta1/PodSecurityPolicy - autoscaling/v2beta1/HorizontalPodAutoscaler
- node.k8s.io/v1beta1/RuntimeClass - policy/v1beta1/PodDisruptionBudget
- policy/v1beta1/PodSecurityPolicy
- node.k8s.io/v1beta1/RuntimeClass
validate: validate:
message: >- message: >-
{{ "{{" }} request.object.apiVersion {{ "}}" }}/{{ "{{" }} request.object.kind {{ "}}" }} is deprecated and will be removed in v1.25. {{ "{{" }} request.object.apiVersion {{ "}}" }}/{{ "{{" }} request.object.kind {{ "}}" }} is deprecated and will be removed in v1.25.
See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/ See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/
deny: {{ "{}" }} deny: {{ "{}" }}
- name: validate-v1-26-removals
--- {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
{{ include "kyverno-policies.configmap" (merge (dict "name" $name) .) }} match:
{{- end -}} any:
- resources:
kinds:
- flowcontrol.apiserver.k8s.io/v1beta1/FlowSchema
- flowcontrol.apiserver.k8s.io/v1beta1/PriorityLevelConfiguration
- autoscaling/v2beta2/HorizontalPodAutoscaler
validate:
message: >-
{{ "{{" }} request.object.apiVersion {{ "}}" }}/{{ "{{" }} request.object.kind {{ "}}" }} is deprecated and will be removed in v1.26.
See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/
deny: {{ "{}" }}
{{- end -}}
\ No newline at end of file
{{- $name := "disallow-host-path" }}
{{- if and .Values.enabled (dig $name "enabled" false .Values.policies) }}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ $name }}
annotations:
policies.kyverno.io/title: Disallow Host Path Volumes
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: {{ default "high" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
HostPath volumes let Pods use host directories and volumes in containers.
Using host resources can be used to access shared data or escalate privileges
and should not be allowed. This policy ensures no hostPath volumes are in use.
labels: {{- include "kyverno-policies.labels" . | nindent 4 }}
spec:
{{- include "kyverno-policies.webhookTimeoutSeconds" (merge (dict "name" $name) .) | indent 2 }}
validationFailureAction: {{ default (dig $name "validationFailureAction" nil .Values.policies) .Values.validationFailureAction }}
rules:
- name: host-path
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod")) .) | nindent 4 }}
validate:
message: >-
HostPath volumes are forbidden. The fields spec.volumes[*].hostPath must not be set.
pattern:
spec:
=(volumes):
- X(hostPath): "null"
{{- end -}}
...@@ -6,7 +6,7 @@ metadata: ...@@ -6,7 +6,7 @@ metadata:
name: {{ $name }} name: {{ $name }}
annotations: annotations:
policies.kyverno.io/title: Disallow Istio Injection Bypass policies.kyverno.io/title: Disallow Istio Injection Bypass
policies.kyverno.io/category: Security Best Practice policies.kyverno.io/category: Best Practices (Security)
policies.kyverno.io/severity: {{ default "low" (dig $name "severity" nil .Values.policies) }} policies.kyverno.io/severity: {{ default "low" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/subject: Pods policies.kyverno.io/subject: Pods
policies.kyverno.io/description: >- policies.kyverno.io/description: >-
......
...@@ -6,7 +6,7 @@ metadata: ...@@ -6,7 +6,7 @@ metadata:
name: {{ $name }} name: {{ $name }}
annotations: annotations:
policies.kyverno.io/title: Disallow NodePort Services policies.kyverno.io/title: Disallow NodePort Services
policies.kyverno.io/category: Security Best Practices policies.kyverno.io/category: Best Practices (Security)
policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }} policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/subject: Service policies.kyverno.io/subject: Service
policies.kyverno.io/description: >- policies.kyverno.io/description: >-
......
...@@ -6,7 +6,7 @@ metadata: ...@@ -6,7 +6,7 @@ metadata:
name: {{ $name }} name: {{ $name }}
annotations: annotations:
policies.kyverno.io/title: Disallow Pod Exec policies.kyverno.io/title: Disallow Pod Exec
policies.kyverno.io/category: Security Best Practices policies.kyverno.io/category: Best Practices (Security)
policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }} policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/minversion: 1.4.2 policies.kyverno.io/minversion: 1.4.2
policies.kyverno.io/subject: PodExecOptions policies.kyverno.io/subject: PodExecOptions
......
...@@ -6,7 +6,7 @@ metadata: ...@@ -6,7 +6,7 @@ metadata:
name: {{ $name }} name: {{ $name }}
annotations: annotations:
policies.kyverno.io/title: Disallow RBAC on default Service Accounts policies.kyverno.io/title: Disallow RBAC on default Service Accounts
policies.kyverno.io/category: Security Best Practices policies.kyverno.io/category: Best Practices (Security)
policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }} policies.kyverno.io/severity: {{ default "medium" (dig $name "severity" nil .Values.policies) }}
policies.kyverno.io/subject: RoleBinding,ClusterRoleBinding policies.kyverno.io/subject: RoleBinding,ClusterRoleBinding
# More info: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions # More info: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions
...@@ -27,7 +27,7 @@ spec: ...@@ -27,7 +27,7 @@ spec:
validate: validate:
message: "Adding permissions to the default service account is not allowed." message: "Adding permissions to the default service account is not allowed."
pattern: pattern:
subjects: =(subjects):
- (kind): ServiceAccount - (kind): ServiceAccount
name: "!default" name: "!default"
- name: validate-rbac-on-group - name: validate-rbac-on-group
...@@ -36,7 +36,7 @@ spec: ...@@ -36,7 +36,7 @@ spec:
validate: validate:
message: "Adding permissions to a service account group is not allowed." message: "Adding permissions to a service account group is not allowed."
pattern: pattern:
subjects: =(subjects):
- (kind): Group - (kind): Group
name: "!system:serviceaccounts*" name: "!system:serviceaccounts*"
{{- end -}} {{- end -}}
\ No newline at end of file
{{- $name := "disallow-subpath-volumes" }} {{- $name := "disallow-shared-subpath-volume-writes" }}
{{- if and .Values.enabled (dig $name "enabled" false .Values.policies) }} {{- if and .Values.enabled (dig $name "enabled" false .Values.policies) }}
apiVersion: kyverno.io/v1 apiVersion: kyverno.io/v1
kind: ClusterPolicy kind: ClusterPolicy
...@@ -12,34 +12,48 @@ metadata: ...@@ -12,34 +12,48 @@ metadata:
policies.kyverno.io/description: >- policies.kyverno.io/description: >-
A security issue was discovered in Kubernetes where a user may be able to create a container with A security issue was discovered in Kubernetes where a user may be able to create a container with
subpath volume mounts to access files and directories outside of the volume, including on the host subpath volume mounts to access files and directories outside of the volume, including on the host
filesystem. This policy denies containers that use volume mounts with subpaths. See the CVE filesystem. This policy denies containers that share a volume between containers where at least
for applicable Kubernetes versions. one has write access and at least one is using a subpath.
labels: {{- include "kyverno-policies.labels" . | nindent 4 }} labels: {{- include "kyverno-policies.labels" . | nindent 4 }}
spec: spec:
{{- include "kyverno-policies.webhookTimeoutSeconds" (merge (dict "name" $name) .) | indent 2 }} {{- include "kyverno-policies.webhookTimeoutSeconds" (merge (dict "name" $name) .) | indent 2 }}
validationFailureAction: {{ default (dig $name "validationFailureAction" nil .Values.policies) .Values.validationFailureAction }} validationFailureAction: {{ default (dig $name "validationFailureAction" nil .Values.policies) .Values.validationFailureAction }}
rules: rules:
- name: subpath-volume-mounts - name: deny-shared-writable-volumes-with-subpaths
{{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }} {{- include "kyverno-policies.exclude" (merge (dict "name" $name) .) | indent 4 }}
{{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod")) .) | nindent 4 }} {{- include "kyverno-policies.match" (merge (dict "name" $name "kinds" (list "Pod")) .) | nindent 4 }}
preconditions:
all:
- key: "{{ "{{" }}request.operation{{ "}}" }}"
operator: In
value:
- CREATE
- UPDATE
validate: validate:
message: >- message: >-
Volume mounts with a subPath are forbidden. The fields spec.containers[*].subPath, spec.initContainers[*].subPath, Having two containers share a writable volume and using a subPath is not allowed due to CVE-2021-25741.
spec.ephemeralContainers[*].subPath, spec.containers[*].subPathExpr, spec.initContainers[*].subPathExpr, and See https://security.googleblog.com/2021/12/exploring-container-security-storage.html
spec.ephemeralContainers[*].subPathExpr must not be set. foreach:
pattern: # Check each volume in the Pod
spec: - list: "request.object.spec.volumes"
=(initContainers): deny:
- =(volumeMounts): conditions:
- X(subPath): "null" all:
X(subPathExpr): "null" # The vulnerabiltity requires at least two containers using the same volume
containers: - key: "{{ "{{" }} request.object.spec.[containers[?volumeMounts[?name == '{{ "{{" }}element.name{{ "}}" }}']], initContainers[?volumeMounts[?name == '{{ "{{" }}element.name{{ "}}" }}']], ephemeralContainers[?volumeMounts[?name == '{{ "{{" }}element.name{{ "}}" }}']]][] | length(@) {{ "}}" }}"
- =(volumeMounts): operator: GreaterThanOrEquals
- X(subPath): "null" value: 2
X(subPathExpr): "null" # The vulnerability requires a container that can write to the volume
# Volume mounts with subpaths are not allowed for ephemeral containers, but included here in case it changes - key: "{{ "{{" }} request.object.spec.[containers, initContainers, ephemeralContainers][].volumeMounts[?name == '{{ "{{" }}element.name{{ "}}" }}' && !readOnly][] | length(@) {{ "}}" }}"
=(ephemeralContainers): operator: GreaterThanOrEquals
- =(volumeMounts): value: 1
- X(subPath): "null" # The vulnerability requires a subpath or subpathexpr to be used
X(subPathExpr): "null" - key: "{{ "{{" }} request.object.spec.[containers, initContainers, ephemeralContainers][].volumeMounts[?name == '{{ "{{" }}element.name{{ "}}" }}' && (subPath || subPathExpr)][] | length(@) {{ "}}" }}"
operator: GreaterThanOrEquals
value: 1
# Volumes types of secret, configMap, downwardAPI, and projected are always read-only (even if you set `readOnly: false`)
# See https://github.com/kubernetes/kubernetes/issues/60814 for details on why these are read-only
- key: "{{ "{{" }} element.[configMap, secret, downwardAPI, projected][] | length(@) {{ "}}" }}"
operator: Equals
value: 0
{{- end -}} {{- end -}}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment