Skip to content

You are viewing documentation for Immuta version 2.8.

For the latest version, view our documentation for Immuta SaaS or the latest self-hosted version.

Custom Policy Handler

Audience: Data Owners

Content Summary: A custom policy handler can be written with code to enforce complex policy rules on your data sources beyond direct string matching provided through the Immuta user interface policy builder. The policy handler is a REST web service that the Data Owner defines to ensure that policies are being applied to data.

This page outlines how to create, deploy, and secure a custom policy handler.

Creating a Custom Policy Handler

  1. Expose a REST web service that accepts a JSON object (see Listing 1) via an HTTP POST request and returns a JSON object (see Listing 2).

    The JSON posted to your policy handler endpoint has the following data to enable you to build the policy logic:

    userAttributes: these are the key:value(s) attributes for that user from the Immuta internal IDAM.

    dataVisibilities: these are all the possible data visibilities from the data source the user is attempting to access.

    groups: these are the groups the user belongs to, either from the Immuta internal IDAM or the external enterprise IDAM, depending how the user logged in.

    iamProfile: this is a JSON representation of all the data for that user from the enterprise IDAM (if one is being used). This is how you know where the groups came from.

  2. The policy handler processes all of the access decisions in bulk for that user against the data source in question. In other words, all the possible data visibilities will be passed to this endpoint for processing. The processing will consist of your handler applying the custom logic that you have implemented to determine which data visibilities a user has the right to see. If there are no errors it will return a 200 response with a JSON object (see Listing 2). The response object will contain two keys:

    userCanSee: a list of the visibility id(s) the user is authorized to see based on the dataVisibilities list POSTed to the endpoint.

    masked: If applicable, a list of masking objects that correspond to each masked column.

If there are any errors with the data that Immuta POSTed then Immuta will expect the policy handler to return an HTTP response with a status code in the 400 range, with an optional message in the body. If there are any errors in the policy handler that are not client related but are server related, then Immuta will expect an HTTP response with a status code in the 500 range, with an optional message in the body.

Listing 1


Listing 2

    “masked”:array[object] (optional)

Masking Configuration

If your policy handler is to mask columns, your policy response should include a masked attribute that contains an array of objects that correspond to masked columns in your data source.

Standard Masking

  • type: The type of masking applied.
  • metadata: Apply additional metadata to your masking configuration. See examples below for details.
  • name: The name of the column that you wish to mask.
"masked": [
        "type": "Consistent Value",
        "metadata": {"constant": null},
        "name": "col_name_1"

Note: The constant value represents the value that will be used as a replacement for your specified column. If no constant is specified in the policy handler response metadata, a hash of the column value will be used.

Regular Expression Masking

If a policy uses regular expression replacement, the policy handler will send this masking configuration in the response:

"masked": [
        "name": "col_name",
        "type": "Regular Expression",
        "metadata": {
            "regex": "your regex",
            "replacement": "your replacement",
            "global": false,
            "caseInsensitive": false


If a policy rounds the value in col_name to the nearest 10, the policy handler will send this masking configuration in the response:

"masked": [
        "name": "col_name",
        "type": "Grouping",
        "metadata": {
            "bucketSize": 10

Deploying a Custom Policy Handler

Handlers are not hosted within the Immuta product, so it is up to the creator of the handler to deploy and maintain handlers.

Securing a Custom Policy Handler

When registering a policy store handler, the Data Owner is provided with these security options:

  • The Data Owner may provide a CA bundle for their blob store handler in the event that an internally signed or self-signed certificate is being used by the policy store handler endpoint.
  • The Data Owner can go one step further and provide a client certificate and key, which will be used by Immuta when contacting the blob store handler. This option will enable two-way SSL with client verification (if that method of operation is supported by the blob store handler endpoint).

The two- way SSL configuration is highly recommended as it is the most secure configuration for a custom policy handler endpoint.

Changing a Policy Handler

One of the benefits of using Immuta is that changing policies is supported. Those changes will take effect and data availability will change accordingly per user.

Data Visibility Changes

For queryable data sources, you can change the column(s) used for the visibility and those changes will propagate to the policy handler. Assuming the handler is prepared to apply the logic for that change, the policy change will take effect based on the latency tolerance of that data source. Editing a policy can be done through the web user interface workflow if that’s the way it was initially created.

For object-backed data sources, this is the only instance where you have to reload your metadata into Immuta to change a policy (that requires a change to the data visibility values of the metadata). However, this is just the metadata that must be changed, not the raw data; therefore, it is best practice to include enough information in your data visibility to account for future policy changes.

Note: The more unique policies you have, the more decisions the policy handler must make. You must balance those trade-offs, as you can’t have a unique data visibility for every blob/entity, but you also can’t make your data visibility so generic that it breaks with future policy requirements.