The Open Policy Agent (OPA) is an open source, general-purpose policy engine that enables unified, context-aware policy enforcement across the entire stack.
2. ● Community
● Overview
○ Features
○ Integrations
○ Roadmap
● Use case deep dive
○ Kubernetes admission control
○ Microservice API authorization
● Q&A
Agenda
3. OPA: Community
Inception
Project started in 2016 at
Styra.
Goal
Unify policy enforcement
across the stack.
Use Cases
Admission control
Authorization
ACLs
RBAC
IAM
ABAC
Risk management
Data Protection
Data Filtering
Users
Netflix
Chef
Medallia
Cloudflare
State Street
Pinterest
Intuit
Capital One
...and many more.
Today
CNCF project (Sandbox)
36 contributors
400 slack members
1.6K stars
20+ integrations
9. openpolicyagent.org
Service
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
Input can be any JSON value:
"alice"
["v1", "users", "bob"]
{"kind": "Pod", "spec": …}
Output can be any JSON value:
true
"request rejected"
{"servers": ["web1", "web2"]}
OPA: General-purpose policy engine
"Service" refers to any one of:
● Custom service
● API gateway
● Message broker
● Kubernetes API server
● CI/CD pipeline script
10. openpolicyagent.org
● 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?
OPA: Features
Service
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
11. openpolicyagent.org
● 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?
● Library, sidecar, host-level daemon
○ Policy and data are kept in-memory
○ Zero decision-time dependencies
OPA: Features
Service
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
12. openpolicyagent.org
● 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?
● Library, sidecar, host-level daemon
○ Policy and data are kept in-memory
○ Zero decision-time dependencies
● 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
OPA: Features
Service
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
13. openpolicyagent.org
● 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?
● Library, sidecar, host-level daemon
○ Policy and data are kept in-memory
○ Zero decision-time dependencies
● 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
● Tooling to build, test, and debug policy
○ opa run, opa test, opa fmt, opa deps, opa check, etc.
○ VS Code plugin, Tracing, Profiling, etc.
OPA: Features
Service
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
14. openpolicyagent.org
OPA: Integrations
Data Filtering
Admission Control “Restrict ingress hostnames for payments team.”
“Ensure container images come from corporate repo.”
API Authorization
“Deny test scripts access to production services.”
“Allow analysts to access APIs serving anonymized data.”
Data Protection
Linux PAM SSH & sudo “Only allow on-call engineers to SSH into production
servers.”
"Trades exceeding $10M must be executed between
9AM and 5PM and require MFA."
"Users can access files for past 6 months related to
the region they licensed."
18. openpolicyagent.org
● As of #990, OPA policies can be compiled into
WebAssembly (Wasm). Wasm provides a
safe, efficient, portable runtime for policy
enforcement on platforms like CDNs, AWS
Lambda, and more.
● Over the next few months, Wasm support will
be extended to cover more of the policy
language and enable daemonless OPA
integrations in a variety of languages. See
#1024 for details.
WebAssembly
19. openpolicyagent.org
Hierarchical Permissions
● Hierarchical permission models are
common (e.g., parent node permissions
are a superset of child node permissions,
recursively.) Today, OPA does not permit
recursion in policies. This prevents policies
from performing traversal operations that
would check these kinds of permissions.
See #947.
● Plan: evaluate options for supporting
hierarchical permission models in OPA
and implement solution.
Possible Solutions:
1. Add support for limited forms of
recursion.
2. Add support for keyword/operator
like transitive closure.
3. Keep existing constraints but
document & optimize pattern for
fixed-depth solution. E.g., (😱):
tc(tree, key) = {key} | x1 | x2 | x3 {
x1 := {x | x := tree[key][_]}
x2 := {x | x := tree[x1[_]][_]}
x3 := {x | x := tree[x2[_]][_]}
}
20. openpolicyagent.org
Rego Playground
● Users don't have a good way to easily share snippets of
Rego. Mediums like Slack and Gists are fine for trivial
examples but are lacking in terms of discoverability,
readability, etc.
● Providing an online playground (similar to play.golang.org)
would allow users to easily experiment with and share
snippets of Rego.
● The MVP for the playground will provide users with a way
to write, check, evaluate, and publish snippets of policy so
that they can be shared with others.
package foo
allow {
...
}
allow {
...
}
allow {
...
}
Output
{
"allow": true
}
Rego Playground Share
21. openpolicyagent.org
LDAP Built-in Functions
● LDAP is a common source of context for policy decisions. Today, we
recommend that integrations embed that context into a token during
authentication. In some cases, this approach does not scale well and/or it
may create undesirable coupling between the auth/n server and the policy.
● Goal: Add built-in functions to Rego that allow policies to execute LDAP
queries during evaluation. See #938.
22. openpolicyagent.org
Variable Scoping
● Earlier this year OPA added dedicated
operators for assignment and
comparison (:= and ==). While less
powerful than the unification operator (=)
their scoping rules are more obvious to
new users and avoid capturing issues in
large policy files.
● OPA does not currently have a similar
solution for variables that appear as
reference operands.
Goal
Introduce syntax so that authors can make
variables in references shadow globals.
Example (current behaviour)
x = 1
p {
q[x] # refers to global x
}
23. openpolicyagent.org
Fuzz Testing
● In #948 we discovered a panic in the error handling portion in OPA's parser.
To uncover similar issues and reduce the likelihood of panics in the future, we
are going to apply a fuzzer (go-fuzz) seeded with a corpus of valid Rego
extracted from the OPA codebase.
24. openpolicyagent.org
Frontpage Refresh
● Over the past year, the OPA end-user community
has grown substantially. We have also seen OPA
integrated with a number of new projects.
● While the current frontpage describes the goals of
the project, it lacks concrete examples of the types
of problems OPA is helping solve today.
● The goal of the frontpage refresh is to give
newcomers a clearer idea of how they can
leverage OPA.
25. openpolicyagent.org
Documentation Refresh
● As OPA has matured, we have learned about what works in the
documentation (and what doesn't). We plan to rework some of the
documentation to help people ramp up on OPA concepts and mechanics
quicker.
● New Docs:
○ "Examples" section that serves as a policy catalogue for popular projects.
○ "Cheat Sheet" section that captures common policy language idioms. See #268.
○ "Integration" section that explains OPA integration options. See #372.
● Improved Docs:
○ Refactor docs to prefer := and == over =. See #952.
○ Extend Best Practices & FAQ with more information. See #633.
26. openpolicyagent.org
Help Wanted
● Add authentication based on mutual TLS (#1040)
● Add stack trace support to topdown (#555)
● Integrations:
○ Prometheus integration to monitor for policy violations
■ OPA policies can audit the state of systems (e.g., Kubernetes) to detect problems
■ Query results could be pushed into Prometheus and surfaced with graphs (e.g., # of
security context violations/time.)
○ Spinnaker integration to enforce invariants
■ Similar use case to Kubernetes admission control, Terraform risk management.
■ Integrate with Spinnaker to enforce OPA policies in CD pipelines.
Issues labelled low-hanging-fruit or help-wanted are good candidates for first contribution.
28. openpolicyagent.org
How does OPA work?
Salary Service V1
OPA
Policy
(Rego)
Data
(JSON)
Request
DecisionQuery
Example policy
"Employees can read their own salary
and the salary of anyone they manage."
30. openpolicyagent.org
OPA: Declarative Language (Rego)
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "bob"
31. openpolicyagent.org
OPA: Declarative Language (Rego)
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "bob"
32. openpolicyagent.org
OPA: Declarative Language (Rego)
allow = true {
input.method = "GET"
input.path = ["salary", "bob"]
input.user = "bob"
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "bob"
33. openpolicyagent.org
OPA: Declarative Language (Rego)
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
Different user now!
34. openpolicyagent.org
OPA: Declarative Language (Rego)
allow = true {
input.method = "GET"
input.path = ["salary", "bob"]
input.user = "bob"
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
This statement will "FAIL"
Different user now!
35. openpolicyagent.org
OPA: Declarative Language (Rego)
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
Context Data
{
"managers": {
"bob": ["alice", "fred"]
"alice": ["fred"]
}
}
36. openpolicyagent.org
OPA: Declarative Language (Rego)
import data.managers
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = managers[employee_id][_]
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
Context Data
{
"managers": {
"bob": ["alice", "fred"]
"alice": ["fred"]
}
}
37. openpolicyagent.org
OPA: Declarative Language (Rego)
import data.managers
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
allow = true {
input.method = "GET"
input.path = ["salary", "bob"]
input.user = managers["bob"][_]
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
Context Data
{
"managers": {
"bob": ["alice", "fred"]
"alice": ["fred"]
}
}
38. openpolicyagent.org
OPA: Declarative Language (Rego)
import data.managers
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
allow = true {
input.method = "GET"
input.path = ["salary", "bob"]
input.user = "alice"
}
Example policy
Employees can read their own salary and the
salary of anyone they manage.
Input Data
method: "GET"
path: ["salary", "bob"]
user: "alice"
Context Data
{
"managers": {
"bob": ["alice", "fred"]
"alice": ["fred"]
}
}
39. openpolicyagent.org
OPA: Declarative Language (Rego)
import data.managers
allow = true {
input.method = "GET"
input.path = ["salary", employee_id]
input.user = employee_id
}
allow = true {
input.method = "GET"
input.path = ["salary", "bob"]
input.user = "alice"
}
More information at openpolicyagent.org
See How Do I Write Policies?
- Explains language constructs
See Language Reference
- Documents built-in functions: glob,
regex, JWTs, x509, etc.
See Tutorials section
- HTTP APIs, Kubernetes, Docker,
Terraform, Kafka, SSH, etc.
42. openpolicyagent.org
Use Cases: Kubernetes
apiserver
authorization admission control
scheduler
federation control plane
OPA
OPAOPA
OPA
Current Use Cases
● Federated Workload Placement
● Pod Scheduling
● Authorization
● Admission Control
● Audit
Future Use Cases
● Storage policy (in progress)
● Network policy
controllers
nodes
43. openpolicyagent.org
Use Cases: Kubernetes: Admission Control
apiserver
admission controllers
quota execwebhook
kubectl apply -f app.yaml
OPA
Example Policies
● Images may only be pulled from internal
registry
● Only scanned images may be deployed in
namespaces A, B, and C
● QA team must sign-off on image before
deployed to production
● Stateful deployments must use ‘recreate’
update strategy
● Developers must not modify selectors or
labels referred to by selectors after
creation
● Containers must have CPU and memory
resource requests and limits set
● Containers cannot run with privileged
security context
● Services in namespace X should have
AWS SSL annotation added
51. openpolicyagent.org
Use Cases: Microservice APIs
Example Policies
● Service Graph: “Reviews service can
talk to ratings but details cannot.”
● Org Chart: “Managers can view
reviews of team members but peers
cannot.”
● PII: “Only HR can see SSN in
employee details.”