Skip to content

API Reference

Overview

Manage Identifiers and Omni Policies programmatically through the Metadata Service (MDS) REST APIs.

Availability

The Policy Authoring API is evolving and is not yet a finalized public contract. For endpoint details and integration guidance, contact your Privacera representative.


Identifier APIs

An Identifier is a reusable, named selection of users, columns, or rows. Create identifiers first, then reference the returned id when authoring policies.

Base path: /api/v1/metadata/identifiers

Operation Method Path
Create POST /api/v1/metadata/identifiers
List / search GET /api/v1/metadata/identifiers
Get by ID GET /api/v1/metadata/identifiers/{id}
Update PUT /api/v1/metadata/identifiers/{id}
Delete DELETE /api/v1/metadata/identifiers/{id}

Common request body fields

Used by Create and Update.

Field Required Description
name Yes Unique identifier name
type Yes USER_IDENTIFIER, COLUMN_IDENTIFIER, or RECORD_IDENTIFIER
description No Human-readable description
status No Status (for example, ACTIVE). Defaults to ACTIVE when omitted
identifiers Yes Non-empty array of definition blocks

Each item in identifiers:

Field Required Description
description No Description of this definition block
controllers Yes One or more controller rules

Each controller:

Field Required Description
type_service Yes Name of the service this rule applies to. Use ALL for User and Column identifiers; for Record identifiers, the Ranger service name from Data Catalog (for example, privacera_snowflake, privacera_bigquery, privacera_databricks_unity_catalog)
query Yes Filter expression (same syntax as the UI)

type_service rules

type_service is the service name for the controller rule.

  • USER_IDENTIFIER and COLUMN_IDENTIFIER must use type_service: "ALL" only.
  • RECORD_IDENTIFIER uses one controller per service. Set type_service to the Ranger service name shown in Data Governance > Data Browser > Data Catalog for your connector (for example, privacera_snowflake, privacera_bigquery, privacera_databricks_unity_catalog).
  • The API does not strictly validate type_service against a fixed list. If a rule does not apply as expected, open Data Browser and confirm the exact service name for your deployment.
  • Do not mix ALL with specific service types in the same identifier.
  • Blank type_service is normalized to ALL.

Request vs response field name

The request body uses identifiers (plural). The response body uses identifier (singular).

Creating an Identifier via API

Create a reusable Identifier (User, Column, or Record) that policies can reference.

API Endpoint:

HTTP
POST <MDS-URL>/api/v1/metadata/identifiers

Request Body: See common request body fields above.

Example Request (USER_IDENTIFIER):

JSON
{
  "name": "Employees",
  "description": "All employees",
  "type": "USER_IDENTIFIER",
  "identifiers": [
    {
      "description": "Employee user type",
      "controllers": [
        {
          "type_service": "ALL",
          "query": "USER.userType == 'EMPLOYEE'"
        }
      ]
    }
  ]
}

Example Request (RECORD_IDENTIFIER):

JSON
{
  "name": "Allowed Properties by Region Access",
  "description": "Properties matching the requesting user's region",
  "type": "RECORD_IDENTIFIER",
  "identifiers": [
    {
      "description": "Snowflake region filter",
      "controllers": [
        {
          "type_service": "privacera_snowflake",
          "query": "obj.region_name = '${{USER.region}}'"
        }
      ]
    }
  ]
}

Example Request (COLUMN_IDENTIFIER):

JSON
{
  "name": "Sensitive financial columns",
  "description": "Columns tagged SENSITIVE_FINANCIAL",
  "type": "COLUMN_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "ALL",
          "query": "HAS_TAG('SENSITIVE_FINANCIAL')"
        }
      ]
    }
  ]
}

HTTP Status Codes:

  • 201 Created: Identifier created successfully
  • 400 Bad Request: Validation error (missing name, invalid type, blank query, invalid type_service)

Response Fields:

  • id: Identifier vertex ID — save this for policy authoring
  • name: Identifier name
  • type: USER_IDENTIFIER, COLUMN_IDENTIFIER, or RECORD_IDENTIFIER
  • description: Description
  • status: Status (for example, ACTIVE)
  • identifier: Array of definition blocks
    • description: Description of the block
    • controllers: Array of rules
      • type_service: Service scope (ALL or a service name)
      • query: Filter expression
  • createdTime / updatedTime: Creation and last-update time as Unix epoch milliseconds
  • createdBy / updatedBy: Audit fields

On failed requests, the response may also include errorCode and message.

Example Response:

JSON
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Employees",
  "type": "USER_IDENTIFIER",
  "description": "All employees",
  "status": "ACTIVE",
  "identifier": [
    {
      "description": "Employee user type",
      "controllers": [
        {
          "type_service": "ALL",
          "query": "USER.userType == 'EMPLOYEE'"
        }
      ]
    }
  ],
  "createdTime": 1780294519989,
  "updatedTime": 1780294519989,
  "createdBy": "admin@example.com",
  "updatedBy": "admin@example.com"
}

Listing Identifiers via API

List and search identifiers. Use optional filters to narrow results by type or name, and use pagination parameters to retrieve additional pages.

API Endpoint:

HTTP
GET <MDS-URL>/api/v1/metadata/identifiers

Query Parameters:

  • types (optional): Filter by identifier type (USER_IDENTIFIER, COLUMN_IDENTIFIER, RECORD_IDENTIFIER). Repeat the parameter to include multiple types (OR logic). Example: types=USER_IDENTIFIER&types=RECORD_IDENTIFIER
  • search (optional): Case-insensitive name search
  • sortBy (optional): Sort field — name, type, createdat, updatedat (default: name)
  • sortOrder (optional): Sort direction — asc or desc (default: asc)
  • page (optional): Page number for pagination (zero-based, default: 0)
  • size (optional): Number of identifiers per page (default: 25, maximum: 1000)

Example Request:

HTTP
GET <MDS-URL>/api/v1/metadata/identifiers?types=USER_IDENTIFIER&search=Employee&sortBy=name&sortOrder=asc&page=0&size=25

Response Fields:

  • eventTime: Timestamp of the operation (epoch milliseconds)
  • status: Status of the operation (for example, SUCCESS)
  • totalCount: Total number of matching identifiers across all pages
  • number: Current page number (zero-based)
  • pageSize: Number of items returned on this page
  • totalPages: Total number of pages
  • hasNext: true when another page is available; increment page to fetch it
  • hasPrevious: true when a previous page is available
  • content: Array of identifier objects (same fields as the create response)
    • id: Identifier vertex ID
    • name: Identifier name
    • type: Identifier type
    • description: Description
    • status: Status
    • identifier: Array of definition blocks with controllers
    • createdTime / updatedTime: Creation and last-update time as Unix epoch milliseconds
    • createdBy / updatedBy: Audit fields
  • filters: Echo of filters applied for this request (for example, types, search)
  • sortBy: Field used for sorting
  • sortOrder: Sort direction

On failed requests, the response may also include errorCode and message.

Example Response:

JSON
{
  "eventTime": 1780294519989,
  "status": "SUCCESS",
  "totalCount": 1,
  "number": 0,
  "pageSize": 25,
  "totalPages": 1,
  "hasNext": false,
  "hasPrevious": false,
  "content": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Employees",
      "type": "USER_IDENTIFIER",
      "description": "All employees",
      "status": "ACTIVE",
      "identifier": [
        {
          "controllers": [
            {
              "type_service": "ALL",
              "query": "USER.userType == 'EMPLOYEE'"
            }
          ]
        }
      ],
      "createdTime": 1780294519989,
      "updatedTime": 1780294519989
    }
  ],
  "filters": {
    "types": ["USER_IDENTIFIER"],
    "search": "Employee"
  },
  "sortBy": "name",
  "sortOrder": "asc"
}

Pagination:

When hasNext is true, more results are available. Request the next page by incrementing the page query parameter while keeping the same size and filters.

Retrieving an Identifier by ID via API

Retrieve a single identifier by its vertex ID.

API Endpoint:

HTTP
GET <MDS-URL>/api/v1/metadata/identifiers/{id}

Path Parameters:

  • id (required): Identifier vertex ID

Example Request:

HTTP
GET <MDS-URL>/api/v1/metadata/identifiers/a1b2c3d4-e5f6-7890-abcd-ef1234567890

HTTP Status Codes:

  • 200 OK: Identifier found
  • 400 Bad Request: Identifier ID is blank
  • 404 Not Found: No identifier with the given ID

Response Fields: Same as the create response.

Updating an Identifier via API

Update an existing identifier. If the number of affected policy resources exceeds the async threshold, the entity update and Ranger re-sync are queued as a background job.

API Endpoint:

HTTP
PUT <MDS-URL>/api/v1/metadata/identifiers/{id}

Path Parameters:

  • id (required): Identifier vertex ID

Request Body: Same structure as create. All required fields (name, type, identifiers) must be provided.

Example Request:

HTTP
PUT <MDS-URL>/api/v1/metadata/identifiers/a1b2c3d4-e5f6-7890-abcd-ef1234567890
Content-Type: application/json
JSON
{
  "name": "Employees",
  "description": "All employees",
  "type": "USER_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "ALL",
          "query": "USER.userType == 'EMPLOYEE'"
        }
      ]
    }
  ]
}

HTTP Status Codes:

  • 200 OK: Update and Ranger re-sync completed inline
  • 202 Accepted: Update queued as a background job
  • 400 Bad Request: Validation error
  • 404 Not Found: Identifier not found

Response Fields (inline update — 200): Same as the create response.

Response Fields (async update — 202):

  • job_id: Background job ID — poll the job endpoint for completion status
  • data: Snapshot of the identifier at the time the job was queued

Example Response (202 Accepted):

JSON
{
  "job_id": 42,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Employees",
    "type": "USER_IDENTIFIER",
    "status": "ACTIVE",
    "identifier": [
      {
        "controllers": [
          {
            "type_service": "ALL",
            "query": "USER.userType == 'EMPLOYEE'"
          }
        ]
      }
    ]
  }
}

Impact of updates

Editing an identifier affects every policy that references it.

Deleting an Identifier via API

Delete an identifier. Deletion is rejected if the identifier is still referenced by one or more Omni Policies.

API Endpoint:

HTTP
DELETE <MDS-URL>/api/v1/metadata/identifiers/{id}

Path Parameters:

  • id (required): Identifier vertex ID

Example Request:

HTTP
DELETE <MDS-URL>/api/v1/metadata/identifiers/a1b2c3d4-e5f6-7890-abcd-ef1234567890

HTTP Status Codes:

  • 204 No Content: Identifier deleted successfully (no response body)
  • 202 Accepted: Delete queued as a background job — response body is { "job_id": <number>, "data": null }; poll the job endpoint for completion
  • 400 Bad Request: Identifier ID is blank
  • 404 Not Found: Identifier not found
  • 409 Conflict: Identifier is still referenced by one or more policies — remove it from all policies first

Identifier examples

The examples below use the Acme scenarios. Create these identifiers first, then use the returned id values when authoring policies.

USER_IDENTIFIER

Employees

Used by the Employee portfolio access policy. Selects all employees.

UI query: USER.userType == 'EMPLOYEE'

API Endpoint:

HTTP
POST <MDS-URL>/api/v1/metadata/identifiers

Example Request:

JSON
{
  "name": "Employees",
  "description": "All employees",
  "type": "USER_IDENTIFIER",
  "identifiers": [
    {
      "description": "Employee user type",
      "controllers": [
        {
          "type_service": "ALL",
          "query": "USER.userType == 'EMPLOYEE'"
        }
      ]
    }
  ]
}

Regional Managers

Used by the Allowed properties to view row-filter policy.

UI query: IS_IN_ROLE('manager')

JSON
{
  "name": "Regional Managers",
  "description": "Users with the manager role",
  "type": "USER_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "ALL",
          "query": "IS_IN_ROLE('manager')"
        }
      ]
    }
  ]
}

Identify Offshore users

Used by the Texas row-filter policies for offshore users.

UI query: USER.location == 'offshore'

JSON
{
  "name": "Identify Offshore users",
  "description": "Users located offshore",
  "type": "USER_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "ALL",
          "query": "USER.location == 'offshore'"
        }
      ]
    }
  ]
}

COLUMN_IDENTIFIER

Sensitive financial columns

Used by the Redact sensitive data masking policy on REAL_ESTATE_TENANTS.

UI query: HAS_TAG('SENSITIVE_FINANCIAL')

API Endpoint:

HTTP
POST <MDS-URL>/api/v1/metadata/identifiers

Example Request:

JSON
{
  "name": "Sensitive financial columns",
  "description": "Columns tagged SENSITIVE_FINANCIAL",
  "type": "COLUMN_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "ALL",
          "query": "HAS_TAG('SENSITIVE_FINANCIAL')"
        }
      ]
    }
  ]
}

RECORD_IDENTIFIER

Allowed Properties by Region Access

Used by the Allowed properties to view row-filter policy. Regional managers see only properties in their region.

UI query: obj.region_name = '${{USER.region}}'

API Endpoint:

HTTP
POST <MDS-URL>/api/v1/metadata/identifiers

Example Request:

JSON
{
  "name": "Allowed Properties by Region Access",
  "description": "Properties matching the requesting user's region",
  "type": "RECORD_IDENTIFIER",
  "identifiers": [
    {
      "description": "Snowflake region filter",
      "controllers": [
        {
          "type_service": "privacera_snowflake",
          "query": "obj.region_name = '${{USER.region}}'"
        }
      ]
    }
  ]
}

Identify Texas data

Used by Restrict Texas data from offshore users. Resolves the STATE column by tag at query time.

UI query: obj.${{TAG_GET_CHILD_RES('STATE')}} = 'TX'

JSON
{
  "name": "Identify Texas data",
  "description": "Rows in Texas",
  "type": "RECORD_IDENTIFIER",
  "identifiers": [
    {
      "description": "Snowflake Texas filter",
      "controllers": [
        {
          "type_service": "privacera_snowflake",
          "query": "obj.${{TAG_GET_CHILD_RES('STATE')}} = 'TX'"
        }
      ]
    }
  ]
}

Used by Texas data for offshore users with consent.

UI query: obj.consent_given = 'true'

JSON
{
  "name": "Identify Data with consent",
  "description": "Rows where consent has been given",
  "type": "RECORD_IDENTIFIER",
  "identifiers": [
    {
      "controllers": [
        {
          "type_service": "privacera_snowflake",
          "query": "obj.consent_given = 'true'"
        }
      ]
    }
  ]
}

Omni Policy APIs (CRUD)

An Omni Policy controls who is governed, which data it applies to, and what action is taken. Create identifiers first, then reference their id values in the policy identifiers map and in whoQuery, dataQuery, and dataFiltersQuery. See Policies for the authoring model these operations manage.

Base path: /api/v1/metadata/omni-policies

Operation Method Path Success
Create POST /api/v1/metadata/omni-policies 201 or 202
Read (list) GET /api/v1/metadata/omni-policies 200
Read (one) GET /api/v1/metadata/omni-policies/{id} 200
Update PUT /api/v1/metadata/omni-policies/{id} 200 or 202
Patch metadata PATCH /api/v1/metadata/omni-policies/{id} 200
Activate PATCH /api/v1/metadata/omni-policies/{id}/activate 200 or 202
Deactivate PATCH /api/v1/metadata/omni-policies/{id}/deactivate 200 or 202
Delete DELETE /api/v1/metadata/omni-policies/{id} 200 or 202

Common request body fields

Used by Create and Update (OmniPolicyRequest).

Field Required Description
name Yes Unique policy name (max 255 characters)
type Yes ACCESS, MASKING, or RLF
description No Human-readable description
status No DRAFT, ACTIVE, or INACTIVE
actions Yes when ACTIVE Array of action definitions (for example, { "action": "DENY" } or { "action": "MASK", "masking": { "type": "MASK_HASH" } })
identifiers No Map of identifier vertex IDs by role (see below)
whoQuery No Identifier vertex ID (or expression of IDs) for the subject filter; must match a user_identifier in identifiers. Do not put the filter expression here — that lives on the Identifier.
dataQuery No Identifier vertex ID (or expression of IDs) for the column filter; must match a column_identifier in identifiers. Do not put the filter expression here — that lives on the Identifier.
dataFiltersQuery Yes when ACTIVE + RLF Identifier vertex ID (or expression of IDs) for the row filter; must match a record_identifier in identifiers. Do not put the filter expression here — that lives on the Identifier.
applyPolicy No Assets and principals the policy applies to
summary No Human-readable summary (does not trigger Ranger sync)

identifiers map keys:

Key Purpose
user_identifier User/principal matching — use the same ID in whoQuery
record_identifier Row-level filtering — use the same ID in dataFiltersQuery
column_identifier Column-level filtering — use the same ID in dataQuery

Each key holds an array of identifier vertex IDs from Create identifier responses. Put those same IDs in whoQuery, dataQuery, and dataFiltersQuery. At Ranger sync time, MDS replaces each ID with the Identifier's stored query. To combine multiple identifiers, join their IDs with AND or OR (for example, "<id1> AND <id2>").

applyPolicy object:

Field Description
assets Where the policy applies — array of { "type", "id" }
principals Who the policy governs — array of { "type", "name" }

Asset type values:

type id meaning
TAG Tag name (for example, CUSTOMER_DATA) — used as the vertex ID
DATA_PRODUCT Data-product vertex ID
RESOURCE Full resource path (for example, privacera_snowflake/db/schema/table). Other resource labels such as TABLE, SCHEMA, or DATABASE are also accepted

Principal type values: USER, GROUP, ROLE. Use GROUP with name public for everyone.

ACTIVE policy validation

When status is ACTIVE: - At least one action is required. - At least one principal in applyPolicy.principals or a user_identifier in identifiers is required. - RLF policies require dataFiltersQuery. - whoQuery requires user_identifier; dataQuery requires column_identifier.

Creating an Omni Policy via API

API Endpoint:

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies

Request Body: See common request body fields above.

Example Request:

JSON
{
  "name": "Restrict Texas data from offshore users",
  "type": "RLF",
  "status": "ACTIVE",
  "actions": [{ "action": "DENY" }],
  "identifiers": {
    "user_identifier": ["<offshore-users-id>"],
    "record_identifier": ["<texas-data-id>"]
  },
  "whoQuery": "<offshore-users-id>",
  "dataFiltersQuery": "<texas-data-id>",
  "applyPolicy": {
    "assets": [{ "type": "TAG", "id": "CUSTOMER_DATA" }]
  }
}

Replace <offshore-users-id> and <texas-data-id> (in both identifiers and the matching query fields) with the id values from Create identifier. This RLF example shows whoQuery and dataFiltersQuery. For dataQuery (column identifiers), see the MASKING example under Omni Policy examples. For ACCESS examples, see the same section.

HTTP Status Codes:

  • 201 Created: Policy created synchronously — response body is the full policy object
  • 202 Accepted: Policy creation queued as async job — response body is { "job_id": <number>, "data": null }; poll the job endpoint for completion
  • 400 Bad Request: Validation error

Response Fields:

  • id: Policy vertex ID
  • name: Policy name
  • type: ACCESS, MASKING, or RLF
  • description: Description
  • policyStatus: DRAFT, ACTIVE, or INACTIVE
  • actions: Array of action definitions
  • identifiers: Linked identifier objects (on single-fetch responses)
  • whoQuery / dataQuery / dataFiltersQuery: Identifier vertex IDs stored on the policy (MDS resolves them to Identifier queries during Ranger sync)
  • applyPolicy: Attached assets and principals
  • createdAt / updatedAt: Creation and last-update time as Unix epoch milliseconds (numeric; not an ISO datetime string)
  • createdBy / updatedBy: Audit fields
  • summary: Human-readable summary

Example Response:

JSON
{
  "id": "policy-001",
  "eventTime": 1780294519989,
  "status": "SUCCESS",
  "name": "Restrict Texas data from offshore users",
  "type": "RLF",
  "policyStatus": "ACTIVE",
  "actions": [{ "action": "DENY" }],
  "identifiers": [
    {
      "id": "<offshore-users-id>",
      "name": "Identify Offshore users",
      "type": "USER_IDENTIFIER"
    },
    {
      "id": "<texas-data-id>",
      "name": "Identify Texas data",
      "type": "RECORD_IDENTIFIER"
    }
  ],
  "whoQuery": "<offshore-users-id>",
  "dataFiltersQuery": "<texas-data-id>",
  "applyPolicy": {
    "assets": [{ "type": "TAG", "id": "CUSTOMER_DATA" }],
    "principals": []
  },
  "createdAt": 1780294519989,
  "updatedAt": 1780294519989
}

Listing Omni Policies via API

API Endpoint:

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies

Query Parameters:

  • search (optional): Search by policy name pattern
  • type (optional): Filter by type — ACCESS, MASKING, or RLF
  • status (optional): Filter by status — DRAFT, ACTIVE, or INACTIVE
  • sortBy (optional): name, type, createdat, updatedat (default: name)
  • sortOrder (optional): asc or desc (default: asc)
  • page (optional): Page number (zero-based, default: 0)
  • size (optional): Page size (default: 25, maximum: 1000)

Example Request:

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies?type=RLF&status=ACTIVE&page=0&size=25

Response Fields:

  • eventTime, status, totalCount, number, pageSize, totalPages, hasNext, hasPrevious
  • content: Array of policy summary objects (name, type, policyStatus, createdAt, updatedAt)
  • filters, sortBy, sortOrder

Retrieving an Omni Policy by ID via API

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/{id}

HTTP Status Codes: 200 OK, 400 Bad Request, 404 Not Found

Response Fields: Full policy object including identifiers and applyPolicy.

Updating an Omni Policy via API

HTTP
PUT <MDS-URL>/api/v1/metadata/omni-policies/{id}

Request Body: Same structure as create.

HTTP Status Codes: 200 OK, 202 Accepted, 400 Bad Request, 404 Not Found

Response Fields (202): job_id, data (policy snapshot at queue time)

Patching Omni Policy metadata via API

Update only name, description, or summary. Does not trigger a Ranger sync.

HTTP
PATCH <MDS-URL>/api/v1/metadata/omni-policies/{id}
JSON
1
2
3
4
{
  "name": "Updated policy name",
  "description": "Updated description"
}

At least one of name, description, or summary must be provided.

HTTP Status Codes: 200 OK, 400 Bad Request, 404 Not Found

Activating and deactivating an Omni Policy via API

Activate (DRAFTACTIVE):

HTTP
PATCH <MDS-URL>/api/v1/metadata/omni-policies/{id}/activate

Deactivate (ACTIVEINACTIVE):

HTTP
PATCH <MDS-URL>/api/v1/metadata/omni-policies/{id}/deactivate

No request body. The policy must pass ACTIVE validation rules before activation succeeds.

HTTP Status Codes: 200 OK, 202 Accepted, 400 Bad Request, 404 Not Found

Deleting an Omni Policy via API

HTTP
DELETE <MDS-URL>/api/v1/metadata/omni-policies/{id}

HTTP Status Codes: 200 OK, 202 Accepted, 400 Bad Request, 404 Not Found


Omni Policy query APIs

Read-only endpoints for inspecting the assets and coverage of a policy.

Operation Method Path Success
Get assets for a policy GET /api/v1/metadata/omni-policies/{id}/assets 200
Get resource count for a policy GET /api/v1/metadata/omni-policies/{id}/summary 200
List policies by asset GET /api/v1/metadata/omni-policies/by-asset/{assetId} 200
Policy summary by identifier GET /api/v1/metadata/omni-policies/by-identifier/{identifierId}/summary 200

Get assets for a policy

Returns every asset attached to a policy via HAS_POLICY_ASSET edges, grouped by type.

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/{id}/assets

Path Parameters:

  • id (required): Omni policy vertex ID

Response Fields:

  • policyId: Policy vertex ID
  • tags: Array of tag assets (name, vertex ID)
  • resources: Array of resource assets (vertex ID, resource path, type, service name)
  • dataProducts: Array of data-product assets (name, status, description, default tags)

All three lists are always present (empty when no assets of that type are attached).

HTTP Status Codes: 200 OK, 400 Bad Request, 404 Not Found

Get resource count for a policy

Returns the policy identity and the number of assets it governs.

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/{id}/summary

Response Fields: policyId, policyName, policyType, policyStatus, resourceCount, userCount

List policies by asset

Returns policies linked to a given asset (via HAS_POLICY_ASSET). Use this endpoint to list every Omni policy that applies to a data product, tag, or resource.

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/by-asset/{assetId}

Path Parameters:

  • assetId (required): Asset identifier — use the same id value as in applyPolicy.assets. Unlike the enforcement APIs, this endpoint has no {type} segment; pass the asset identifier directly.
Asset type {assetId} value Example
DATA_PRODUCT Data-product vertex ID dp-real-estate-portfolio
TAG Tag name (used as the vertex ID) CUSTOMER_DATA
RESOURCE Full resource path privacera_snowflake/PS_SF_DB/OMNI_SCHEMA/OMNI_TABLE_1

Query Parameters:

  • name (optional): Case-insensitive policy-name prefix filter
  • type (optional): ACCESS, MASKING, or RLF
  • sortBy (optional): name (default), type, createdAt, updatedAt, status
  • sortOrder (optional): asc or desc
  • page (optional): Zero-based page number (default: 0)
  • size (optional): Page size (default: 25)

Example Requests:

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/by-asset/CUSTOMER_DATA?type=RLF&page=0&size=25
HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/by-asset/dp-real-estate-portfolio
HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/by-asset/privacera_snowflake/PS_SF_DB/OMNI_SCHEMA/OMNI_TABLE_1

URL encoding

When {assetId} contains slashes (resource paths), URL-encode the path segments in the request.

Response Fields:

  • eventTime, status, totalCount, number, pageSize, totalPages, hasNext, hasPrevious
  • content: Array of policy objects (same fields as the create response)
  • filters, sortBy, sortOrder

HTTP Status Codes: 200 OK, 400 Bad Request, 404 Not Found

Policy summary by identifier

Returns every policy referencing the identifier, each with its resource count, plus grand totals.

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/by-identifier/{identifierId}/summary

Response Fields:

  • identifierId: Identifier vertex ID
  • policyCount: Number of policies referencing this identifier
  • totalResources / totalActiveResources: Distinct asset totals (all / ACTIVE only)
  • resourceCountByType / activeResourceCountByType: Per-type counts (for example, { "MASKING": 15, "RLF": 10 })
  • policies: Array of { policyId, policyName, policyType, policyStatus, resourceCount, userCount }

HTTP Status Codes: 200 OK, 400 Bad Request


Omni Policy enforcement APIs

Base path: /api/v1/metadata/omni-policies/enforcement

Grant or revoke Ranger policies on an asset, or manage direct access grants. The {type} path segment must be one of: tags, resources, data-products.

Operation Method Path Success
Grant policies POST /enforcement/grant/{type}/{assetId} 200
Revoke policies POST /enforcement/revoke/{type}/{assetId} 200
Grant access POST /enforcement/grant-access/{type}/{assetId} 200
Revoke access POST /enforcement/revoke-access/{type}/{assetId} 200
List grant-access GET /enforcement/grant-access/{type}/{assetId} 200

Grant / revoke policies

Push (grant) or remove (revoke) the Ranger policies defined by the supplied policy IDs on the asset.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies/enforcement/grant/{type}/{assetId}
POST <MDS-URL>/api/v1/metadata/omni-policies/enforcement/revoke/{type}/{assetId}

Request Body:

JSON
1
2
3
{
  "omniPolicyIds": ["<policy-id-1>", "<policy-id-2>"]
}

At least one policy ID is required.

Grant / revoke access

Create or delete GRANTS_PERMISSION_TO edges (asset → principals), then re-sync the Ranger ACCESS policy for the asset.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies/enforcement/grant-access/{type}/{assetId}
POST <MDS-URL>/api/v1/metadata/omni-policies/enforcement/revoke-access/{type}/{assetId}

Grant access — request body:

JSON
1
2
3
4
5
6
7
8
{
  "permission": "READ",
  "principals": {
    "users": ["david"],
    "groups": [],
    "roles": []
  }
}

permission must be READ or WRITE. At least one of users, groups, or roles must be non-empty.

Revoke access — request body:

JSON
1
2
3
4
5
6
7
{
  "principals": {
    "users": ["david"],
    "groups": [],
    "roles": []
  }
}

Omit permission on revoke. At least one of users, groups, or roles must be non-empty.

HTTP Status Codes: 200 OK, 400 Bad Request, 404 Not Found

List grant-access

Returns a paginated list of principals granted access on the asset, each with its permission.

HTTP
GET <MDS-URL>/api/v1/metadata/omni-policies/enforcement/grant-access/{type}/{assetId}

Query Parameters: principalType (USER, GROUP, ROLE), search, sortBy (name, type, permission), sortOrder, page, size (max 200).


Masking function support API

Returns each masking function with the service types that support it (and those that do not), plus services with no masking support at all. Use it to check compatibility before choosing a masking action.

HTTP
GET <MDS-URL>/api/v1/metadata/masking-functions/service-support

Response Fields:

  • masking_functions: Map of masking function → { "supported": [services], "not_supported": [services] }
  • services_without_masking_support: Services that support no masking functions

HTTP Status Codes: 200 OK


Omni Policy examples

The examples below use the Acme scenarios. Replace placeholder IDs with values from your environment and from the identifier examples above.

Policy name API type Action Identifiers used
Employee portfolio access ACCESS READ user_identifier
Allowed properties to view RLF ALLOW record_identifier (+ principals)
Restrict Texas data from offshore users RLF DENY user_identifier, record_identifier
Texas data for offshore users with consent RLF ALLOW user_identifier, record_identifier
Redact sensitive data MASKING MASK (MASK_NULL) column_identifier

ACCESS — Employee portfolio access

Goal: Let all employees read the REAL_ESTATE_PORTFOLIO data product, so a new hire is covered automatically. whoQuery is the Employees user identifier ID; applyPolicy.assets scopes the policy to the data product.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies
JSON
{
  "name": "Employee portfolio access",
  "description": "Employees can read the property portfolio",
  "type": "ACCESS",
  "status": "ACTIVE",
  "actions": [{ "action": "READ" }],
  "identifiers": {
    "user_identifier": ["<employees-id>"]
  },
  "whoQuery": "<employees-id>",
  "applyPolicy": {
    "assets": [{ "type": "DATA_PRODUCT", "id": "<real-estate-portfolio-id>" }]
  }
}

RLF — Allowed properties to view

Goal: Regional managers (david, emily) see only rows for their own region. dataFiltersQuery is the Allowed Properties by Region Access record identifier ID (that Identifier holds the row filter expression).

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies
JSON
{
  "name": "Allowed properties to view",
  "type": "RLF",
  "status": "ACTIVE",
  "actions": [{ "action": "ALLOW" }],
  "identifiers": {
    "record_identifier": ["<region-access-id>"]
  },
  "dataFiltersQuery": "<region-access-id>",
  "applyPolicy": {
    "assets": [{ "type": "DATA_PRODUCT", "id": "<real-estate-portfolio-id>" }],
    "principals": [
      { "type": "USER", "name": "david" },
      { "type": "USER", "name": "emily" }
    ]
  }
}

RLF — Restrict Texas data from offshore users

Goal: Hide Texas customer rows from offshore users across all tables tagged CUSTOMER_DATA. The DENY action drops matching rows. whoQuery and dataFiltersQuery are the offshore-user and Texas-data identifier IDs.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies
JSON
{
  "name": "Restrict Texas data from offshore users",
  "type": "RLF",
  "status": "ACTIVE",
  "actions": [{ "action": "DENY" }],
  "identifiers": {
    "user_identifier": ["<offshore-users-id>"],
    "record_identifier": ["<texas-data-id>"]
  },
  "whoQuery": "<offshore-users-id>",
  "dataFiltersQuery": "<texas-data-id>",
  "applyPolicy": {
    "assets": [{ "type": "TAG", "id": "CUSTOMER_DATA" }]
  }
}

Goal: Allow offshore users to see Texas rows, but only for customers who gave consent. Same scope as the previous policy; dataFiltersQuery is the consent record identifier ID.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies
JSON
{
  "name": "Texas data for offshore users with consent",
  "type": "RLF",
  "status": "ACTIVE",
  "actions": [{ "action": "ALLOW" }],
  "identifiers": {
    "user_identifier": ["<offshore-users-id>"],
    "record_identifier": ["<consent-data-id>"]
  },
  "whoQuery": "<offshore-users-id>",
  "dataFiltersQuery": "<consent-data-id>",
  "applyPolicy": {
    "assets": [{ "type": "TAG", "id": "CUSTOMER_DATA" }]
  }
}

MASKING — Redact sensitive data

Goal: Mask sensitive financial columns for everyone (including data owners) on the REAL_ESTATE_TENANTS data product. MASK_NULL replaces values with NULL; dataQuery is the Sensitive financial columns column identifier ID. principals is GROUP public so it applies to all users.

HTTP
POST <MDS-URL>/api/v1/metadata/omni-policies
JSON
{
  "name": "Redact sensitive data",
  "description": "Mask sensitive financial columns for all users",
  "type": "MASKING",
  "status": "ACTIVE",
  "actions": [
    {
      "action": "MASK",
      "masking": { "type": "MASK_NULL" }
    }
  ],
  "identifiers": {
    "column_identifier": ["<sensitive-columns-id>"]
  },
  "dataQuery": "<sensitive-columns-id>",
  "applyPolicy": {
    "assets": [{ "type": "DATA_PRODUCT", "id": "<real-estate-tenants-id>" }],
    "principals": [{ "type": "GROUP", "name": "public" }]
  }
}

Draft-first workflow

JSON
1
2
3
4
5
{
  "name": "Employee portfolio access",
  "type": "ACCESS",
  "status": "DRAFT"
}

After adding actions, identifiers, and applyPolicy via PUT, activate:

HTTP
PATCH <MDS-URL>/api/v1/metadata/omni-policies/<policy-id>/activate