Unified Security API
Management API for security policy definitions and assignments
Overview
The Unified Security API lets you manage security policies programmatically. Create policy definitions (reusable policy templates) and assignments (bindings between policy definitions and actors) to control connection-level, schema-level, and row-level security across your project.
For a conceptual overview, see Policy Definitions & Assignments.
Base path:
All endpoints require authentication with an ADMIN role. Request and response bodies use JSON.
Policy Definitions
A policy definition is a connection-scoped policy template. It describes what security rules to apply but not who they apply to.
List Policy Definitions
GET /definitions
Returns all policy definitions in the project, sorted by name.
Response:
Create Policy Definition
POST /definitions
Creates a new policy definition for a connection.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
connectionId | string | Yes | ID of the connection this policy definition applies to |
name | string | Yes | Display name for the policy definition |
clsConfig | CLSConfig | No | Connection-level security configuration |
slsConfig | SLSConfig | No | Schema-level security configuration |
rlsConfig | RLSConfig | No | Row-level security configuration |
At least one config required
You must provide at least one of clsConfig, slsConfig, or rlsConfig. A policy definition without any config is rejected.
Response (201):
Get Policy Definition
GET /definitions/{definitionId}
Returns a single policy definition with its connection details and assignment count.
Response:
Update Policy Definition
PATCH /definitions/{definitionId}
Updates an existing policy definition. Provide only the fields you want to change. At least one field must be included.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Updated display name |
clsConfig | CLSConfig | null | No | Updated CLS config. Pass null to remove. |
slsConfig | SLSConfig | null | No | Updated SLS config. Pass null to remove. |
rlsConfig | RLSConfig | null | No | Updated RLS config. Pass null to remove. |
Response:
Delete Policy Definition
DELETE /definitions/{definitionId}
Deletes a policy definition. Fails with 409 Conflict if assignments still reference it.
Response:
Assignments
An assignment binds a policy definition to a specific actor (user, tenant, or all tenants) and provides the concrete parameter values for that actor.
List Assignments
GET /assignments
Returns all assignments in the project with resolved actor details.
Response:
Create Assignment
POST /assignments
Creates a new assignment that binds a definition to an actor.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
definitionId | string | Yes | ID of the definition to assign |
scopeType | string | Yes | One of ALL_TENANTS, TENANT, TENANT_USER, ORG_USER |
orgUserId | string | Conditional | Required when scopeType is ORG_USER |
tenantId | string | Conditional | Required when scopeType is TENANT |
tenantUserId | string | Conditional | Required when scopeType is TENANT_USER |
params | object | No | Parameter values to fill placeholders in the definition |
Scope type validation
Each scope type requires specific fields and rejects others:
| Scope Type | Required Fields | Must Not Set |
|---|---|---|
ALL_TENANTS | definitionId | orgUserId, tenantId, tenantUserId |
TENANT | definitionId, tenantId | orgUserId, tenantUserId |
TENANT_USER | definitionId, tenantUserId | orgUserId, tenantId |
ORG_USER | definitionId, orgUserId | tenantId, tenantUserId |
Response (201):
Get Assignment
GET /assignments/{assignmentId}
Returns a single assignment with its related definition, connection, and actor details.
Response:
Update Assignment
PATCH /assignments/{assignmentId}
Updates an existing assignment. Provide only the fields you want to change. At least one field must be included.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
scopeType | string | No | Updated scope type |
orgUserId | string | null | No | Updated org user ID |
tenantId | string | null | No | Updated tenant ID |
tenantUserId | string | null | No | Updated tenant user ID |
params | object | null | No | Updated parameter values |
Response:
Delete Assignment
DELETE /assignments/{assignmentId}
Response:
Preview
The preview endpoint lets you test how security policies resolve for a given actor without affecting live dashboards. Use it to verify that definitions and assignments produce the expected CLS, SLS, and RLS context before going live.
Preview Security Context
POST /preview
Resolves the full security context for an actor against a connection, including any compiled RLS conditions.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
connectionId | string | Yes | Connection to resolve against |
actor | Actor | Yes | The actor to preview |
assignmentId | string | No | Preview using a specific persisted assignment |
draftAssignment | object | No | Preview an unsaved assignment (same shape as create assignment body) |
ignorePersistedAssignments | boolean | No | If true, only use tokenPolicyInput (skip stored assignments) |
runtimeParams | object | No | Additional runtime parameter values |
tokenPolicyInput | object | No | Inline CLS/SLS/RLS to merge (simulates token-level policy) |
sql | string | No | SQL statement for RLS compilation |
referencedEntities | array | No | Table references for RLS matcher resolution |
Actor object
The actor field uses a discriminated union on kind:
Example request:
Response:
The compiled field shows how RLS rules translate to SQL conditions for the given sql or referencedEntities. If no SQL is provided, compiled.status is "not_requested".
Type Reference
CLSConfig
Connection-level security. Controls which database connection or file path the actor uses.
| Field | Type | Required | Description |
|---|---|---|---|
connectionTemplate | string | null | No | Connection string template with {{ }} placeholders |
filePathTemplates | Record<string, string> | No | File path templates keyed by source name |
params | Record<string, string | number | boolean> | No | Static parameter values for CLS resolution |
Mutual exclusion
Use either connectionTemplate or filePathTemplates, not both. At least one of connectionTemplate, filePathTemplates, or params must be present.
SLSConfig
Schema-level security. Controls which database schema the actor queries.
| Field | Type | Required | Description |
|---|---|---|---|
schema | string | null | No | Fixed schema name |
schemaTemplate | string | null | No | Schema name with {{ }} placeholders |
allowedSchemas | string[] | No | Allowlist of permitted schemas |
defaultSchema | string | null | No | Fallback schema. Must exist in allowedSchemas if set. |
Use either schema or schemaTemplate, not both. At least one field must be present.
RLSConfig
Row-level security. Contains one or more filter rules that inject WHERE conditions at query time.
| Field | Type | Required | Description |
|---|---|---|---|
rules | RLSRule[] | Yes | At least one rule is required |
RLSRule
A single row-level filter rule.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Human-readable name for the rule |
description | string | null | No | Optional description |
matcher | RLSMatcher | Yes | Determines which tables this rule applies to |
expression | string | Yes | SQL expression injected as a WHERE condition. Supports {{ }} placeholders. |
params | Record<string, ParamValue> | No | Static param values for this rule |
enabled | boolean | No | Defaults to true. Set false to disable without removing. |
RLSMatcher
Determines which tables an RLS rule applies to. Three variants:
ALL_TABLES_WITH_COLUMN -- applies to every table that contains the named column.
TABLE_LIST -- applies to an explicit set of tables.
Each table entry requires a table name. The schema and database fields are optional qualifiers.
SCHEMA -- applies to all tables in a schema, optionally filtered by column.
Parameter Values
Parameters (params in assignments, rules, and configs) accept the following value types:
| Type | Example |
|---|---|
| string | "acme_corp" |
| number | 42 |
| boolean | true |
| string[] | ["us-east", "us-west"] |
| number[] | [1, 2, 3] |
Error Handling
All error responses follow this format:
Common Error Codes
| Code | HTTP Status | Description |
|---|---|---|
AUTH_FAILED | 401 | Missing or invalid authentication |
PROJECT_ACCESS_DENIED | 403 | User lacks ADMIN role |
PROJECT_NOT_FOUND | 404 | Project does not exist |
NOT_FOUND | 404 | Definition or assignment not found |
INVALID_REQUEST | 400 | Validation failed (see details for field-level errors) |
CONFLICT | 409 | Cannot delete a definition with existing assignments |
INTERNAL_ERROR | 500 | Unexpected server error |
Validation Errors
When validation fails, the response includes a details object with field-level errors: