Skip to content

Latest commit

 

History

History
1262 lines (887 loc) · 25.2 KB

PolicyAsVersionedCodeLightning.md

File metadata and controls

1262 lines (887 loc) · 25.2 KB
title description author image marp theme url class video_embed
Policy as [versioned] code (Lightning)
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/esynergy
lead
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/Nstv7OA4abo" 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 | esynergy | 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


What if...


Update policy...


Update policy...
Daily!?


👀


👨‍👨‍👦‍👦


bg right

Chris Nesbitt-Smith

  • Learnk8s & ControlPlane - Instructor+consultant
  • esynergy - Digital Transformation Consultant
  • Crown Prosecution Service (UK gov) - Consultant
  • Opensource

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


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


😜


📝


<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


👯‍♀️


🎰


🤪🎛


<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

👹


{👹}


bg


bg


But, we just provide

warnings not errors?


bg left

CVE-2021-44228


bg right

CVE-2021-45046


bg left fit

CVE-2021-45105


bg fit


bg cover

🙄🤖


bg cover


🏔 + ☸️

(Terraform + Kubernetes)


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
- - -

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

🧩


terraform
kubernetes


many-to-many


bg fit


bg fit


bg fit


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

Chris Nesbitt-Smith


<style scoped> </style>

⚡️⚡️🙏⚡️⚡️

bg opacity:0.2


cns.me
cns.me


github.com/policy-as-versioned-code

Chris Nesbitt-Smith