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 Slide

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

    View Slide

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

    View Slide

  4. Why policy?
    Introducing Open Policy Agent

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

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

    View Slide

  11. View Slide

  12. 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 Slide

  13. 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 Slide

  14. 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 Slide

  15. 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 Slide

  16. Demo

    View Slide

  17. 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 Slide

  18. Documentation
    www.openpolicyagent.org/docs

    View Slide

  19. The Rego Playground
    play.openpolicyagent.org

    View Slide

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

    View Slide

  21. 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 Slide

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

    View Slide

  23. 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 Slide

  24. Pulumi CrossGuard supports Open Policy Agent

    View Slide

  25. 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 Slide

  26. 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 Slide

  27. 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 Slide

  28. Demo

    View Slide

  29. 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 Slide

  30. 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 Slide

  31. 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 Slide

  32. 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 Slide

  33. Sharing policy
    Scaling with reuse

    View Slide

  34. 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 Slide

  35. 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 Slide

  36. 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 Slide

  37. Conclusions
    If all you remember is...

    View Slide

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

    View Slide

  39. 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 Slide

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

    View Slide

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

    View Slide