Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing configuration with Open Policy Agent

Testing configuration with Open Policy Agent

Talk from the Cloud Engineering Summit, all about applying policy to configuration. Covers Open Policy Agent, Conftest and some of the integrated options in Pulumi.

Gareth Rushgrove

October 08, 2020
Tweet

More Decks by Gareth Rushgrove

Other Decks in Technology

Transcript

  1. Testing configuration with
    Open Policy Agent
    Gareth Rushgrove

    View full-size slide

  2. Gareth Rushgrove
    Director, Product Management, Snyk
    Devops Weekly curator
    Open Policy Agent, Conftest Maintainer
    @garethr

    View full-size slide

  3. Agenda Why policy?
    01
    Policy and developer workflow
    02
    The importance of sharing
    03
    Conclusions
    04

    View full-size slide

  4. Why policy?
    Introducing Open Policy Agent

    View full-size slide

  5. policy
    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.
    Cambridge Dictionary
    noun [ C ]
    UK /ˈpɒl.ə.si/ US /ˈpɑː.lə.si/

    View full-size slide

  6. policy
    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.
    Cambridge Dictionary
    noun [ C ]
    UK /ˈpɒl.ə.si/ US /ˈpɑː.lə.si/
    All Go projects should have
    been updated to use Go 1.13

    View full-size slide

  7. policy
    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.
    Cambridge Dictionary
    noun [ C ]
    UK /ˈpɒl.ə.si/ US /ˈpɑː.lə.si/
    All Go projects should have
    been updated to use Go 1.13
    All EC2 instances should
    have tags showing which
    team owns them

    View full-size slide

  8. policy
    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.
    Cambridge Dictionary
    noun [ C ]
    UK /ˈpɒl.ə.si/ US /ˈpɑː.lə.si/
    All Go projects should have
    been updated to use Go 1.13
    All EC2 instances should
    have tags showing which
    team owns them
    Dockerfiles should not use
    FROM with images tagged
    latest

    View full-size slide

  9. Open Policy Agent
    github.com/open-policy-agent/opa
    Service
    OPA
    .rego
    Query
    (any JSON value)
    Decision
    (any JSON value)
    Data
    (JSON)
    Policy
    (Rego)
    Request, Event, etc.
    Declarative
    Express policy in a high-level, declarative language
    that promotes safe, performant, fine-grained controls.
    Use a language purpose-built for policy in a world
    where JSON is pervasive.
    Context-aware
    Leverage external information to write the policies
    you really care about. Write logic that adapts to the
    world around it and attach that logic to the systems
    that need it.

    View full-size slide

  10. Conftest
    github.com/open-policy-agent/conftest

    View full-size slide

  11. Given a Kubernetes YAML file
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: hello-kubernetes
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: hello-kubernetes
    template:
    metadata:
    labels:
    app: hello-kubernetes
    spec:
    containers:
    - name: hello-kubernetes
    YAML

    View full-size slide

  12. Write your policies
    deny[msg] {
    input.kind = "Deployment"
    not input.spec.template.spec.securityContext.runAsNonRoot = true
    msg = "Containers must not run as root"
    }
    We should deny any input for which
    Deployment is the value for kind and
    When runAsNonRoot is not true
    REGO

    View full-size slide

  13. Run tests with conftest
    $ conftest test deployment.yaml
    FAIL - Containers must not run as root
    1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

    View full-size slide

  14. Lots of output options
    $ conftest test service.yaml -o table
    +---------+--------------+--------------------------------+
    | RESULT | FILE | MESSAGE |
    +---------+--------------+--------------------------------+
    | success | service.yaml | data.main.deny |
    | success | service.yaml | data.main.violation |
    | success | service.yaml | |
    | success | service.yaml | |
    | warning | service.yaml | Found service hello-kubernetes |
    | | | but services are not allowed |
    +---------+--------------+--------------------------------+

    View full-size slide

  15. Write unit tests for Rego in Rego
    test_blank_input {
    no_violations with input as {}
    }
    test_correctly_encrypted_azure_disk {
    no_violations with input as {"resource": { "azurerm_managed_disk": { "sample": { "encryp
    }
    test_unencrypted_azure_disk {
    deny["Azure disk `sample` is not encrypted"] with input as {"resource": { "azurerm_managed_di
    }
    REGO

    View full-size slide

  16. Documentation
    www.openpolicyagent.org/docs

    View full-size slide

  17. The Rego Playground
    play.openpolicyagent.org

    View full-size slide

  18. Policy and developer workflow
    Local testing, CI and more

    View full-size slide

  19. Any configuration format
    Conftest currently supports YAML, JSON, INI, TOML,
    HOCON, HCL, CUE, Dockerfile, EDN, VCL, XML and
    Jsonnet.
    Lots of infrastructure use cases
    Pulumi, Terraform, Azure Resource Manager, AWS
    CloudFormation, Varnish, Dockerfile, Envoy, CircleCI
    configuration, Tekton, Kubernetes and lots more.
    Test any configuration file or structured output
    Anything that outputs, or takes as input,
    structured data in a standard format.

    View full-size slide

  20. Conftest integrations
    Easy to run in common CI/CD systems

    View full-size slide

  21. Modern Infrastructure as Code
    Create and deploy cloud software that use
    containers, serverless functions, hosted services,
    and infrastructure, on any cloud.
    Describe infrastructure in Typescript, Python,
    Go or .NET.
    let aws = require("@pulumi/aws");
    let sg = new aws.ec2.SecurityGroup("web-sg", {
    ingress: [{ protocol: "tcp", fromPort: 80,
    toPort: 80, cidrBlocks: ["0.0.0.0/0"]}],
    });
    for (let i = 0; i < 3; i++) {
    new aws.ec2.Instance(`web-${i}`, {
    ami: "ami-7172b611",
    instanceType: "t2.micro",
    securityGroups: [ sg.name ],
    userData: `#!/bin/bash
    echo "Hello, World!" > index.html
    nohup python -m SimpleHTTPServer 80 &`,
    });
    }
    TYPESCRIPT

    View full-size slide

  22. Pulumi CrossGuard supports Open Policy Agent

    View full-size slide

  23. Write policies for any Pulumi provider
    package kubernetes
    name = input.metadata.name
    labels {
    input.metadata.labels["app.kubernetes.io/name"]
    input.metadata.labels["app.kubernetes.io/instance"]
    input.metadata.labels["app.kubernetes.io/version"]
    input.metadata.labels["app.kubernetes.io/component"]
    input.metadata.labels["app.kubernetes.io/part-of"]
    input.metadata.labels["app.kubernetes.io/managed-by"]
    }
    deny[msg] {
    input.kind = "Deployment"
    not labels
    msg = sprintf("%s must include Kubernetes recommended labels", [name])
    }
    REGO

    View full-size slide

  24. Gate pulumi up on passing policy
    $ pulumi up --policy-pack policy
    Previewing update (dev)
    View Live:
    https://app.pulumi.com/garethr/pulumi-oketeto-conftest-demo/dev/previews/b100f975-5715-4ced-acd4-a2dd
    961e6617
    Type Name Plan Info
    pulumi:pulumi:Stack pulumi-oketeto-conftest-demo-dev 1 error
    ~ └─ pulumi:providers:kubernetes kubernetes update [diff:
    -kubeconfig]
    Diagnostics:
    pulumi:pulumi:Stack (pulumi-oketeto-conftest-demo-dev):
    error: preview failed
    Policy Violations:
    [mandatory] kubernetes v0.0.1 deny (nginx: kubernetes:apps/v1:Deployment)
    nginx-fxpagomr must include Kubernetes recommended labels

    View full-size slide

  25. Output to YAML with Pulumi (beta)
    from pulumi_kubernetes import Provider
    # Instantiate a Kubernetes Provider and specify the render directory.
    render_provider = Provider("k8s-yaml-rendered",
    render_yaml_to_directory="yaml")
    PYTHON
    import * as k8s from "@pulumi/kubernetes";
    import * as kx from "@pulumi/kubernetesx";
    // Instantiate a Kubernetes Provider and specify the render directory.
    const provider = new k8s.Provider("render-yaml", {
    renderYamlToDirectory: "rendered",
    });
    TYPESCRIPT

    View full-size slide

  26. Lots of tools output JSON
    Any tool that can output to a one of the structured
    formats supported by Conftest can be tested with
    Open Policy Agent.
    Provides a rules engine for anything from kubectl to
    aws to snyk.
    Useful for checking output as well as input
    $ snyk container test your/image --json
    ...
    {
    "title": "CVE-2019-9619",
    "packageName": "systemd",
    "language": "linux",
    "packageManager": "debian:10",
    "description": "...",
    "identifiers": {
    "CVE": [
    "CVE-2019-9619"
    ],
    },
    "severity": "low",
    "references": [
    {
    "title": "Debian Security Tracker",
    "url": "https://security-tracker.debian.o

    View full-size slide

  27. Prohibiting high severity vulnerabilities
    package main
    deny[msg] {
    issue = input.vulnerabilities[index]
    issue.severity = "high"
    msg = sprintf("High severity issue found. package: %v issue: %v", [issue.name, issue.title])
    }
    Rego for the JSON output from snyk
    Here we’re saying we want to prohibit any images with known high-severity vulnerabilities.
    REGO

    View full-size slide

  28. Watching out for crypto issues
    package main
    deny[msg] {
    issue = input.vulnerabilities[index]
    issue.identifiers["CWE"][_] = "CWE-327"
    issue.severity = "high"
    msg = sprintf("High severity cryptography issue (CWE-327). package: %v", [issue.name])
    }
    warn[msg] {
    issue = input.vulnerabilities[index]
    issue.identifiers["CWE"][_] = "CWE-327"
    issue.severity != "high"
    msg = sprintf("Crypto issue (CWE-327). package: %v severity: %v", [issue.name, issue.severity])
    }
    REGO

    View full-size slide

  29. Run locally and as part of image pipelines
    $ snyk container test ghcr.io/garethr/snykt/base --file=base/Dockerfile --json | conftest test -
    WARN - Cryptography issue (CWE-327). package: gnupg severity: low
    WARN - Cryptography issue (CWE-327). package: openssl/libssl1.0.0 severity: medium
    WARN - Cryptography issue (CWE-327). package: openssl/libssl1.0.0 severity: low
    WARN - Cryptography issue (CWE-327). package: openssl severity: medium
    WARN - High severity issue found. package: apt/libapt-pkg4.12 issue: Arbitrary Code Injection
    FAIL - High severity issue found. package: apt issue: Arbitrary Code Injection
    FAIL - High severity issue found. package: bzip2/libbz2-1.0 issue: Out-of-bounds Write
    FAIL - High severity issue found. package: glibc/libc-bin issue: Out-of-bounds Read
    Stdin
    Use conftest and Open Policy Agent with any tool that outputs to JSON.

    View full-size slide

  30. Sharing policy
    Scaling with reuse

    View full-size slide

  31. Sharing via Git, HTTP, S3 and more
    $ conftest pull bucket.s3.amazonaws.com/foo
    # Note here we’re only getting the contents of a specific subdirectory, policy
    $ conftest pull github.com/garethr/pulumi-okteto-conftest-demo.git//policy
    Pull policies from remote locations
    Support for local files, Git, Mercurial, HTTP, Amazon S3, Google GCP

    View full-size slide

  32. Sharing via OCI registries
    $ conftest push ghcr.io/garethr/pulumi-okteto-conftest-demo/policy
    ...
    $ conftest pull oci://ghcr.io/garethr/pulumi-okteto-conftest-demo/policy:latest
    Powered by the OCI Artifacts specification
    Not supported by all registries yet, but ACR, ECR, GitHub Container Registry,
    Harbor and more support this capability now.

    View full-size slide

  33. Sharing via Pulumi
    $ pulumi policy publish
    # Note here we’re only getting the contents of a specific subdirectory, policy
    $ pulumi policy ls
    NAME VERSIONS
    kubernetes 1
    $ pulumi policy enable garethr/kubernetes 1
    Pulumi’s commercial service has sharing built-in
    Automatic enforcement on pulumi up without having to specify
    the policy pack locally.

    View full-size slide

  34. Conclusions
    If all you remember is...

    View full-size slide

  35. Configuration needs
    tests too
    Infrastructure as code benefits from
    software development practices just
    like other software development.

    View full-size slide

  36. Standardize tools for
    common problems
    OPA is useful for individual use
    cases, but the cost of adoption
    really pays off when using to solve
    several problems

    View full-size slide

  37. Policy needs to shift left
    Catching problems only at the end
    of the process doesn’t make for a
    nice developer experience.

    View full-size slide

  38. Thanks for listening
    Sign up for Snyk for free at
    snyk.io/signup

    View full-size slide