Compare languages | The admission-policy-engine module: FAQ

How do I configure alternative security policy management solutions?

Как настроить альтернативные решения по управлению политиками безопасности?

For DKP to work correctly, extended privileges are required to run and operate system component payloads. If you are using some alternative security policy management solution (e. g., Kyverno) instead of the admission-policy-engine module, you have to configure exceptions for the following namespaces:

  • kube-system;
  • all namespaces with the d8-* prefix (e.g., d8-system).

Для корректной работы DKP необходимы расширенные привилегии на запуск и работу полезной нагрузки системных компонентов. Если вместо модуля admission-policy-engine используется альтернативное решение по управлению политиками безопасности (например, Kyverno), необходима настройка исключений для следующих пространств имен:

  • kube-system;
  • все пространства имен с префиксом d8-* (например, d8-system).

How do I extend Pod Security Standards policies?

Как расширить политики Pod Security Standards?

Pod Security Standards respond to the security.deckhouse.io/pod-policy: restricted or security.deckhouse.io/pod-policy: baseline label.

Pod Security Standards реагируют на label security.deckhouse.io/pod-policy: restricted или security.deckhouse.io/pod-policy: baseline.

To extend the Pod Security Standards policy by adding your checks to existing checks, you need to:

  • Create a constraint template for the check (a ConstraintTemplate resource).
  • Bind it to the restricted or baseline policy.

Чтобы расширить политику Pod Security Standards, добавив к существующим проверкам политики свои собственные, необходимо:

  • создать шаблон проверки (ресурс ConstraintTemplate);
  • привязать его к политике restricted или baseline.

Example of the ConstraintTemplate for checking a repository URL of a container image:

Пример шаблона для проверки адреса репозитория образа контейнера:

yaml apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8sallowedrepos spec: crd: spec: names: kind: K8sAllowedRepos validation: openAPIV3Schema: type: object properties: repos: type: array items: type: string targets:

  • target: admission.k8s.gatekeeper.sh rego: | package d8.pod_security_standards.extended

yaml apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8sallowedrepos spec: crd: spec: names: kind: K8sAllowedRepos validation: openAPIV3Schema: type: object properties: repos: type: array items: type: string targets:

  • target: admission.k8s.gatekeeper.sh rego: | package d8.pod_security_standards.extended

violation[{“msg”: msg}] { container := input.review.object.spec.containers[] satisfied := [good | repo = input.parameters.repos[] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf(“container <%v> has an invalid image repo <%v>, allowed repos are %v”, [container.name, container.image, input.parameters.repos]) }

violation[{“msg”: msg}] { container := input.review.object.spec.containers[] satisfied := [good | repo = input.parameters.repos[] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf(“container <%v> has an invalid image repo <%v>, allowed repos are %v”, [container.name, container.image, input.parameters.repos]) }

violation[{“msg”: msg}] { container := input.review.object.spec.initContainers[] satisfied := [good | repo = input.parameters.repos[] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf(“container <%v> has an invalid image repo <%v>, allowed repos are %v”, [container.name, container.image, input.parameters.repos]) }

violation[{“msg”: msg}] { container := input.review.object.spec.initContainers[] satisfied := [good | repo = input.parameters.repos[] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf(“container <%v> has an invalid image repo <%v>, allowed repos are %v”, [container.name, container.image, input.parameters.repos]) }

Example of binding a check to the restricted policy:

Пример привязки проверки к политике restricted:

yaml apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sAllowedRepos metadata: name: prod-repo spec: match: kinds:

  • apiGroups: [””] kinds: [“Pod”] namespaceSelector: matchLabels: security.deckhouse.io/pod-policy: restricted parameters: repos:
  • “mycompany.registry.com”

yaml apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sAllowedRepos metadata: name: prod-repo spec: match: kinds:

  • apiGroups: [””] kinds: [“Pod”] namespaceSelector: matchLabels: security.deckhouse.io/pod-policy: restricted parameters: repos:
  • “mycompany.registry.com”

The example demonstrates the configuration of checking the repository address in the image field for all Pods created in the namespace having the security.deckhouse.io/pod-policy : restricted label. A Pod will not be created if the address in the image field of the Pod does not start with mycompany.registry.com.

Пример демонстрирует настройку проверки адреса репозитория в поле image у всех подов, создающихся в пространстве имен, имеющих label security.deckhouse.io/pod-policy: restricted. Если адрес в поле image создаваемого пода начинается не с mycompany.registry.com, под создан не будет.

The Gatekeeper documentation may find more info about templates and policy language.

Подробнее о шаблонах и языке политик можно узнать в документации Gatekeeper.

Find more examples of checks for policy extension in the Gatekeeper Library.

Больше примеров описания проверок для расширения политики можно найти в библиотеке Gatekeeper.

How to allow some Pod Security Standards policies without disabling whole list?

Как включить одну или несколько политик Pod Security Standards, не отключая весь набор?

To apply only the required security policies without turning off the entire built-in set:

Чтобы применить только нужные политики безопасности, не отключая весь предустановленный набор:

  1. Add the security.deckhouse.io/pod-policy: privileged label to your namespace in order to disable built-in policies.
  2. Create a SecurityPolicy resource that matches the baseline or restricted policy while also editing the list of policies elements as you see fit.
  3. Add a label to your namespace that matches the namespaceSelector in the SecurityPolicy resource. In the examples below, the label is operation-policy.deckhouse.io/baseline-enabled: "true" or operation-policy.deckhouse.io/restricted-enabled: "true".
  1. Добавьте в нужное пространство имён метку: security.deckhouse.io/pod-policy: privileged, чтобы отключить встроенный набор политик.
  2. Создайте ресурс SecurityPolicy, соответствующий уровню baseline или restricted. В секции policies укажите только необходимые вам настройки.
  3. Добавьте в пространство имён дополнительную метку, которая будет соответствовать селектору namespaceSelector в SecurityPolicy. В примерах ниже это operation-policy.deckhouse.io/baseline-enabled: "true" либо operation-policy.deckhouse.io/restricted-enabled: "true"

SecurityPolicy that matches baseline standard:

SecurityPolicy, соответствующая baseline:

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: baseline spec: enforcementAction: Deny policies: allowHostIPC: false allowHostNetwork: false allowHostPID: false allowPrivilegeEscalation: true allowPrivileged: false allowedAppArmor:

  • runtime/default
  • localhost/* allowedCapabilities:
  • AUDIT_WRITE
  • CHOWN
  • DAC_OVERRIDE
  • FOWNER
  • FSETID
  • KILL
  • MKNOD
  • NET_BIND_SERVICE
  • SETFCAP
  • SETGID
  • SETPCAP
  • SETUID
  • SYS_CHROOT allowedHostPaths: [] allowedHostPorts:
  • max: 0 min: 0 allowedProcMount: Default allowedUnsafeSysctls:
  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.ip_unprivileged_port_start
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range
  • net.ipv4.ip_local_reserved_ports
  • net.ipv4.tcp_keepalive_time
  • net.ipv4.tcp_fin_timeout
  • net.ipv4.tcp_keepalive_intvl
  • net.ipv4.tcp_keepalive_probes seLinux:
  • type: “”
  • type: container_t
  • type: container_init_t
  • type: container_kvm_t
  • type: container_engine_t seccompProfiles: allowedProfiles:
  • RuntimeDefault
  • Localhost
  • undefined
  • ’’ allowedLocalhostFiles:
  • ‘*’ match: namespaceSelector: labelSelector: matchLabels: operation-policy.deckhouse.io/baseline-enabled: “true”

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: baseline spec: enforcementAction: Deny policies: allowHostIPC: false allowHostNetwork: false allowHostPID: false allowPrivilegeEscalation: true allowPrivileged: false allowedAppArmor:

  • runtime/default
  • localhost/* allowedCapabilities:
  • AUDIT_WRITE
  • CHOWN
  • DAC_OVERRIDE
  • FOWNER
  • FSETID
  • KILL
  • MKNOD
  • NET_BIND_SERVICE
  • SETFCAP
  • SETGID
  • SETPCAP
  • SETUID
  • SYS_CHROOT allowedHostPaths: [] allowedHostPorts:
  • max: 0 min: 0 allowedProcMount: Default allowedUnsafeSysctls:
  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.ip_unprivileged_port_start
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range
  • net.ipv4.ip_local_reserved_ports
  • net.ipv4.tcp_keepalive_time
  • net.ipv4.tcp_fin_timeout
  • net.ipv4.tcp_keepalive_intvl
  • net.ipv4.tcp_keepalive_probes seLinux:
  • type: “”
  • type: container_t
  • type: container_init_t
  • type: container_kvm_t
  • type: container_engine_t seccompProfiles: allowedProfiles:
  • RuntimeDefault
  • Localhost
  • undefined
  • ’’ allowedLocalhostFiles:
  • ‘*’ match: namespaceSelector: labelSelector: matchLabels: operation-policy.deckhouse.io/baseline-enabled: “true”

SecurityPolicy that matches restricted standard:

SecurityPolicy, соответствующая restricted:

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: restricted spec: enforcementAction: Deny policies: allowHostIPC: false allowHostNetwork: false allowHostPID: false allowPrivilegeEscalation: false allowPrivileged: false allowedAppArmor:

  • runtime/default
  • localhost/* allowedCapabilities:
  • NET_BIND_SERVICE allowedHostPaths: [] allowedHostPorts:
  • max: 0 min: 0 allowedProcMount: Default allowedUnsafeSysctls:
  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.ip_unprivileged_port_start
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range
  • net.ipv4.ip_local_reserved_ports
  • net.ipv4.tcp_keepalive_time
  • net.ipv4.tcp_fin_timeout
  • net.ipv4.tcp_keepalive_intvl
  • net.ipv4.tcp_keepalive_probes allowedVolumes:
  • configMap
  • csi
  • downwardAPI
  • emptyDir
  • ephemeral
  • persistentVolumeClaim
  • projected
  • secret requiredDropCapabilities:
  • ALL runAsUser: rule: MustRunAsNonRoot seLinux:
  • type: “”
  • type: container_t
  • type: container_init_t
  • type: container_kvm_t
  • type: container_engine_t seccompProfiles: allowedProfiles:
  • RuntimeDefault
  • Localhost allowedLocalhostFiles:
  • ‘*’ match: namespaceSelector: labelSelector: matchLabels: operation-policy.deckhouse.io/restricted-enabled: “true”

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: restricted spec: enforcementAction: Deny policies: allowHostIPC: false allowHostNetwork: false allowHostPID: false allowPrivilegeEscalation: false allowPrivileged: false allowedAppArmor:

  • runtime/default
  • localhost/* allowedCapabilities:
  • NET_BIND_SERVICE allowedHostPaths: [] allowedHostPorts:
  • max: 0 min: 0 allowedProcMount: Default allowedUnsafeSysctls:
  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.ip_unprivileged_port_start
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range
  • net.ipv4.ip_local_reserved_ports
  • net.ipv4.tcp_keepalive_time
  • net.ipv4.tcp_fin_timeout
  • net.ipv4.tcp_keepalive_intvl
  • net.ipv4.tcp_keepalive_probes allowedVolumes:
  • configMap
  • csi
  • downwardAPI
  • emptyDir
  • ephemeral
  • persistentVolumeClaim
  • projected
  • secret requiredDropCapabilities:
  • ALL runAsUser: rule: MustRunAsNonRoot seLinux:
  • type: “”
  • type: container_t
  • type: container_init_t
  • type: container_kvm_t
  • type: container_engine_t seccompProfiles: allowedProfiles:
  • RuntimeDefault
  • Localhost allowedLocalhostFiles:
  • ‘*’ match: namespaceSelector: labelSelector: matchLabels: operation-policy.deckhouse.io/restricted-enabled: “true”

What if there are multiple policies (operational or security) that are applied to the same object?

Что, если несколько политик (операционных или безопасности) применяются на один объект?

In that case the object’s specification have to fulfil all the requirements imposed by the policies.

В таком случае необходимо, чтобы конфигурация объекта соответствовала всем политикам, которые на него распространяются.

For example, consider the following two security policies:

Например, рассмотрим две следующие политики безопасности:

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: foo spec: enforcementAction: Deny match: namespaceSelector: labelSelector: matchLabels: name: test policies: readOnlyRootFilesystem: true requiredDropCapabilities:

  • MKNOD

    apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: bar spec: enforcementAction: Deny match: namespaceSelector: labelSelector: matchLabels: name: test policies: requiredDropCapabilities:

  • NET_BIND_SERVICE

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: foo spec: enforcementAction: Deny match: namespaceSelector: labelSelector: matchLabels: name: test policies: readOnlyRootFilesystem: true requiredDropCapabilities:

  • MKNOD

    apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: bar spec: enforcementAction: Deny match: namespaceSelector: labelSelector: matchLabels: name: test policies: requiredDropCapabilities:

  • NET_BIND_SERVICE

Then, in order to fulfill the requirements of the above security policies, the following settings must be set in a container specification:

Тогда для выполнения требований приведенных политик безопасности в спецификации контейнера нужно указать:

yaml securityContext: capabilities: drop:

  • MKNOD
  • NET_BIND_SERVICE readOnlyRootFilesystem: true

yaml securityContext: capabilities: drop:

  • MKNOD
  • NET_BIND_SERVICE readOnlyRootFilesystem: true

Verification of image signatures

Проверка подписи образов

This feature is available in the following editions: SE+, EE.

Доступно в следующих редакциях: SE+, EE, CSE Lite (1.67), CSE Pro (1.67).

The module implements a function for checking the signatures of container images signed using Cosign. Checking the signatures of container images allows you to ensure their integrity (that the image has not been modified since its creation) and authenticity (that the image was created by a trusted source). You can enable container image signature verification in the cluster using the policies.verifyImageSignatures parameter of the SecurityPolicy resource.

В модуле реализована функция проверки подписи образов контейнеров, подписанных с помощью инструмента Cosign. Проверка подписи образов контейнеров позволяет убедиться в их целостности (что образ не был изменен после его создания) и подлинности (что образ был создан доверенным источником). Включить проверку подписи образов контейнеров в кластере можно с помощью параметра policies.verifyImageSignatures ресурса SecurityPolicy.

Steps to sign an image:

  • Generate keys: cosign generate-key-pair
  • Sign the image: cosign sign --key <key> <image>

Шаги для подписания образа:

  • Сгенерируйте ключи: cosign generate-key-pair
  • Подпишите образ: cosign sign --key <key> <image>

For more information on working with Cosign, you can check the documentation.

Подробнее о работе с Cosign можно узнать в документации.

Example of SecurityPolicy for configuring the signature verification of container images:

Пример SecurityPolicy для настройки проверки подписи образов контейнеров:

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: verify-image-signatures spec: match: namespaceSelector: labelSelector: matchLabels: kubernetes.io/metadata.name: default policies: verifyImageSignatures:

  • reference: docker.io/myrepo/* publicKeys:
  • |- —–BEGIN PUBLIC KEY—– MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== —–END PUBLIC KEY—–
  • reference: company.registry.com/* dockerCfg: zxc== publicKeys:
  • |- —–BEGIN PUBLIC KEY—– MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== —–END PUBLIC KEY—–

yaml apiVersion: deckhouse.io/v1alpha1 kind: SecurityPolicy metadata: name: verify-image-signatures spec: match: namespaceSelector: labelSelector: matchLabels: kubernetes.io/metadata.name: default policies: verifyImageSignatures:

  • reference: docker.io/myrepo/* publicKeys:
  • |- —–BEGIN PUBLIC KEY—– MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== —–END PUBLIC KEY—–
  • reference: company.registry.com/* dockerCfg: zxc== publicKeys:
  • |- —–BEGIN PUBLIC KEY—– MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== —–END PUBLIC KEY—–

Policies do not affect the creation of pods whose container image addresses do not match those described in the reference parameter. If the address of any Pod container image matches those described in the reference policies, and the image is not signed or the signature does not correspond to the keys specified in the policy, the creation of the pod will be prohibited.

Политика не влияет на создание подов, адреса образов контейнеров которых не подходят под описанные в параметре reference. Если же адрес какого-либо образа контейнера подходит под описанные в параметре reference политики, и образ не подписан или подпись не соответствует указанным в политике ключам, создание пода будет запрещено.

Example of an error output when creating a Pod with a container image that has not passed the signature verification:

Пример вывода ошибки при создании пода с образом контейнера, не прошедшим проверку подписи:

console [verify-image-signatures] Image signature verification failed: nginx:1.17.2

console [verify-image-signatures] Image signature verification failed: nginx:1.17.2