Open Policy Agent: The Policy Engine That Rewrote Its Own Language
Styra — founded 2015 by two ex-Nicira/VMware engineers who had built OpenStack's Congress policy engine — pushed the root commit on 2015-12-28. The Rego language, the Gatekeeper CRD rebuild, the 1.0 syntax purge, and a 2025 Apple acquihire followed.
Sources
- open-policy-agent/opa repository (created 2015-12-28, GitHub repo ID 48714685; 12.4k stars today)
- Root commit 7eb56674 — 'Initial commit', Tim Hinrichs (2015-12-28)
- Early parser-era commits — jsonlog parser and PR #5 (Tim Hinrichs, 2016-01)
- Built-ins era — PR #73 merge, string/regexp built-ins (Torin Sandall, 2016-07)
- OPA docs: The Rego policy language — 'inspired by Datalog, joins are implicit'
- open-policy-agent/kube-mgmt — the original OPA sidecar for Kubernetes (created 2017-06-14)
- CNCF project page — accepted to CNCF on March 29, 2018; Incubating April 2, 2019; Graduated January 29, 2021
- CNCF: Cloud Native Computing Foundation Announces Open Policy Agent Graduation (2021-02-04)
- Cure53: Pentest-Report Open Policy Agent 08.2018 — the CNCF-funded security audit
- OPA SECURITY_AUDIT.pdf (Cure53 results, committed in the repo)
- Gatekeeper SECURITY_AUDIT.pdf (the second incubation-era audit)
- Kubernetes blog: OPA Gatekeeper — Policy and Governance for Kubernetes (Rita Zhang, Max Smythe, Craig Hooper, Tim Hinrichs, Lachie Evenson, Torin Sandall — 2019-08-06)
- kubernetes/website PR #14487 — the Gatekeeper blog post, merged 2019-08-06
- open-policy-agent/gatekeeper repository (created 2018-10-26, GitHub repo ID 154894457; 4.3k stars today)
- VMblog (Rita Zhang, Microsoft): Policy in Kubernetes — Gatekeeper v3 first stable release in August 2020
- open-policy-agent/conftest — Rego tests for structured configuration (created 2019-03-28)
- Cisco Investments: Styra — Security as Code for Cloud-Native (founding story, Congress roots, 15th graduated project, Series B with Battery Ventures)
- Unusual Ventures: Styra — Series A announcement with Accel and A.Capital (Nicira/VMware origin, the Declarative Authorization Service, Bill Mann as CEO)
- Styra's Unusual Journey (Hinrichs, Koponen, Mann) — $14M Series A in November 2019, $40M Series B in May 2021
- CNCF Humans of Cloud Native: Torin Sandall — Co-creator of OPA
- OPA v0.36.0 release notes (2022-01-04) — future keyword imports in the wild
- OPA v0.59.0 release notes (2023-11-30) — the --rego-v1 transition flag
- OPA v0.70.0 release notes (2024-10-31) — the final v0 release
- OPA v1.0.0 release notes (2024-12-20) — if/contains mandatory, every/in default, 10-20% evaluation speedup
- OPA blog: Announcing OPA 1.0 — A New Standard for Policy as Code (2024-12)
- OPA docs: The v0 compatibility guide
- OPA v1.22.0 release notes (2026-10-29) — the new rego.v2 import
- OPA v1.22.2 release notes (2026-11-06) — current tip of the 1.x line
- open-policy-agent/opa MAINTAINERS.md — today's maintainer roster and affiliations
- CNCF Atlas: Open Policy Agent — history (the August 2025 Styra-to-Apple acquihire)
- Kubernetes blog: Validating Admission Policy Is Generally Available in 1.30 (2024-04-24)
- KEP-3488: CEL for Admission Control — the in-tree alternative that squeezed the webhook niche
Every platform team eventually rediscovers the same problem: authorization logic is smeared across API gateways, service meshes, Kubernetes admission, CI pipelines, and a hundred if-statements nobody dares to delete. Open Policy Agent was built in 2015 to collapse all of it into one declarative engine with one query language. It succeeded so thoroughly that the language itself became the product — and then, eight years in, the project did something almost nothing in the CNCF portfolio has dared: it broke its own syntax on purpose, shipped OPA 1.0, and deprecated every policy ever written for v0. This is the archaeology of how a two-founder startup became the cloud's default authorization engine — the sidecar model it abandoned, the CRD rebuild that made Gatekeeper, the audit that embarrassed it into hardening, and the acquihire that left its founding company gone while the engine keeps shipping.
The Origin: Congress Veterans and a Christmas Root Commit
The two people who wrote the first lines of OPA were not Kubernetes people. Tim Hinrichs and Teemu Koponen came out of Nicira — the software-defined networking company VMware acquired in 2012 — and Hinrichs spent his VMware years working on OpenStack Congress, a policy engine for OpenStack whose entire premise was that infrastructure policy should be a declarative query over a database of resources. That premise did not survive contact with OpenStack's politics, but it survived in its author. When Hinrichs and Koponen heard customers complain that authorization had to be re-implemented in every layer of every system, they left to build the general version. They founded Styra in 2015 and started the Open Policy Agent project, as Cisco's investment team later told it, "to unify policy enforcement across different technologies and systems."
The repository's birth is unusually well-documented, because the root commit is the project's founding act:
open-policy-agent/opa (GitHub repo ID 48714685, created 2015-12-28T22:08:25Z)
├── root 7eb56674 "Initial commit" (timothyhinrichs, 2015-12-28)
├── f260b790 "Merge pull request #2 from timothyhinrichs" (timothyhinrichs, 2015-12-28)
├── cecbc342 "Add parser test" (timothyhinrichs, 2016-01-04)
├── 9cfea2c2 "Add jsonlog parser" (timothyhinrichs, 2016-01-06)
├── 1c4494e1 "Changed representation of dictionary
│ to handle variables" (timothyhinrichs, 2016-01-06)
└── fdda9817 "Merge pull request #73 from tsandall/dev" (tsandall, 2016-07-22)
— by mid-July 2016: string built-ins, regexp built-ins, cross-compile refactors
Read the commit messages and the design priority is obvious: OPA began as a language implementation, not a Kubernetes tool. Before there was a Docker image, before there was an admission webhook, there was a parser — a query language over JSON that became Rego, inspired by Datalog, with implicit joins over nested document data. Torin Sandall shows up in the history in 2016 building the standard library — string manipulation, regexp match built-ins — and becomes the project's co-creator and most public face for the next decade. The "agent" in the name is doing honest work: the 2016-era vision was a daemon, or a Go library, that any system could call for a policy decision over HTTP or in-process.
That generality is the first thing platform engineers should internalize about OPA, because it explains everything that came later — including the crisis points. OPA was never a Kubernetes admission controller. Kubernetes was one integration among many: in the early years the docs carried recipes for Docker engine authorization plugins, HTTP API authorization, SSH daemon integration, and even PAM policies for sudo — the CNCF's 2018 Cure53 audit literally reproduces a scenario where OPA decides who may run sudo on a Linux host. The Kubernetes story, the one that made OPA famous, arrived later and was rebuilt twice.
The Timeline: From Sidecar ConfigMaps to the CNCF's Authorization Standard
- 2015-12-28 — Tim Hinrichs pushes the root commit
Initial commitinto the new open-policy-agent/opa repository, six months after co-founding Styra with ex-Nicira colleague Teemu Koponen. - 2016-01 — Parser-first development: PRs #2 and #5 land the query language core — Datalog-style evaluation over JSON documents. Torin Sandall joins and spends 2016 building the built-in function library (PR #73 merges in July).
- 2016 — The "policy for everything" era: documentation and examples cover Docker engine authz plugins, HTTP API authorization, and SSH/PAM integration. Kubernetes is a use case, not the product.
- 2017-06-14 — Styra creates
open-policy-agent/kube-mgmt, the sidecar that loads Rego policies from ConfigMaps into OPA pods. Kubernetes deployment now means: OPA + kube-mgmt sidecar + policies hand-stuffed into ConfigMaps. - 2018-03-29 — OPA is accepted into the CNCF sandbox. Styra donates the project — an unusually early hand-off of a company's core asset, one year before the company raises its Series A.
- 2018-08 — The Linux Foundation/CNCF funds a Cure53 audit: 18 days, six testers, six findings. Two are vulnerabilities — an XSS in the query UI (High) and an SSRF via
http.sendthrough the open query endpoint (Medium) — plus a sudo-policy bypass in the documented PAM setup. The report's recurring recommendation: secure-by-default, because OPA's flexibility "heavily relies on proper configuration." - 2018-10-26 — The Gatekeeper repository is created in the OPA org. Gatekeeper v1, donated by Styra, is OPA plus the kube-mgmt sidecar enforcing ConfigMap-based policies through a validating webhook. Early commits (Nikhil Bhatia, Dave Strebel, November 2018) wire a single mutating-and-validating endpoint — one commit message reads
Update the muate webhook endpoint to /admit, typo and all. - 2019-03-28 —
open-policy-agent/conftestis created: Rego unit tests for Terraform, Kubernetes, and other structured config — the clearest signal that the language, not the runtime, is the asset. - 2019-04-02 — OPA moves to CNCF Incubating, roughly one year after sandbox acceptance.
- 2019-08-06 — The Gatekeeper v3 announcement lands on the Kubernetes blog (Rita Zhang, Max Smythe, Craig Hooper, Tim Hinrichs, Lachie Evenson, Torin Sandall): the sidecar/ConfigMap model is abandoned for a kubebuilder-built controller with CRD-based constraints — ConstraintTemplates, constraint CRDs, and audit results stored on the CRDs themselves. A collaboration between Google, Microsoft, Red Hat, and Styra; the blog PR (kubernetes/website #14487) merges the same day.
- 2019-11-12 — Styra raises a $14M Series A led by Accel. Bill Mann, appointed CEO in 2018, drives the commercial product (Styra DAS — a management plane over OPA) while the engine stays in the foundation.
- 2020-08 — Gatekeeper v3 publishes its first stable release. The CRD model — shareable constraint templates, parameterized constraints, audit — becomes the de facto way to do Kubernetes admission policy with Rego.
- 2021-01-29 — OPA graduates in the CNCF (announced February 4). The graduation release counts 90+ individuals from ~30 organizations, maintainers from four companies (Google, Microsoft, VMware, Styra), production users from Goldman Sachs to Netflix to Pinterest to T-Mobile, and a user survey where 91% of ~150 organizations run OPA from QA through production. Cisco calls it the 15th graduated project and the first focused on authorization.
- 2021-05 — Styra raises a $40M Series B led by Battery Ventures, with Capital One Ventures and Citi Ventures joining; Cisco's investment team counts OPA at more than 75 million downloads in the same window.
- 2021–2022 — The syntax reckoning begins:
if,in, andeveryship as opt-in "future keywords" behind feature imports (v0.36.0's changelog is already fixingopa fmtbugs in future-keyword imports by January 2022). Old rule bodies — bare, brace-only — start their long deprecation. - 2023-11-30 — v0.59.0 introduces the
--rego-v1flag foropa fmtandopa check: policy authors can now migrate their modules to the planned 1.0 syntax a year before it becomes mandatory. - 2024-04-24 — Kubernetes 1.30 ships ValidatingAdmissionPolicy GA: CEL-based admission validation evaluated in-process by the API server, no webhook at all. The "simple admission check" niche OPA/Gatekeeper occupied suddenly has an in-tree competitor with zero infrastructure cost.
- 2024-10-31 — v0.70.0, the last v0 release ever, ships the optimized read mode for OPA's in-memory store. There is no v0.71.
- 2024-12-20 — OPA 1.0: the future becomes the present.
iffor rule definitions andcontainsfor multi-value rules are mandatory,everyandinneed no imports, and strict-mode checks (duplicate imports, shadowing) become defaults. A v0-compatibility flag and guide keep the old world compiling, and a batch of allocation PRs by Anders Eknert nets a 10–20% evaluation speedup to sweeten the break. - 2025-08 — Apple acquihires Styra: the three founders (Tim Hinrichs, Teemu Koponen, Torin Sandall) and several engineers move to Apple, and the company winds down — with no public acquisition filing. The project's founding company is gone; its MAINTAINERS.md now lists the six opa-area maintainers as Apple-affiliated.
- 2026-09-30 — conftest gains a new independent maintainer (James Alseth) — the first non-Apple, non-vendor maintainer entry added since the acquihire.
- 2026-10-29 — v1.22.0 ships a new
rego.v2import — the language is iterating again — plus partial evaluation that unrollseveryover a known domain, and a breaking change: stricter bundle signature filename handling. - 2026-11-06 — v1.22.2, the current tip of the 1.x line, lands six days before this tale. The Gatekeeper side of the family is at v3.23.1 (August 2026) with a v3.24.0 beta in flight.
Crisis Points & Architectural Pivots
Crisis one: the ConfigMap sidecar model. OPA's first Kubernetes story was
operationally honest but primitive. You ran an OPA pod, attached the kube-mgmt sidecar, and
the sidecar discovered policies by scanning ConfigMaps labeled
openpolicyagent.org/policy=rego and syncing their contents into the
engine:
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-policy
labels:
openpolicyagent.org/policy: rego # kube-mgmt syncs this ConfigMap into OPA
data:
policy.rego: |
package kubernetes.admission
deny[msg] {
input.request.kind.kind == "Ingress"
not input.request.object.spec.tls
msg := "ingress must be TLS-only"
}
This is the shape the Kubernetes blog post later described as Gatekeeper v1 — "OPA as the admission controller with the kube-mgmt sidecar enforcing configmap-based policies… donated by Styra" — with v2 a Microsoft donation of the same idea with audit bolted on. The toil was structural, not incidental: policies were opaque ConfigMap blobs with no parameters, no reusable abstractions, no cluster-visible state of what was enforced, and drift between clusters was invisible. Every team that adopted it ended up maintaining a private library of copy-pasted Rego. The v3 rebuild — announced August 6, 2019 as "a collaboration between Google, Microsoft, Red Hat, and Styra" — moved the entire policy lifecycle into Kubernetes resources:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
listKind: K8sRequiredLabelsList
plural: k8srequiredlabels
singular: k8srequiredlabels
validation:
openAPIV3Schema: # parameters the constraint instances will pass
properties:
labels:
type: array
items: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
deny[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
One CRD now carries the Rego and the parameter schema; administrators instantiate
it as ordinary constraint CRDs (kind: K8sRequiredLabels) with a
match block and parameters; audit results are written back to the
constraint's own status. The shareable-template problem — Gatekeeper's explicit design goal,
"to enable users to customize admission control via configuration, not code" — was solved by
the same primitive every other Kubernetes operator uses. The pivot is a close structural
cousin of Helm deleting Tiller: the K8s integration was rebuilt to be
Kubernetes-native, and the old path (kube-mgmt still lives, unarchived, in the OPA org)
became a relic you should not build on today.
v1/v2 ERA (2017-2019): policies ride ConfigMaps into a sidecar-synced engine
kube-apiserver ──webhook──▶ gatekeeper pod
├─ OPA (policies + data, in memory)
└─ kube-mgmt (sync loop)
▲
ConfigMaps labeled openpolicyagent.org/policy=rego
(hand-authored, per-cluster, opaque)
toil: no parameters, no reusable templates, no enforcement state on objects,
no audit record, silent drift between clusters
v3 ERA (2019-present): policies are cluster resources
kube-apiserver ──webhook──▶ gatekeeper v3 controller (kubebuilder)
▲ ├─ OPA as embedded library (in-process)
│ └─ constraint framework
│ CRD watch / reconcile
ConstraintTemplate CRD ──▶ generates Constraint CRD kind ──▶ constraint instances
(Rego + parameter schema) (match + parameters)
──▶ deny/warn at admission
violations written back to constraint status (audit) — enforcement state is queryable
Crisis two: the language. By the early 2020s the number-one community
complaint about OPA was not performance or the engine — it was that Rego's v0 rule bodies
were hard to read. A rule was just a name, followed by a bare brace block, and every line
inside was an implicit conjunct; there was no visible keyword separating the rule head from
its body, and comprehension-heavy idioms made authoring errors common. The project's answer
was a two-year, opt-in deprecation: the new syntax shipped first as "future keywords"
(if, in, every)
behind explicit imports, then v0.59.0 (November 2023) added a
--rego-v1 flag to opa fmt and
opa check so teams could migrate their modules a year ahead, and
finally OPA 1.0 (December 20, 2024) flipped the default:
v0 (every OPA release before 1.0):
package example
allow {
input.method == "GET"
input.path == ["salary", employee_id]
data.salaries[employee_id] == input.user
}
v1 (OPA 1.0+, December 2024 — default, no imports needed):
package example
allow if {
input.method == "GET"
input.path == ["salary", employee_id]
data.salaries[employee_id] == input.user
}
multi-value rules gain 'contains':
allowed_users contains user if user in data.admins
'in' and 'every' need no future-keywords imports;
strict-mode checks (duplicate/shadowing imports) become defaults.
Legacy policies keep compiling behind the v0 compatibility flag.
Credit where due: this was a deprecation done the way the CNCF wishes every project did it — two years of opt-in, a mechanical migration flag, a compatibility mode, and a hard cutover only at a major version that also bought users a 10–20% evaluation speedup from a batch of memory-allocation rewrites (PRs #7172–#7222, Anders Eknert). The cost was real anyway: every Rego tutorial, blog post, and library written before December 2024 now renders in a syntax the current engine treats as legacy, and every large policy estate had to budget a migration sprint. Ask any team that ran it what their CI said the week they upgraded without reading the release notes.
Crisis three: the founding company disappears. In August 2025, Apple
acquihired Styra — the three founders and several engineers moved over, and the company
wound down with no public acquisition filing, as the CNCF Atlas history records it. For most
CNCF projects that would be a governance scare; for OPA it landed on a graduated project with
foundation-owned governance, an audited security process, and a maintainer bench that
keeps shipping: the 1.21 indexer rewrite (September 2026) and v1.22.0's
rego.v2 import (October 2026) both landed post-acquihire, and
conftest gained a new independent maintainer in September 2026. The uncomfortable fact is
still on the screen in MAINTAINERS.md: every maintainer of the core opa repository
area is now Apple-affiliated. The single-employer maintainer concentration that killed
countless open source projects is now OPA's structural risk, mitigated — so far — only by
CNCF governance and Apple's continued investment. Watch that table.
Community Engine & Corporate Influence: Who Actually Built It
The CNCF arc was fast by foundation standards: sandbox March 29, 2018; incubating April 2, 2019; graduated January 29, 2021 — announced February 4 with production users from Goldman Sachs, Netflix, Pinterest, and T-Mobile, 90+ individuals from ~30 organizations, and maintainers from four companies (Google, Microsoft, VMware, Styra). The graduation press release also carries the two incubation-era security audits (OPA's Cure53 report and Gatekeeper's own audit) and the user-survey stat platform teams still quote: 91% of ~150 surveyed organizations ran OPA somewhere between QA and production, with configuration authorization — Kubernetes admission — and API authorization the two dominant use cases. Cisco Investments counted OPA as the 15th CNCF graduated project and the first focused on authorization.
The commercial engine behind the first five years was Styra: founded 2015 by Tim Hinrichs and Teemu Koponen (ex-Nicira, where Hinrichs went on to build OpenStack's Congress policy engine at VMware), with Bill Mann installed as CEO in 2018, a $14M Series A led by Accel in November 2019, and a $40M Series B led by Battery in May 2021 — by then claiming over a million OPA downloads a week. Torin Sandall, the third OPA co-creator, was the project's public face for most of that decade. The company monetized a management plane (Styra DAS) over the engine it had given away; the engine's growth curve — 75M+ downloads by the Series B announcement — is the open source working as intended.
Today's maintainer table, straight from the repository's MAINTAINERS.md, tells the
post-Styra story with unusual candor. Core opa: Anders Eknert,
Ash Narkar, Charlie Egan, Stephan Renatus, Tim Hinrichs, Torin Sandall — all Apple. The
Gatekeeper cluster (gatekeeper, gatekeeper-library, frameworks/constraints,
cert-controller, external-data-provider): Max Smythe at Google, Sertaç Özercan and Jaydip
Gabani at Microsoft. Conftest: James Alseth, independent, added September 30, 2026. The
emeritus list — Rita Zhang (Microsoft, co-author of the Gatekeeper v3 announcement), Patrick
East, Will Beason, Ernest Wong, Craig Tabita, Oren Shomron, Andrew Peabody, Nilekh
Chaudhari — reads like a roster of every era: the Styra founding years, the
Microsoft-Google Gatekeeper collaboration, and the CNCF-era contributors who carried the
project to graduation.
The ecosystem footprint is where OPA's real gravity shows. The open-policy-agent GitHub organization spans the engine (12.4k stars), Gatekeeper (4.3k stars), the constraint frameworks, the template library, conftest for config testing, the Envoy authorization plugin, and the certificate controller that bootstraps Gatekeeper's webhook TLS. Rego long ago escaped the admission niche: it now tests Terraform plans in CI, authorizes API calls in service meshes, gates CI pipelines, and powers commercial authorization products — the "policy as code" category that Cisco's investors credited Styra with creating. The engine's adoption story is the same one the Helm tale tells: the artifact everyone standardized on (there, the chart format; here, a query language) outgrew the tool that shipped it.
Current Trajectory: The Verdict
The trajectory question for OPA in late 2026 is not whether the engine works — v1.22.2
shipped six days before this tale, and the 1.x line's biggest recent change is a new
rego.v2 import in v1.22.0, which tells you the project's center of
gravity is still the language. The question is who needs a general-purpose policy engine
now that the platforms have learned from it. Kubernetes 1.30 graduated
ValidatingAdmissionPolicy (April 2024): CEL expressions evaluated in-process by the API
server, no webhook, no sidecar, no extra failure domain — and its own KEP is explicit that
it targets "the vast majority of validating admission use cases." For simple label checks,
resource limits, and security-context validation, the honest engineering answer is the
in-tree feature; running Gatekeeper for those is paying the webhook tax to keep a language
you may not need (we run the numbers in
our Gatekeeper vs. Kyverno guide).
What CEL cannot do — by design — is everything that made OPA bigger than admission in the
first place. A ValidatingAdmissionPolicy sees the request in front of it; it does not join
the object against your CMDB, your ownership data, or your spend graph without more
machinery, and the same CEL policy does not follow your service out of the cluster into your
API gateway, your CI pipeline, and your data layer. OPA's defensible territory is exactly the
original 2015 thesis: one declarative language, one engine, policy decisions wherever the
data lives — admission being merely the highest-volume integration. The performance
envelope is actively managed: the 1.21 release rewrote rule indexing for large policy sets
(see our
1.21 release coverage for the numbers and two silent
breaking changes worth knowing about), and 1.22 extended partial evaluation to unroll
every over known domains — the compile-time work that makes
data-filtering use cases viable.
Verdict: OPA is the rare infrastructure project that survived two acts of institutional courage — donating its core asset to a foundation before its Series A, and deleting its own v0 syntax at the height of its adoption — and its current form is more library and language than product. Who should skip it? Clusters on Kubernetes ≥1.30 whose entire policy estate is simple admission checks should use ValidatingAdmissionPolicy and skip the webhook infrastructure; teams that would have to hire or train for Rego specifically for one use case should not bother — the language rewards exactly the platform teams that get leverage from writing policy once and enforcing it everywhere; and organizations allergic to the current bus-factor risk of an all-Apple maintainer bench should pin their OPA versions and watch MAINTAINERS.md more closely than the release notes. Everyone else — platform teams building golden paths, anyone unifying authorization across K8s admission, API gateways, and CI, and anyone who wants their infrastructure rules to be a queryable, testable artifact rather than scattered if-statements — gets the most honest answer in the policy space: a language that a decade of production use has failed to dislodge, maintained by the people who wrote it, shipped twice in the two weeks this tale was written. (For the delivery tools that consume OPA policies at deploy time rather than admission time, see our Argo CD and Flux tales; for the packaging half of the platform equation, the Helm tale covers the other engine that standardized a format and then had to delete part of itself to grow up.)