Skip to content

Latest commit

 

History

History
1890 lines (1253 loc) · 42.5 KB

PolicyAsVersionedCode.md

File metadata and controls

1890 lines (1253 loc) · 42.5 KB
title description author image marp theme url class video_embed
Policy as [versioned] code
In this talk Chris will trace back the origins of how policies are often incepted, how it can get out of hand, be slow if not impossible to update and measure compliance, and often lead us to question of is the policy helping or hindering. From this talk you'll learn how to use a software development pattern and product ways of thinking towards how your organization can manage policy; achieve continual updates to policy allowing the risk mitigations to move as fast as the risk does, not get in the way and be easy to measure compliance.
Chris Nesbitt-Smith
true
themes/cns
lead
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/YWQG_E7vgiQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Policy as [versioned]
Code

🤔

Chris Nesbitt-Smith

UK Gov | Control Plane | LearnK8s | lots of open source


👋


🐘🥱


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


bg


What if...


Update policy...


Update policy...
Daily!?


👀


bg fit


👩‍👦


👨‍👨‍👦‍👦


🤔



bg right

Chris Nesbitt-Smith

  • LearnK8s - Instructor
  • Control-Plane - Consultant
  • CDDO (UK gov) - Consultant
  • Open source

🙋👩‍🌾👩‍🚒
🙋‍♀️🦹‍♀️🙋‍♂️


👩‍🌾🙋🙋‍♂️
🦹‍♀️🙋‍♀️👩‍🚒


😜


📝


bg fit


<style scoped> section { font-size: 2.7em; } h1 { font-size: 2em; } </style>

policy

noun [ C ]

UK /ˈpɒl.ə.si/ US /ˈpɑː.lə.si/

a set of ideas or a plan of what to do in particular situations that has been agreed to officially by a group of people, a business organization, a government, or a political party


bg


🔐


👯‍♀️


🎰


🤪🎛


👩‍⚖️


bg


💊 | 🦠


👩‍💻


Policy, as <code/>?


<style scoped> li { font-size: 1.7em; } </style>
  • Admission Control
  • Anchore
  • Apparmor
  • Azure Policy
  • Checkov
  • Istio
  • jspolicy
  • K-rail
  • Kopf
  • Kubewarden
  • Kyverno
  • Network Policy
  • OPA Gatekeeper
  • Opslevel
  • Polaris
  • Prisma Cloud
  • Qualys
  • Rego
  • Regula
  • Seccomp
  • SeLinux
  • Sentinel
  • ServiceControlPolicy
  • Sysdig
  • TiDB

👹


{👹}


🤫


SHIFT⬅️?


✅❌✅✅✅ = ❌


bg fit invert


bg


bg


bg


But, we just provide

warnings not errors?


👀


jenkins

gitops


bg


✅ = 👍


bg


bg right

(easily:)

  • visible
  • communicable
  • consumable
  • testable
  • usable
  • updatable
  • measurable

bg


bg


>= inner source


open source?


bg right

(easily:)

  • visible ✅
  • communicable
  • consumable
  • testable
  • usable
  • updatable
  • measurable

semver

(semantic versioning)


1.20.300

Breaking change


2.20.300

Breaking change


2.20.300

Minor change


2.21.300

Minor change


2.21.300

Patch change


2.21.301

Patch change


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable
  • testable
  • usable
  • updatable
  • measurable

sudo apt-get install coffee


npm install --save-dev eslint


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable ✅
  • testable
  • usable
  • updatable
  • measurable

unit testing

no really...


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable ✅
  • testable ✅
  • usable
  • updatable
  • measurable

SHIFT ⬅️


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable ✅
  • testable ✅
  • usable ✅
  • updatable
  • measurable

bonus[able]: reliable


<style scoped> h1 { margin-top: -12%; font-size: 35em; } </style>


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable ✅
  • testable ✅
  • usable ✅
  • updatable ✅
  • measurable

🦹‍♀️🙋👩‍🚒
🙋‍♀️👩‍🌾🙋‍♂️


bg left

CVE-2021-44228


bg right

CVE-2021-45046


bg left fit

CVE-2021-45105


bg fit


bg fit


bg


bg right

(easily:)

  • visible ✅
  • communicable ✅
  • consumable ✅
  • testable ✅
  • usable ✅
  • updatable ✅
  • measurable ✅

bg fit


/\w*able/g


bg cover

🙄🤖


bg cover


bg cover


terraform + k8s


bg cover


🛠


<style scoped> li { font-size: 1.7em; } </style>
  • Admission Control
  • Anchore
  • Apparmor
  • Azure Policy
  • Checkov
  • Istio
  • jspolicy
  • K-rail
  • Kopf
  • Kubewarden
  • Kyverno
  • Network Policy
  • OPA Gatekeeper
  • Opslevel
  • Polaris
  • Prisma Cloud
  • Qualys
  • Rego
  • Regula
  • Seccomp
  • SeLinux
  • Sentinel
  • ServiceControlPolicy
  • Sysdig
  • TiDB

github.com/policy-as-versioned-code

bg fit


fit bg


<style scoped> pre { width: 45%; } pre:nth-child(2) { right: 1vh; position: absolute; } </style>

v1.0.0 policy

# kyverno kubernetes
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-department-label
  annotations:
    policies.kyverno.io/title: Require Department Label
    policies.kyverno.io/category: Example Org Policy
    policies.kyverno.io/description: >-
      It is important we know the department that resources
      belong to, so you need to define a 'mycompany.com/department'
      label on all your resources.
    pod-policies.kyverno.io/autogen-controllers: none
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: require-department-label
      validate:
        message: >-
          The label `mycompany.com/department` is 
          required.
        pattern:
          metadata:
            labels:
              "mycompany.com/department": "?*"
# checkov terraform
metadata:
  name: >-
    Check that all resources are tagged with
    the key - department"
  id: "CUSTOM_AWS_1"
  category: "CONVENTION"
scope:
  provider: aws
definition:
  and:
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "exists"

<style scoped> pre { width: 45%; } pre:nth-child(2) { right: 1vh; position: absolute; } </style>

v1.0.0 policy tests

# fail0.yaml
apiVersion: v1
kind: Pod
metadata:
  name: require-department-label-fail0
spec: ...
---
# pass0.yaml
apiVersion: v1
kind: Pod
metadata:
  name: require-department-label-pass0
  labels:
    mycompany.com/department: finance
spec: ...
// fail0.tf
resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
}
---
// pass0.tf
resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
  tags = {
    mycompany.com.department = "finance"
  }
}

bg fit


bg fit


<style scoped> pre { width: 45%; } pre:nth-child(2) { right: 1vh; position: absolute; } </style>

v2.0.0 policy

# kyverno kubernetes
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-department-label
  annotations:
    policies.kyverno.io/title: Require Department Label
    policies.kyverno.io/category: Example Org Policy
    policies.kyverno.io/description: >-
      It is important we know the department that resources
      belong to, so you need to define a 'mycompany.com/department'
      label on all your resources.
    pod-policies.kyverno.io/autogen-controllers: none
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: require-department-label
      validate:
        message: >-
          The label `mycompany.com/department` is required to be one
          of [acounts|hr]"
        pattern:
          metadata:
            labels:
              "mycompany.com/department": "acounts|hr"
# checkov terraform
metadata:
  name: >-
    Check that all resources are tagged with the key - department"

  id: "CUSTOM_AWS_1"
  category: "CONVENTION"
scope:
  provider: aws
definition:
  or:
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: hr
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: acounts

<style scoped> pre { width: 45%; } pre:nth-child(2) { right: 1vh; position: absolute; } </style>

v2.1.0 policy

# kyverno kubernetes
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-department-label
  annotations:
    policies.kyverno.io/title: Require Department Label
    policies.kyverno.io/category: Example Org Policy
    policies.kyverno.io/description: >-
      It is important we know the department that resources
      belong to, so you need to define a 'mycompany.com/department'
      label on all your resources.
    pod-policies.kyverno.io/autogen-controllers: none
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: require-department-label
      validate:
        message: >-
          The label `mycompany.com/department` is required to be one
          of [accounts|hr]"
        pattern:
          metadata:
            labels:
              "mycompany.com/department": "accounts|hr"
# checkov terraform
metadata:
  name: >-
    Check that all resources are tagged with the key - department"

  id: "CUSTOM_AWS_1"
  category: "CONVENTION"
scope:
  provider: aws
definition:
  or:
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: hr
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: accounts

<style scoped> pre { width: 45%; } pre:nth-child(2) { right: 1vh; position: absolute; } </style>

v2.1.1 policy

# kyverno kubernetes
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-department-label
  annotations:
    policies.kyverno.io/title: Require Department Label
    policies.kyverno.io/category: Example Org Policy
    policies.kyverno.io/description: >-
      It is important we know the department that resources
      belong to, so you need to define a 'mycompany.com/department'
      label on all your resources.
    pod-policies.kyverno.io/autogen-controllers: none
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: require-department-label
      validate:
        message: >-
          The label `mycompany.com/department` is required to be one
          of [tech|accounts|hr]"
        pattern:
          metadata:
            labels:
              "mycompany.com/department": "tech|accounts|hr"
# checkov terraform
metadata:
  name: >-
    Check that all resources are tagged with
    the key - department"
  id: "CUSTOM_AWS_1"
  category: "CONVENTION"
scope:
  provider: aws
definition:
  or:
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: hr
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: accounts
    - cond_type: "attribute"
      resource_types: "all"
      attribute: "tags.mycompany.com.department"
      operator: "equals"
      value: tech

<style scoped> table { font-size: 2em; } </style>

app1 (k8s) | infra1 (tf)

1.0.0 2.0.0 2.1.0 2.1.1

$schema: "https://docs.renovatebot.com/renovate-schema.json",
labels: ["policy"],
regexManagers: [{
  fileMatch: ["kustomization.yaml"],
  matchStrings: ['mycompany.com/policy-version: "(?<currentValue>.*)"\\s+'],
  datasourceTemplate: "github-tags",
  depNameTemplate: "policy",
  packageNameTemplate: "policy-as-versioned-code/policy",
  versioningTemplate: "semver",
},{
  fileMatch: [".*tf$"],
  matchStrings: [
    '#\\s*renovate:\\s*policy?\\s*default = "(?<currentValue>.*)"\\s',
  ],
  datasourceTemplate: "github-tags",
  depNameTemplate: "policy",
  lookupNameTemplate: "policy-as-versioned-code/policy",
  versioningTemplate: "semver",
}],

bg fit


bg fit


bg


<style scoped> table { font-size: 2em; } </style>

app2 (k8s) | infra2 (tf)

1.0.0 2.0.0 2.1.0 2.1.1
- ☑️ ☑️

bg


<style scoped> table { font-size: 2em; } </style>

app3 (k8s) | infra3 (tf)

1.0.0 2.0.0 2.1.0 2.1.1
- - -

🪄


#!/bin/bash


bg fit


<style scoped> pre { width: 50%; } h1 { width: 50% !important; right: 1vh; position: absolute; } </style>

👩‍💻

$ docker run --rm -ti \
  -v $(pwd):/apps \
  ghcr.io/policy-as-versioned-code/policy-checker

Found kustomization.yaml
Checking policy version...
Policy version: 1.0.0
Fetching Policy...
Policy fetched.
Running policy checker...

Applying 1 policy to 1 resource...
(Total number of result count may vary as the
policy is mutated by Kyverno. To check the
mutated policy please try with log level 5)

pass: 1, fail: 0, warn: 0, error: 0, skip: 0

🧩


k8s terraform


many-to-many


bg fit


bg fit


bg fit


bg


bg


bg cover


⁉️


💡


bg


bg


bg


bg


bg


🗣📢🧠


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


Purposeless policy
is potentially
practically
pointless policy.


<style scoped> h2 { position: absolute; bottom: 1ch; left: 2vw; width: 95% } </style>

🙏 Thanks 🙏

bg right

  • cns.me
  • talks.cns.me
  • github.com/chrisns
  • github.com/policy-as-versioned-code
  • learnk8s.io
  • control-plane.io

Chris Nesbitt-Smith


<style scoped> </style>

Q&A🙋‍♀️🙋🙋‍♂️

bg opacity:0.2


cns.me
cns.me


github.com/policy-as-versioned-code

Chris Nesbitt-Smith