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. • Before: Artisanal and Handcrafted • Point-and-Click UX • SSH

    + Manual Setup • Rsync between machines • etc INFRASTRUCTURE BEFORE
  2. • After: Automated and Standardized • Single source of truth

    • Automated provisioning • Enables Scale INFRASTRUCTURE AS CODE
  3. • Learn from Software Development • Versioning (Rollbacks) • Peer

    Review • Abstraction / Encapsulation • Code Reuse • Automation and Leverage BENEFITS
  4. • 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
  5. • Governs Infrastructure as Code • Defines a sandbox to

    automate in • Codify business regulation and “sanity checking” POLICY AS CODE
  6. • 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
  7. • 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
  8. • Security / Compliance teams define and enforce • Not

    familiar with “As Code” approach • Need to test policies ORGANIZATIONAL CHALLENGES
  9. • “Policy as Code Framework” • Sentinel Language Specification* •

    Golang Embedded Runtime • Simulator tool • Import SDK WHAT IS SENTINEL * https://docs.hashicorp.com/sentinel/language/spec
  10. • Non-programmer friendly • Easy to Embed • Simple •

    Debuggable • Go Friendly DESIGN GOALS
  11. • 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
  12. • 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
  13. • 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
  14. • Easy to debug and test for those not familiar

    • Often the sharpest corner when learning DEBUGABBLE
  15. • Majority of HashiCorp tooling is Go • Simple to

    integration • Minimal changes to tooling / process • Performance implications GO FRIENDLY
  16. • Sentinel has dynamic types • Wanted static typing •

    Much friendlier to non-programmers • External integrations more complex DESIGN DECISIONS: DYNAMIC TYPING
  17. import "time" deployment_window = rule { time.hour > 8 and

    time.hour < 17 } main = rule { deployment_window } First Class Rules
  18. • Equivalent to functions • Lazy • Memoized • Performance

    for redundant rules • More Friendly DESIGN DECISIONS: FIRST CLASS RULES
  19. import "external" external_ready = rule { external.expensive_call() } internal_override =

    rule { … } main = rule { external_ready or (!external_ready and interal_override) }
  20. • 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
  21. • Plain English Operators • and, or, contains, in, is,

    matches, not • Traditional Operators • Easier for non-programmers DESIGN DECISIONS: SIMPLE OPERATORS
  22. • Avoid Exceptions / Panic • Must propagate errors •

    “Infectious” Undefined • Can be escaped by boolean logic with else DESIGN DECISIONS: UNDEFINED VALUE
  23. 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 }
  24. main = rule { all obj.items as item { item

    matches "my-item-[a-z0-9]+" } }
  25. sum = func(list) { count = 0 for list as

    elem { count += elem } return count } main = rule { sum(obj.items) is 42 }
  26. 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}
  27. • Lexer / Parser • Semantic Checker • Evaluator /

    Interpreter • Standard Library KEEP IT SIMPLE
  28. • Learn From Go • Maintain the position offsets (line,

    column) • Support a “fmt” command • Canonical Format LEXER / PARSER
  29. • Early warning to users • Main rules exist •

    Imports valid SEMANTIC CHECKING
  30. • Rule Memoization • Policy Caching • Import Recycling •

    Sandboxing • Execution time limited • Memory limited • Stack depth limited EVALUATOR
  31. • Avoid User Functions • Built in Standard Library •

    Time, Math, CIDR parsing, Strings, etc STANDARD LIBRARY
  32. • Different Levels • Runtime aware • Advisory • Soft

    Mandatory • Hard Mandatory ENFORCEMENT LEVELS
  33. • Policy is allowed to fail • Warning is showed

    to user • “Warn if user provisions deprecated instance type” ENFORCEMENT LEVEL: ADVISORY
  34. • 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
  35. • Action is blocked when policy fails • Override is

    not possible • “Encryption keys are at least 128 bits and non-exportable” ENFORCEMENT LEVEL: HARD MANDATORY
  36. • Multiple policies may be evaluated per action • Smaller

    policies vs Monolithic policy • Mandatory failures can short circuit RUNTIME AWARENESS
  37. • Sentinel Runtime is embedded • In Data Path •

    Active Enforcement • How to develop and test policies? EMBEDDED FRAMEWORK
  38. Terminal Usage: sentinel [--version] [--help] <command> [<args>] 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
  39. 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
  40. 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
  41. • Apply allows for playing with policies during development •

    Test suites • Regression testing TESTING POLICIES
  42. Terminal $ tree . ├── example_1.sentinel ├── test │ ├──

    example_1 │ │ ├── fail.json │ │ └── pass.json
  43. { "config": { ... }, "mock": { "time": { "hour":

    9 } }, "test": { "main": false } } pass.json
  44. 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
  45. • Infrastructure composed of many pieces • Many policies require

    external information • Easy to incorporate external state IMPORTS
  46. • 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
  47. • Infrastructure as Code guardrails • Simplify Compliance • “Fool

    me once, shame on you.” POLICY AS CODE USE CASES
  48. • Define Sandbox • Limits the potential damage of automation

    • Impose “sanity check” without manual process INFRASTRUCTURE AS CODE GUARDRAILS
  49. • 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
  50. • Policies will never be exhaustive • Memory is finite!

    • Codify policies to defend against repeat mistakes • Scaling policies easier to expanding memory AVOID REPEAT MISTAKES
  51. • 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