Open Policy Agent Policybased control for cloud native
Open Policy Agent Policy-based control for cloud native environments.
Agenda ● Overview ○ ○ Background, what is OPA? Features ● Design & Architecture ○ ○ Architecture & APIs Language
Cloud-native Diversity/Dynamism Make Policy Management Challenging Container Management CICD Microservices 1 2 3 Orchestration Databases 4 CICD Pipeline Servers UI API Container sshd Database sshd Host Cloud Linux Public Cloud
Open Policy Agent: Community Inception Production Users Use Cases Today Project started in 2016 by Styra Netflix GCP Azure (AKS) Pinterest Yelp Reddit Chef Atlassian Intuit Capital One ABN AMRO Goldman Sachs BNY Mellon. . . and many more. Admission control Authorization ACLs RBAC IAM ABAC Risk management Data Protection Data Filtering CNCF project (Incubating) Goal Unify policy enforcement across the stack 361 contributors 1800+ slack users 20+ integrations >8 M Image pulls
OPA: General-purpose Policy Engine Request Linux PAM Enforcement is decoupled from decision-making. Service Policy Query Policy Decision OPA Input can be ANY JSON value Policy (Rego) Output can be ANY JSON value Data (JSON) openpolicyagent. org
OPA: Features Request ● Declarative Policy Language (Rego) ○ ○ ○ Can user X do operation Y on resource Z? What invariants does workload W violate? Which records should bob be allowed to see? Service Query ● Language features ○ ○ 50+ built-in functions: JWTs, date/time, CIDR math , etc. Context-aware policies (e. g. , Kubernetes, AD, entitlements, etc. ) Composition & delegation Performance optimizations (Rule Indexing, Partial Evaluation) Policy (Rego) ● Library (Go), sidecar/host-level daemon ○ ○ Policy and data are kept in-memory Zero decision-time dependencies Decision OPA Data (JSON) openpolicyagent. org
OPA: Features Request ● Management APIs for control & observability ○ ○ Bundle service API for sending policy & data to OPA Status service API for receiving status from OPA Log service API for receiving audit log from OPA Discovery API for dynamic policy discovery & distribution Service Query ● Tooling to build, test, and debug policy ○ ○ ○ Decision OPA opa run, opa test, opa fmt, opa deps, opa check, etc. VS Code plugin, Tracing, Profiling, etc. play. openpolicyagent. org Policy (Rego) Data (JSON) openpolicyagent. org
Agenda ● Overview ○ ○ Background, what is OPA? Features ● Design & Architecture ○ ○ Architecture & APIs Language
Architecture: Distributed systems are the norm ● ● ● OPA serves as a host-local cache for decisions Policies & data cached in-memory No decision-time dependencies (by default) Leverage fate-sharing architecture CDN-compatible policy distribution model OPA Service OPA network partition control plane Service OPA Service openpolicyagent. org
Architecture: Simple APIs for easy integration Request 1. Caller queries OPA. Supplies arbitrary JSON as input. POST v 1/data/http/authz/allow {"input": { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob"}} Service Query Decision 2. OPA executes policy OPA package http. authz allow = true { input. user == “bob” } 3. Caller enforces decision 200 OK {“result”: true} Policy (Rego) Data (JSON) openpolicyagent. org
Language: IF-THEN statements ● NOT a general-purpose language. No data structures, I/O, errors, etc. ● IF-THEN statements map to real-world policies. Called "rules" in Rego. Remove unnecessary keywords ("assert", "if", "and", etc. ) pseudo-Rego assert allow is true if. . . input. method is "GET" and. . . input. resource is "/salary/{user}" and. . . input. user is user. allow is true { input. method is "GET" input. resource is "/salary/{user}" input. user is user } allow = true { some user input. method = "GET" input. resource = ["salary", user] input. user = user } Replace "is" with "=". Declare variables. Use pattern matching with JSON. openpolicyagent. org
Language: allow is not a keyword ● Rules assign values (e. g. , true) to variables (e. g. , allow) based on conditions allow = true { some user input. method = "GET" input. resource = ["salary", user] input. user = user } VARIABLE = TERM { TERM = TERM } OPA/Rego understands assignments, conditions, terms (values/vars), etc. ● "allow" is not a keyword, special variable, etc. ○ ○ neither are deny, warn, etc. enables domain-specific abstractions ● "true" is just a JSON value ○ ratelimit = 7 { input. tier == "gold" } non-boolean decisions openpolicyagent. org
Language: Collaboration is required ● Rules can refer to other rules ● Rules are namespaced and grouped in "packages" ● Conflict resolution expressed within conditions reporting_app. rego cross_cutting. rego main. rego package app package ops package main allow { input. method = "GET" } deny { import data. app input. num_reqs_in_last_hour >= import data. ops max_requests_per_hour } allow { app. allow max_requests_per_hour = 7 not ops. deny } openpolicyagent. org
Language: Decision-making requires context/data ● Document-oriented data is the norm ○ Users know the format of data in other systems ● First-class support for logic over JSON, YAML, etc. ○ ○ Reference data with JSON Path like syntax e. g. , input. spec. containers[0]. image ● OPA/Rego can adapt to the outside world ○ ○ Transform incoming data Build reusable domain-specific abstractions kubernetes metadata: labels: app: nginx namespace: opa spec: containers: - image: nginx image. Pull. Policy: Always name: nginx volume. Mounts: - mount. Path: "/var/run/serviceaccount" name: default-token-tm 9 v 8 openpolicyagent. org
Language: Performance is important ● Goal: policy authors should not be concerned with performance ○ Imperative languages leave global optimization up to the author ● Declarative languages focus on global optimization ○ ○ ○ Not turing complete No side-effects (Almost) order-independent ● OPA targets a range of use cases ○ ○ E. g. , API authorization requires low-latency/high-frequency decision making Rule indexing and partial evaluation enable constant-time evaluation of non-linear policies Links: https: //www. openpolicyagent. org/docs/latest/policy-performance/ https: //blog. openpolicyagent. org/partial-evaluation-162750 eaf 422 https: //blog. openpolicyagent. org/optimizing-opa-rule-indexing-59 f 03 f 17 caf 3 openpolicyagent. org
Thank You! slack. openpolicyagent. org github. com/open-policy-agent/opa
Kubernetes Policy Example JSON/YAML from Kubernetes api. Version: admission. k 8 s. io/v 1 beta 1 kind: Admission. Review request: kind: group: '' kind: Pod version: v 1 namespace: opa object: metadata: labels: app: nginx namespace: opa spec: containers: - image: nginx image. Pull. Policy: Always name: nginx volume. Mounts: - mount. Path: "/var/run/serviceaccount" name: default-token-tm 9 v 8 OPA Playground OPA Policy: All images come from a trusted registry package kubernetes. admission deny[msg] { input. request. kind == "Pod" some i image : = input. request. object. spec. containers[i]. image not startswith(image, "hooli. com") msg : = sprintf("image comes from bad registry: %v", [image]) } openpolicyagent. org
Envoy Policy Example JSON/YAML from Envoy parsed_path: [“api”, “v 1”, “products”] attributes: source: address: Address: Socket. Address: address: "172. 17. 0. 10" Port. Specifier: Port. Value: 36472 destination: address: Address: Socket. Address: address: "172. 17. 0. 17" Port. Specifier: Port. Value: 9080 request: http: id: 13359530607844510314 method: GET headers: . . . path: "/api/v 1/products" OPA Playground OPA Policy: Allow all GET and some PUT package envoy. authz default permit = false # everyone can read everything permit { input. attributes. request. http. method == "GET" } # writes dependent on source permit { input. attributes. request. http. method == "PUT" input. parsed_path = ["v 1", "deployment", x] src : = input. attributes. source addr : = src. address. Address. Socket. Address. address net. cidr_contains("172. 28. 0. 0/16", addr) } openpolicyagent. org
- Slides: 18