Stop using a different policy language, policy model, and policyAPI for every product and service you use. Use OPA for a unifiedtoolset and framework for policy across the cloud native stack.
Whether for one service or for all your services, use OPA todecouple policy from the service's code so you can release,analyze, and review policies (which security and compliance teamslove) without sacrificing availability or performance.
{ "apiVersion": "admission.k8s.io/v1", "kind": "AdmissionReview", "request": { "kind": { "group": "", "kind": "Pod", "version": "v1" }, "object": { "metadata": { "name": "myapp" }, "spec": { "containers": [ { "image": "nginx", "name": "nginx-frontend" }, { "image": "mysql", "name": "mysql-backend" } ] } } }}
{ "deny": [ "image 'mysql' comes from untrusted registry", "image 'nginx' comes from untrusted registry" ]}
{ "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { "kind": { "group": "extensions", "kind": "Ingress", "version": "v1beta1" }, "object": { "metadata": { "name": "prod", "namespace": "bar" }, "spec": { "rules": [ { "host": "initech.com", "http": { "paths": [ { "backend": { "serviceName": "banking", "servicePort": 443 }, "path": "/finance" } ] } } ] } } }}
{ "deny": []}
{ "attributes": { "destination": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 8000 }, "address": "172.17.0.8" } } } }, "request": { "http": { "headers": { ":authority": "example-app", ":method": "GET", ":path": "/pets", "user-agent": "Wget", "x-forwarded-proto": "http", "x-request-id": "4d75f8d5-983f-4ec5-92bb-d27e620b4921" }, "host": "example-app", "id": "8910035251488566126", "method": "GET", "path": "/pets", "protocol": "HTTP/1.1" } }, "source": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 54292 }, "address": "172.17.0.6" } } } } }, "parsed_path": [ "pets" ]}
{ "allow": true}
{ "attributes": { "destination": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 8000 }, "address": "172.17.0.8" } } } }, "request": { "http": { "headers": { ":authority": "example-app", ":method": "GET", ":path": "/pets/owners", "user-agent": "Wget", "x-forwarded-client-cert": "By=spiffe://domain.test/db-server;Hash=331f2f4eb2a1729fa4e0f46c8c663786098151ae571fed7b66680e970f6a0f94;URI=spiffe://domain.test/frontend", "x-forwarded-proto": "http", "x-request-id": "4d75f8d5-983f-4ec5-92bb-d27e620b4921" }, "host": "example-app", "id": "8910035251488566126", "method": "GET", "path": "/pets/owners", "protocol": "HTTP/1.1" } }, "source": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 54292 }, "address": "172.17.0.6" } } } } }, "parsed_path": [ "pets", "owners" ]}
{ "allow": true, "http_request": { "headers": { ":authority": "example-app", ":method": "GET", ":path": "/pets/owners", "user-agent": "Wget", "x-forwarded-client-cert": "By=spiffe://domain.test/db-server;Hash=331f2f4eb2a1729fa4e0f46c8c663786098151ae571fed7b66680e970f6a0f94;URI=spiffe://domain.test/frontend", "x-forwarded-proto": "http", "x-request-id": "4d75f8d5-983f-4ec5-92bb-d27e620b4921" }, "host": "example-app", "id": "8910035251488566126", "method": "GET", "path": "/pets/owners", "protocol": "HTTP/1.1" }, "source_spiffe_id": "spiffe://domain.test/frontend"}
{ "method": "PUT", "owner": "bob@example.com", "path": [ "pets", "pet113-987" ], "user": "alice@example.com"}
{ "allow": false}
{ "pet_list": [ { "breed": "St. Bernard", "name": "Cujo", "up_for_adoption": false }, { "breed": "Collie", "name": "Lassie", "up_for_adoption": true } ], "token": "eyJ1IjoiSFMyNTYiLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UiLCJlbXBsb3llZSI6dHJ1ZSwibmFtZSI6IkFsaWNlIFNtaXRoIn0.vMBYEW8VK9XM7yPkKTu1C3Gy1tOq1A0d4-xYMkkRpEc"}
{ "allowed_pets": [ { "breed": "Collie", "name": "Lassie", "up_for_adoption": true }, { "breed": "St. Bernard", "name": "Cujo", "up_for_adoption": false } ]}
Kubernetes
{ "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { "kind": { "group": "", "kind": "Pod", "version": "v1" }, "object": { "metadata": { "name": "myapp" }, "spec": { "containers": [ { "image": "nginx", "name": "nginx-frontend" }, { "image": "mysql", "name": "mysql-backend" } ] } } }}
{ "deny": [ "image 'mysql' comes from untrusted registry", "image 'nginx' comes from untrusted registry" ]}
{ "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { "kind": { "group": "extensions", "kind": "Ingress", "version": "v1beta1" }, "object": { "metadata": { "name": "prod", "namespace": "bar" }, "spec": { "rules": [ { "host": "initech.com", "http": { "paths": [ { "backend": { "serviceName": "banking", "servicePort": 443 }, "path": "/finance" } ] } } ] } } }}
{ "deny": []}
Envoy
{ "attributes": { "destination": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 8000 }, "address": "172.17.0.8" } } } }, "request": { "http": { "headers": { ":authority": "example-app", ":method": "GET", ":path": "/pets", "user-agent": "Wget", "x-forwarded-proto": "http", "x-request-id": "4d75f8d5-983f-4ec5-92bb-d27e620b4921" }, "host": "example-app", "id": "8910035251488566126", "method": "GET", "path": "/pets", "protocol": "HTTP/1.1" } }, "source": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 54292 }, "address": "172.17.0.6" } } } } }, "parsed_path": [ "pets" ]}
{ "allow": true}
{ "attributes": { "destination": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 8000 }, "address": "172.17.0.8" } } } }, "request": { "http": { "headers": { ":authority": "example-app", ":method": "GET", ":path": "/pets/owners", "user-agent": "Wget", "x-forwarded-client-cert": "By=spiffe://domain.test/db-server;Hash=331f2f4eb2a1729fa4e0f46c8c663786098151ae571fed7b66680e970f6a0f94;URI=spiffe://domain.test/frontend", "x-forwarded-proto": "http", "x-request-id": "4d75f8d5-983f-4ec5-92bb-d27e620b4921" }, "host": "example-app", "id": "8910035251488566126", "method": "GET", "path": "/pets/owners", "protocol": "HTTP/1.1" } }, "source": { "address": { "Address": { "SocketAddress": { "PortSpecifier": { "PortValue": 54292 }, "address": "172.17.0.6" } } } } }, "parsed_path": [ "pets", "owners" ]}
{ "allow": true, "source_spiffe_id": "spiffe://domain.test/frontend"}
Application
{ "method": "PUT", "owner": "bob@example.com", "path": [ "pets", "pet113-987" ], "user": "alice@example.com"}
{ "allow": false}
package application.authz# Everyone can see pets up for adoptionallowed_pets contains pet if {some pet in input.pet_listpet.up_for_adoption}# Employees can see all pets.allowed_pets contains pet if {[_, payload, _] := io.jwt.decode(input.token)payload.employeesome pet in input.pet_list}
{ "allowed_pets": [ { "breed": "Collie", "name": "Lassie", "up_for_adoption": true }, { "breed": "St. Bernard", "name": "Cujo", "up_for_adoption": false } ]}
Declarative. Express policy ina high-level,declarative language that promotes safe,performant, fine-grained controls. Use a languagepurpose-built for policy in a world where JSON ispervasive. Iterate, traverse hierarchies, and apply150+ built-ins like string manipulation and JWTdecoding to declare the policies you want enforced.
Context-aware. Leverageexternal information towrite the policies you really care about. Stopinventing roles that represent complex relationshipsthat years down the road no one will understand.Instead, write logic that adapts to the world aroundit and attach that logic to the systems that need it.
Deploy OPA as a separate process on the samehost as your service. Integrate OPA by changingyour service’s code, importing an OPA-enabledlibrary, or using a network proxy integrated with OPA.
Embed OPA policies into your service. Integrate OPA as a Golibrarythat evaluates policy, or integrate a WebAssembly runtimeand use OPAto compile policy to WebAssembly instructions.
OPA embraces policy-as-code, complete with tools that help peopleuse and understand the policies they putinplace. Integrated development environments, testing, profiling,coverage, automated performance tuning, andhotreloading aren’t just things you need for programming--you need themfor policy too, and OPA delivers.
© 2025 Open Policy Agent contributors.Licensed under the Apache License, Version 2.0. See thecontributing documentationfor information about contributing.
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,please see ourTrademark Usage page.