diff --git a/docs/docs/rest-api.md b/docs/docs/rest-api.md index fd4ccd1da0..629d2d505a 100644 --- a/docs/docs/rest-api.md +++ b/docs/docs/rest-api.md @@ -9,7 +9,7 @@ groups: - [Policy API](#policy-api) - manage policy loaded into the OPA instance. - [Data API](#data-api) - evaluate rules and retrieve data. - [Query API](#query-api) - execute adhoc queries. -- [Compile API](#compile-api) - access Rego's [Partial Evaluation](https://blog.openpolicyagent.org/partial-evaluation-162750eaf422) functionality. +- [Compile API](#compile-api) - access Rego's [Partial Evaluation](https://blog.openpolicyagent.org/partial-evaluation-162750eaf422) and data filtering functionality. - [Health API](#health-api) - access instance operational health information. - [Config API](#config-api) - view instance configuration. - [Status API](#status-api) - view instance [status](./management-status) state. @@ -1608,6 +1608,124 @@ The following table summarizes the behavior for partial evaluation results. > The partially evaluated queries are represented as strings in the table above. The actual API response contains the JSON AST representation. + +### Compling a Rego policy (and query) into data filters + +```http +POST /v1/compile/{path:.+} +Content-Type: application/json +``` + +Where the `{path}` is the slash delimited filter rule to be compiled. +E.g., to compile the `data.filters.include` rule, query `/v1/compile/filters/include` + + +#### Request Headers + +| Name | Required | Accepted Values | Description | +| --- | --- | --- | --- | +| Content-Type | No | `application/json` | Indicates the request body is either a JSON encoded document. | +| Content-Encoding | No | gzip | Indicates the request body is a compressed gzip object. | +| Accept | Yes | See [below](#accept-header--controlling-the-target-response-format) | See [below](#accept-header--controlling-the-target-response-format) | + + +#### Accept Header – Controlling the Target Response Format + +The same request can generate filters that are representable in many different ways, such as raw SQL `WHERE` clauses or Universal Conditions AST (UCAST). + +OPA uses the `Accept` header to denote the target response format. + +| Value | Response Schema | Description | +| --- | --- | -- | +| Multitarget: `application/vnd.opa.multitarget+json` | `result.{ucast,sqlserver,mysql,postgresql,sqlite}` | The partially evaluated result of the query in each target dialect. Use the `options.targetDialects` field in the request body to control targets. | +| UCAST: `application/vnd.opa.ucast.all+json`, `application/vnd.opa.ucast.minimal+json`, `application/vnd.opa.ucast.linq+json`, `application/vnd.opa.ucast.prisma+json` | `result.query`| UCAST JSON object describing the conditions under which the query is true. | +| SQL: `application/vnd.opa.sql.sqlserver+json`, `application/vnd.opa.sql.mysql+json`, `application/vnd.opa.sql.postgresql+json`, `application/vnd.opa.sql.sqlite+json` | `result.query`| String representing the SQL equivalent of the conditions under which the query is true. | + + +#### Request Body + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `input` | `any` | No | The input document to use during partial evaluation and during mask rule evaluation (default: undefined). | +| `options` | `object[string, any]` | No | Additional options to use during partial evaluation | +| `options.disableInlining` | `array[string]` | No. Default: undefined | A list of rule references. | +| `options.maskRule` | `string` | No | The rule to evaluate for generating column masks. Overrides any `mask_rule` annotations defined in the policy. | +| `options.targetDialects` | `array[string]`, one of `ucast+all`, `ucast+minimal`, `ucast+prisma`, `ucast+linq`, `sql+sqlserver`, `sql+mysql`, `sql+postgresql` | Yes, if using `multitarget`. **Ignored for all other targets** | The output targets for partial evaluation. Different targets will have different constraints. Use [`Accept` header](#accept-header--controlling-the-target-response-format) to request a single compilation target. | +| `options.targetSQLTableMappings` | `object[string, object[string, string]]` | No | A mapping between tables and columns. See the [example](#using-table-and-column-remappings) for the schema. | +| `unknowns` | `array[string]` | No | The terms to treat as unknown during partial evaluation (default: `["input"]`]). | + + +#### Example Request + +With OPA running with this policy, we'll compile the query `data.filters.include` into SQL filters: + +```rego +package filters + +# METADATA +# scope: document +# custom: +# unknowns: [input.fruits] +include if input.fruits.name == input.favorite + +include if { + input.fruits.name == "apple" + not input.favorite +} +``` + +```http +POST /v1/compile/filters/include HTTP/1.1 +Content-Type: application/json +Accept: application/vnd.opa.sql.postgresql+json +``` + +```json +{ + "input": { + "favorite": "pineapple" + } +} +``` + + +#### Example Response + +```http +HTTP/1.1 200 OK +Content-Type: application/vnd.opa.sql.postgresql+json +``` + +```json +{ + "result": { + "query": "WHERE fruits.name = E'pineapple'" + } +} +``` + + +#### Unconditional Results from Filters Generation + +An absent `query` in the `result` indicates **unconditional deny**: + +```json +{ + "result": {} +} +``` + +An empty string `query` indicates **unconditional include**: + +```json +{ + "result": { + "query": "" + } +} +``` + + ## Health API The `/health` API endpoint executes a simple built-in policy query to verify