Skip to content

Create Virtual Resources and MDS Policies

Resources are not discovered automatically. Declare them in the Data Catalog before a policy can reference them. This is called a virtual resource.

One API call creates the virtual resource, if it does not already exist, and the matching access policy. The revoke call also creates the resource if it does not exist.

A successful call returns 200 OK with an empty body, even when nothing changed. A revoke that matches no grant, for example because the path differs in case, also returns 200 OK. To confirm the result, go to Data Browser → Data Catalog, open the resource, and check that its access permissions list the principal with the expected permission. The resource being present is not proof, because both calls create it.

Register a resource without a policy

The call on this page also grants access. To register the resource only, use the Creating Resources via API endpoint, linked under Create tag-based and other policies below.

Create the principals first

The users, groups, or roles named in the request must already exist in Privacera.

Who can call these endpoints

The caller must be a Privacera admin, or the zone admin of the security zone that governs the resource. For a resource that does not exist yet, that is the zone of its nearest existing parent.

Get the API base URL

  1. In the Portal, go to Settings → API Keys → Generate API Keys.
  2. Enter a Purpose and an Expiry date, then copy the generated API key.
  3. Select the info icon next to the key and copy the Ranger Admin URL.
  4. Replace __API_KEY__ with that key and append /omni-metadata, for example https://apiserver.example.com/api/a1b2c3d4/omni-metadata:

    https://<apiserver-host>/api/<api-key>/omni-metadata
    

The key in the URL authenticates the request, so no authorization header is needed.

  1. Turn on Crypto UI under Settings → System Configurations. Create a token with Type MDS and the Metadata Write scope under Settings → Token Management. A zone admin of the security zone that governs the resource can use a Metadata Read token instead; anyone else gets 403 Forbidden.
  2. Use the URL the Omni Metadata Service is exposed at on your plane. The service is not published under a fixed hostname, so ask whoever set up the ingress. A common form is omni-metadata-<namespace> on the plane's domain, for example https://omni-metadata-runtime-plane.example.com:

    https://<omni-metadata-service-host>
    
  3. Send the token on every request:

    Authorization: Bearer <mds-token>
    

Set Content-Type: application/json on every request.

The examples use the default service repositories. If this connector uses a custom service repository, set serviceName to its name. See Custom Service Repo for Access Management for Starburst Trino.

Hive

Grant read access

Bash
curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <mds-token>' \
    -d '{
      "resource": {
        "serviceName": "privacera_hive",
        "serviceType": "HIVE",
        "resourceType": "TABLE",
        "resourcePath": "<database>/<table>"
      },
      "grant": {
        "permission": "READ",
        "principals": {
          "users": ["<user>"],
          "groups": ["<group>"],
          "roles": ["<role>"]
        }
      }
    }' \
    <mds-base-url>/api/v2/metadata/omni-policies/enforcement/grant-access/resources

Replace the placeholders and check serviceName:

Placeholder Description
<mds-base-url> The base URL from the start of this page.
<mds-token> Self-Managed only. The MDS token from the start of this page. On D2P the API key in the URL authenticates the request, so omit this header.
<database> The Hive database name.
<table> The table name.
<user>, <group>, <role> The principals to grant to. All three keys are optional — send only the ones you need. Each principal must already exist in Privacera.
serviceName The service repository the connector enforces against: privacera_hive by default. If a custom service repository is configured, use its name.

Grant write access

Send the same request with "permission": "WRITE".

READ and WRITE expand to these Hive access types:

Permission Access types granted
READ select, read, refresh
WRITE select, read, refresh, update, create, drop, alter, index, lock, write, data_admin, repladmin, serviceadmin, tempudfadmin, all

Leave accessTypes unset.

Revoke access

Send the same resource with a revoke object that holds only principals, to <mds-base-url>/api/v2/metadata/omni-policies/enforcement/revoke-access/resources. Leave out permission.

Revoke removes all access, READ and WRITE, that the listed principals have on the resource. To downgrade WRITE to READ, grant READ instead. A new grant replaces the existing one.

Resource types

Set resourceType and resourcePath to the level the policy applies to:

Resource type Path shape Example
DATABASE <database> sales_db
TABLE <database>/<table> sales_db/orders
COLUMN <database>/<table>/<column> sales_db/orders/customer_email
UDF <database>/<udf> sales_db/mask_email

A TABLE grant covers every column of the table, including columns added later. Use the narrowest level.

Note

Hive names are not case sensitive. Sales_DB/Orders is stored as sales_db/orders, so it is the same resource.

Masking and row-level filtering are not created by this call. Hive mask types are MASK_HASH, MASK_NULL, MASK_SHOW_FIRST_4, MASK_SHOW_LAST_4, and MASK_NONE.

Trino

Grant read access

Bash
curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <mds-token>' \
    -d '{
      "resource": {
        "serviceName": "privacera_trino",
        "serviceType": "TRINO",
        "resourceType": "TABLE",
        "resourcePath": "<catalog>/<schema>/<table>"
      },
      "grant": {
        "permission": "READ",
        "principals": {
          "users": ["<user>"],
          "groups": ["<group>"],
          "roles": ["<role>"]
        }
      }
    }' \
    <mds-base-url>/api/v2/metadata/omni-policies/enforcement/grant-access/resources

Replace the placeholders and check serviceName:

Placeholder Description
<mds-base-url> The base URL from the start of this page.
<mds-token> Self-Managed only. The MDS token from the start of this page. On D2P the API key in the URL authenticates the request, so omit this header.
<catalog> The Trino catalog name.
<schema> The schema name.
<table> The table name.
<user>, <group>, <role> The principals to grant to. All three keys are optional — send only the ones you need. Each principal must already exist in Privacera.
serviceName The service repository the connector enforces against: privacera_trino by default. If a custom service repository is configured, use its name.

Grant write access

Send the same request with "permission": "WRITE".

READ and WRITE expand to these Trino access types:

Permission Access types granted
READ select, use, show, read_sysinfo
WRITE select, use, show, insert, create, drop, delete, alter, grant, revoke, impersonate, all, execute, createview, data_admin, kill, ownership, publish, update, read_sysinfo, write_sysinfo

WRITE is an administrative grant. Use READ unless the principal must administer the resource.

Leave accessTypes unset.

Revoke access

Send the same resource with a revoke object that holds only principals, to <mds-base-url>/api/v2/metadata/omni-policies/enforcement/revoke-access/resources. Leave out permission.

Revoke removes all access, READ and WRITE, that the listed principals have on the resource. To downgrade WRITE to READ, grant READ instead. A new grant replaces the existing one.

Resource types

Set resourceType and resourcePath to the level the policy applies to:

Resource type Path shape Example
CATALOG <catalog> iceberg
SCHEMA <catalog>/<schema> iceberg/sales_db
TABLE <catalog>/<schema>/<table> iceberg/sales_db/orders
COLUMN <catalog>/<schema>/<table>/<column> iceberg/sales_db/orders/customer_email
PROCEDURE <catalog>/<schema>/<procedure> iceberg/sales_db/refresh_orders

A TABLE grant covers every column of the table, including columns added later. Use the narrowest level.

Note

Trino names are not case sensitive. Iceberg/Sales_DB/Orders is stored as iceberg/sales_db/orders, so it is the same resource.

Which service to grant on

Grant on the service that backs the catalog:

  • Table in a catalog mapped to Hive (by default hive and awsdatacatalog) → privacera_hive
  • Table in any other catalog (Iceberg, Redshift, PostgreSQL, BigQuery) → privacera_trino
  • Locations used in CREATE SCHEMA, CREATE TABLE … WITH (location=…), or ALTER TABLE … SET PROPERTIES location → privacera_s3, so these statements need both grants. Trino does not check S3 for queries on existing tables. The S3 check is on by default and is controlled by FILE_LOCATION_AUTHZ_ENABLED; see Configure External Location Access Check.

Masking and row-level filtering are not created by this call. Trino mask types are MASK_HASH, MASK_NULL, MASK_SHOW_FIRST_4, MASK_SHOW_LAST_4, and MASK_NONE.

S3

Grant on the folder, not on the file

Policies apply at the folder level. For an object such as s3://<bucket>/user/data/sample/sample.txt, create the policy on the folder that contains it:

<bucket>/user/data/sample/

A grant covers the folder and everything under it, including objects added later. Use the narrowest folder.

Grant read access

Bash
curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <mds-token>' \
    -d '{
      "resource": {
        "serviceName": "privacera_s3",
        "serviceType": "S3",
        "resourceType": "OBJECTPATH",
        "resourcePath": "<bucket>/<prefix>/"
      },
      "grant": {
        "permission": "READ",
        "principals": {
          "users": ["<user>"],
          "groups": ["<group>"],
          "roles": ["<role>"]
        }
      }
    }' \
    <mds-base-url>/api/v2/metadata/omni-policies/enforcement/grant-access/resources

Replace the placeholders and check serviceName:

Placeholder Description
<mds-base-url> The base URL from the start of this page.
<mds-token> Self-Managed only. The MDS token from the start of this page. On D2P the API key in the URL authenticates the request, so omit this header.
<bucket> The S3 bucket name.
<prefix> The object path inside the bucket, without a leading or trailing /, for example user/data/sample. The payload adds the trailing / that marks a folder.
serviceName The service repository the connector enforces against: privacera_s3 by default. If a custom service repository is configured, use its name.
<user>, <group>, <role> The principals to grant to. All three keys are optional — send only the ones you need. Each principal must already exist in Privacera.

Grant write access

Send the same request with "permission": "WRITE".

READ and WRITE expand to these S3 access types:

Permission Access types granted
READ read, mread
WRITE read, write, delete, mwrite, admin, mread

Leave accessTypes unset.

Revoke access

Send the same resource with a revoke object that holds only principals.

Bash
curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <mds-token>' \
    -d '{
      "resource": {
        "serviceName": "privacera_s3",
        "serviceType": "S3",
        "resourceType": "OBJECTPATH",
        "resourcePath": "<bucket>/<prefix>/"
      },
      "revoke": {
        "principals": {
          "users": ["<user>"],
          "groups": ["<group>"],
          "roles": ["<role>"]
        }
      }
    }' \
    <mds-base-url>/api/v2/metadata/omni-policies/enforcement/revoke-access/resources

Revoke removes all access, READ and WRITE, that the listed principals have on the resource. To downgrade WRITE to READ, grant READ instead. A new grant replaces the existing one.

Resource types

S3 resources have two levels:

Resource type Path shape Example
BUCKETNAME <bucket> test-bucket
OBJECTPATH <bucket>/<prefix>/ test-bucket/user/data/sample/

Bucket-level grants

A grant on a bucket covers every object in it. It is refused unless the request URL ends with ?allowContainerLevelAccess=true. Prefer a folder.

Note

Object paths are case sensitive, so the path must match the object exactly.

Masking and row-level filtering do not apply to S3.

Create tag-based and other policies

Once a resource is in the Data Catalog:

Task Where
Create a tag Tags and Metadata
Register a resource without creating a policy Creating Resources via API
Attach a tag to a resource Applying Tags to Resources via API
Create an access, masking, or row-filter policy Policies

For a tag-based policy, tag the resources first, then set the policy Data scope to Data Tag.

Note

Tag-based policies are enforced by this connector only after Privacera Support enables tag-based enforcement for plugin services.

Verify

Run these from the Starburst Trino CLI — see Run Starburst Trino CLI. Run each check twice: once as a granted user and once as a denied user.

Hive catalog table

Checks the Hive policy.

SQL
SELECT * FROM hive.<database>.<table> LIMIT 10;

Iceberg catalog table

Checks the Trino policy.

SQL
SELECT * FROM <iceberg-catalog>.<schema>.<table> LIMIT 10;

Create a database on an S3 location

Checks the S3 policy together with the catalog policy. The READ grants above are not enough. Before this check, grant the user WRITE on:

  • privacera_hive, resource type DATABASE, path <database>
  • privacera_s3, resource type OBJECTPATH, path <bucket>/<prefix>/
SQL
CREATE SCHEMA hive.<database> WITH (location = 's3://<bucket>/<prefix>/');

The statement creates the schema, so a second run fails with "already exists". Drop it after the check:

SQL
DROP SCHEMA hive.<database>;

Then, in the portal, go to Access Management → Audits → ACCESS and confirm an Allowed or Denied record for that user and resource.