OPA Filter
An opa filter works by turning policy rules into partial queries or request checks. Your app sends user details to Open Policy Agent and gets back conditions to apply. Teams often start with simple role checks inside each app. Over time, these broad roles let users read far too much data. Adding a filter rule helps limit which rows or items a user can read. How an opa filter works in your stack Open Policy Agent acts as a central rule engine for your stack. Instead of returning a simple yes o
Gatekeeper / OPA (K8s): the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
An opa filter works by turning policy rules into partial queries or request checks. Your app sends user details to Open Policy Agent and gets back conditions to apply. Teams often start with simple role checks inside each app. Over time, these broad roles let users read far too much data. Adding a filter rule helps limit which rows or items a user can read.
How an opa filter works in your stack
Open Policy Agent acts as a central rule engine for your stack. Instead of returning a simple yes or no, it can return filter conditions. Your app sends a small JSON message with user attributes and request details. The engine runs partial evaluation against the policy rules you wrote. It leaves unknown data values as variables in the output.
Your app takes that output and translates it into a native database query. For example, the app adds a clause to check the user department. Then the database runs the final query and returns only matching rows. This flow keeps policy rules outside the main app code. Teams can update the rules without deploying the whole app again.
Another way to run an opa filter is inside a service mesh. In this setup, a sidecar checks HTTP requests before they reach your service. The sidecar sends headers, paths, and token claims to the rule engine. If the rule passes, the request moves forward to the app. If the rule fails, the sidecar blocks the call right away.
Why teams build query filters with policy engines
Hardcoding access logic inside ten different microservices creates a huge mess. Every time a rule changes, ten teams must rewrite their code. A shared rule engine fixes this problem by putting rules in one place. Security teams can read the policy files and see how rules work. App developers spend less time writing custom role checks for each endpoint.
Row filtering also works better than fetching all data into memory first. If an app pulls ten thousand rows and filters them in code, it wastes memory. Translating policy rules into query conditions lets the database do the heavy work. Indexes still work well, and network traffic stays low between systems.
Gatekeeper / OPA (K8s): architecture patterns and best practices
Continue reading? Get the full guide.
Free. No spam. Unsubscribe anytime.
What an opa filter solves and what it misses
This pattern solves app-level data filtering for routine service calls. It works well when all traffic flows through your custom backend code. Every app request gets the extra query conditions added before execution. Your normal app users only get the rows that match their role.
Still, this setup requires you to write translator code for every database type. If you use three different databases, you must maintain three translators. Worse, it does nothing when engineers log in to databases or servers directly. During an outage, engineers open a client tool and run raw queries. Those direct sessions bypass your app code and its query translator completely.
Native roles decide who can log in to the database or server. They do not inspect individual commands or queries while they run in flight. An engineer with a broad role can still run a dangerous drop command. They can also query tables full of sensitive emails, phone numbers, and card numbers. App-level filters cannot rewrite those raw results during a direct admin session.
Govern statements and responses across databases and APIs
Good config and scoped roles are needed setup. They do not check single queries in flight or mask sensitive fields in returned rows. Across Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes APIs, SSH, and internal HTTP endpoints, hoop.dev runs beside each supported service as an open-source proxy, a sidecar for your database or API.
First, hoop.dev guardrails block banned queries before they run. Then hoop.dev data masking rewrites matched sensitive values in responses in memory. The audit trail records every statement and verdict per resource. Furthermore, hoop.dev holds SOC 2 Type II and is open source on GitHub.
Frequently asked questions
What is the difference between standard policy checks and an opa filter?
A standard check returns a simple allow or deny decision for one request. A filter returns conditions that your app adds to a database query. This lets one query return only the specific rows a user may read.
Does Open Policy Agent run the database query itself?
No, the policy engine never talks to your database directly. It only evaluates your rule file and returns a set of conditions. Your app must translate those conditions into a native query and run it.
Do app-level policy filters protect direct database sessions?
No, app filters only work when requests pass through your app code. When engineers connect with a database client, they bypass the app entirely. You need runtime controls on the session itself to check those commands.
Related guides
In this post