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

Policy as Code: Intro to Sentinel

Armon Dadgar
September 29, 2017

Policy as Code: Intro to Sentinel

In the last few years, we've seen an explosion of DSLs and tools that focus on enabling Infrastructure as Code. The Infrastructure as Code approach allows the best practices of software development like code reuse, versioning, and peer review to be applied to new domains such as infrastructure management. In helping organizations adopt these tools, we found a common shortcoming was the ability to impose specific compliance or security policies on infrastructure changes. In trying to apply the "As Code" approach to this problem, we created a new language called Sentinel, focusing specifically on policy applications. Sentinel is meant to be read and written by non-programmers, specific compliance and security officers who are unfamiliar with traditional programming languages and constructs. We discuss the design principles of the Sentinel language, it's basic syntax, runtime implementation, and some of the use cases we've deployed it for.

Armon Dadgar

September 29, 2017
Tweet

More Decks by Armon Dadgar

Other Decks in Technology

Transcript


  1. Policy as Code:
    Intro to Sentinel
    @armon

    View Slide


  2. Armon Dadgar
    @armon

    View Slide

  3. @armon

    View Slide

  4. “POLICY AS CODE”

    View Slide

  5. “INFRASTRUCTURE AS CODE”

    View Slide

  6. • Before: Artisanal and Handcrafted
    • Point-and-Click UX
    • SSH + Manual Setup
    • Rsync between machines
    • etc
    INFRASTRUCTURE BEFORE

    View Slide

  7. • After: Automated and Standardized
    • Single source of truth
    • Automated provisioning
    • Enables Scale
    INFRASTRUCTURE AS CODE

    View Slide

  8. View Slide

  9. • Learn from Software Development
    • Versioning (Rollbacks)
    • Peer Review
    • Abstraction / Encapsulation
    • Code Reuse
    • Automation and Leverage
    BENEFITS

    View Slide

  10. PROVISIONING A DATACENTER

    View Slide

  11. Developers
    IT Operations
    Networking
    Security
    Procurement
    Sysadmins
    Finance
    Legal

    View Slide

  12. • Replace ticketing workflows with APIs
    • Public Cloud consolidated many concerns
    • Private Cloud brings similar APIs
    • Enables Infrastructure as Code
    • Huge increase in leverage
    UBIQUITOUS APIS

    View Slide

  13. PARADOX OF AUTOMATION

    View Slide

  14. SANITY CHECKING
    IT Ops Procurement
    “Please provision 5000 VMs”

    View Slide

  15. SANITY CHECKING
    IT Ops Procurement
    “Are you sure 5000?”

    View Slide

  16. SANITY CHECKING
    IT Ops Cloud
    “Please provision 5000 VMs”

    View Slide

  17. SANITY CHECKING
    IT Ops Cloud
    “Done!”

    View Slide

  18. • Paradox of Automation
    • Accidental Error
    • Compliance Bypass
    • Malicious Intent
    SCALING AUTOMATION

    View Slide

  19. • Governs Infrastructure as Code
    • Defines a sandbox to automate in
    • Codify business regulation and “sanity checking”
    POLICY AS CODE

    View Slide

  20. • Separate teams for Procurement / IT Operations / etc
    • Bulkhead against failures
    • Separate authors
    • Policy as Code (Compliance / Security)
    • Infrastructure as Code (Operators / Developers)
    SEPARATION OF RESPONSIBILITY

    View Slide

  21. POLICY AS CODE

    View Slide

  22. • Changes only during business hours
    • Min / Max number of service instances
    • Instance types allowed
    • Public Cloud regions
    • Ensure resources are tagged (billing, tenancy)
    • Certified containers / AMIs only
    EXAMPLE POLICIES

    View Slide

  23. • Security / Compliance teams define and enforce
    • Not familiar with “As Code” approach
    • Need to test policies
    ORGANIZATIONAL CHALLENGES

    View Slide

  24. SENTINEL

    View Slide

  25. • “Policy as Code Framework”
    • Sentinel Language Specification*
    • Golang Embedded Runtime
    • Simulator tool
    • Import SDK
    WHAT IS SENTINEL
    * https://docs.hashicorp.com/sentinel/language/spec

    View Slide

  26. • Non-programmer friendly
    • Easy to Embed
    • Simple
    • Debuggable
    • Go Friendly
    DESIGN GOALS

    View Slide

  27. • Language must be read and written by those with little to no
    programming experience
    • Traditional constructs should be available, but not needed for
    most policies
    NON-PROGRAMMER FRIENDLY

    View Slide

  28. • Impacts Runtime more than Language
    • No support for unsafe operations (arbitrary memory access)
    • Must be easy to sandbox
    • Active Enforcement
    • Prevent Violation A Priori
    • Passive Enforcement
    • Detect Violation Post Hoc
    EASY TO EMBED

    View Slide

  29. • Simple types (string, int, bool) at the expense of performance or
    exactness
    • Policies are typically small and don’t need to much flexibility
    • Ideally only one way to do something
    • “Zen of Python”
    SIMPLE

    View Slide

  30. • Easy to debug and test for those not familiar
    • Often the sharpest corner when learning
    DEBUGABBLE

    View Slide

  31. • Majority of HashiCorp tooling is Go
    • Simple to integration
    • Minimal changes to tooling / process
    • Performance implications
    GO FRIENDLY

    View Slide

  32. NOT INVENTED HERE?

    View Slide

  33. • JavaScript, Python, Lua, Ruby
    • Non-programmer friendliness
    • Embeddable
    • Go friendliness
    EXISTING LANGUAGES

    View Slide

  34. • Sentinel has dynamic types
    • Wanted static typing
    • Much friendlier to non-programmers
    • External integrations more complex
    DESIGN DECISIONS: DYNAMIC TYPING

    View Slide

  35. import "time"
    deployment_window = rule {
    time.hour > 8 and time.hour < 17
    }
    main = rule { deployment_window }
    First Class Rules

    View Slide

  36. • Equivalent to functions
    • Lazy
    • Memoized
    • Performance for redundant rules
    • More Friendly
    DESIGN DECISIONS: FIRST CLASS RULES

    View Slide

  37. import "external"
    external_ready = rule { external.expensive_call() }
    internal_override = rule { … }
    main = rule {
    external_ready or
    (!external_ready and interal_override)
    }

    View Slide

  38. • Dedicated Existential Operators
    • any: expression is true for any term
    • all: expression is true for all terms
    • “All artifacts must come from a trusted source”
    • “Any of the tags must be the tenant ID”
    DESIGN DECISIONS: EXISTENTIAL OPERATORS

    View Slide

  39. • Plain English Operators
    • and, or, contains, in, is, matches, not
    • Traditional Operators
    • Easier for non-programmers
    DESIGN DECISIONS: SIMPLE OPERATORS

    View Slide

  40. • Avoid Exceptions / Panic
    • Must propagate errors
    • “Infectious” Undefined
    • Can be escaped by boolean logic with else
    DESIGN DECISIONS: UNDEFINED VALUE

    View Slide

  41. import “time”
    # valid_bar will be undefined
    obj = null
    valid_bar = rule { obj.foo.bar == 42 }
    valid_time = rule { time.hour > 8 }
    main = rule { (valid_bar or valid_time) else false }

    View Slide

  42. BASIC SYNTAX

    View Slide

  43. main = rule {
    all obj.items as item {
    item matches "my-item-[a-z0-9]+"
    }
    }

    View Slide

  44. sum = func(list) {
    count = 0
    for list as elem {
    count += elem
    }
    return count
    }
    main = rule {
    sum(obj.items) is 42
    }

    View Slide

  45. allowed_size = ["m3.small", "m4.small", "c1.large"]
    allowed_regions = {“stage”:“east","prod":“west"}
    valid_provider = rule { all providers as p {
    p.region is allowed_regions[env.region]
    }

    }
    valid_resource = rule { all resources as r {
    r.type is "instance" and r.size in allowed_size
    }
    }
    main = rule { valid_provider and valid_resource}

    View Slide

  46. RUNTIME IMPLEMENTATION

    View Slide

  47. • Lexer / Parser
    • Semantic Checker
    • Evaluator / Interpreter
    • Standard Library
    KEEP IT SIMPLE

    View Slide

  48. • Learn From Go
    • Maintain the position offsets (line, column)
    • Support a “fmt” command
    • Canonical Format
    LEXER / PARSER

    View Slide

  49. • Early warning to users
    • Main rules exist
    • Imports valid
    SEMANTIC CHECKING

    View Slide

  50. • Rule Memoization
    • Policy Caching
    • Import Recycling
    • Sandboxing
    • Execution time limited
    • Memory limited
    • Stack depth limited
    EVALUATOR

    View Slide

  51. • Avoid User Functions
    • Built in Standard Library
    • Time, Math, CIDR parsing, Strings, etc
    STANDARD LIBRARY

    View Slide

  52. ENFORCEMENT LEVELS
    "I'm sorry, Dave.
    I'm afraid I can't do that"

    View Slide

  53. • Different Levels
    • Runtime aware
    • Advisory
    • Soft Mandatory
    • Hard Mandatory
    ENFORCEMENT LEVELS

    View Slide

  54. • Policy is allowed to fail
    • Warning is showed to user
    • “Warn if user provisions deprecated instance type”
    ENFORCEMENT LEVEL: ADVISORY

    View Slide

  55. • Action is blocked when policy fails
    • Action is allowed when an override is specified
    • Override is tied to additional permissions
    • User has explicitly acknowledged out of policy action
    • “Do not allow changes outside of business hours (unless there is
    an outage)”
    ENFORCEMENT LEVEL: SOFT MANDATORY

    View Slide

  56. • Action is blocked when policy fails
    • Override is not possible
    • “Encryption keys are at least 128 bits and non-exportable”
    ENFORCEMENT LEVEL: HARD MANDATORY

    View Slide

  57. • Multiple policies may be evaluated per action
    • Smaller policies vs Monolithic policy
    • Mandatory failures can short circuit
    RUNTIME AWARENESS

    View Slide

  58. • Sentinel Runtime is embedded
    • In Data Path
    • Active Enforcement
    • How to develop and test policies?
    EMBEDDED FRAMEWORK

    View Slide

  59. SENTINEL SIMULATOR

    View Slide

  60. Terminal
    Usage: sentinel [--version] [--help] []
    Available commands are:
    apply Execute a policy and output the result
    doc Show documentation for an import from a doc file
    fmt Format Sentinel policy to a canonical format
    test Test policies
    version Prints the Sentinel version

    View Slide

  61. Terminal
    $ sentinel apply -trace example_1.sentinel
    Pass
    Execution trace. The information below will show the values of all
    the rules evaluated and their intermediate boolean expressions. Note that
    some boolean expressions may be missing if short-circuit logic was taken.
    TRUE - example_1.sentinel:3:1 - Rule "main"
    TRUE - example_1.sentinel:3:15 - time.hour > 8
    TRUE - example_1.sentinel:3:33 - time.hour < 17

    View Slide

  62. Terminal
    $ sentinel apply -trace example_1.sentinel
    Fail
    Execution trace. The information below will show the values of all
    the rules evaluated and their intermediate boolean expressions. Note that
    some boolean expressions may be missing if short-circuit logic was taken.
    FALSE - example_1.sentinel:3:1 - Rule "main"
    FALSE - example_1.sentinel:3:15 - time.hour > 16

    View Slide

  63. • Apply allows for playing with policies during development
    • Test suites
    • Regression testing
    TESTING POLICIES

    View Slide

  64. Terminal
    $ tree
    .
    ├── example_1.sentinel
    ├── test
    │ ├── example_1
    │ │ ├── fail.json
    │ │ └── pass.json

    View Slide

  65. {
    "config":
    {
    ...
    },
    "mock":
    {
    "time": {
    "hour": 9
    }
    },
    "test": {
    "main": false
    }
    }
    pass.json

    View Slide

  66. Terminal
    $ sentinel test -v example_1.sentinel
    PASS - example_1.sentinel
    PASS - test/example_1/fail.json
    trace:
    FALSE - example_1.sentinel:3:1 - Rule "main"
    FALSE - example_1.sentinel:3:15 - time.hour >= 16
    PASS - test/example_1/pass.json
    trace:
    TRUE - example_1.sentinel:3:1 - Rule "main"
    TRUE - example_1.sentinel:3:15 - time.hour >= 16
    TRUE - example_1.sentinel:3:35 - time.hour < 17

    View Slide

  67. CONTINUOUS INTEGRATION

    View Slide

  68. IMPORT SDK

    View Slide

  69. • Infrastructure composed of many pieces
    • Many policies require external information
    • Easy to incorporate external state
    IMPORTS

    View Slide

  70. • SDK makes it easy to expose new import
    • Host systems allow imports to be specified
    • Configured in advance for security
    • Plugins use IPC
    • Runtime multiplexes and garbage collects
    IMPORT SDK

    View Slide

  71. • Integrate common systems
    • Integrate custom internal systems
    • Extend with arbitrary logic
    IMPORT SDK

    View Slide

  72. CROSS SYSTEM PROTECTION
    Submit
    Service
    Service
    Configured?

    View Slide

  73. CROSS SYSTEM PROTECTION
    Delete
    Service
    Config
    Service
    Running?

    View Slide

  74. USE CASES

    View Slide

  75. • Infrastructure as Code guardrails
    • Simplify Compliance
    • “Fool me once, shame on you.”
    POLICY AS CODE USE CASES

    View Slide

  76. • Define Sandbox
    • Limits the potential damage of automation
    • Impose “sanity check” without manual process
    INFRASTRUCTURE AS CODE GUARDRAILS

    View Slide

  77. • Compliance often expressed as Word doc
    • Codify compliance requirements
    • Active enforcement simpler than passive detection
    • “An once of prevention is worth a pound of cure.”
    SIMPLIFY COMPLIANCE

    View Slide

  78. • Policies will never be exhaustive
    • Memory is finite!
    • Codify policies to defend against repeat mistakes
    • Scaling policies easier to expanding memory
    AVOID REPEAT MISTAKES

    View Slide

  79. • Policy as Code builds upon “As Code”
    • Shared benefits as Infrastructure as Code
    • Sentinel a framework for Policy as Code
    • Language, Import SDK OSS
    • Next Step in Infrastructure Automation
    CONCLUSION

    View Slide

  80. THANKS!

    View Slide