> This is part 1 of 5 of the full documentation (pages 1–100 of 404).
> The content is paginated: fetch every part to see all of it.
> Next part: https://documentation.immuta.com/2026.2/llms-full.txt/1
> Page index: https://documentation.immuta.com/2026.2/llms.txt

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
This site has an agentic ask interface you may use to query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://documentation.immuta.com/2026.2/index.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

---

# Immuta Documentation - 2026.2

One platform to optimize how you access and control data.

Immuta gives everyone fast, governed access to data with the built-in controls, collaboration workflows, automated provisioning, and continuous monitoring you need to keep risk low and compliance high.

### Configure Immuta

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden></th></tr></thead><tbody><tr><td>1 - <strong>Deploy Immuta</strong></td><td>Install Immuta and optimize the deployment in your Kubernetes environment.<br><br></td><td><a href="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/K6KfkEiv3B4psBOvwy35/Deploy%20Immuta%20-%20Gray%20Rocket@2x.jpg">Deploy Immuta - Gray Rocket@2x.jpg</a></td><td><a href="/2026.2/configuration/self-managed-deployment">Deploy Immuta</a></td><td></td></tr><tr><td>2 - <strong>Connect your data platform</strong></td><td>Before you can create policies, Immuta must be connected to your data platform to manage controls and grant access.</td><td><a href="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/y8w3f3AXFQmLm4jLkJ5Y/Connect%20your%20data%20platform@2x.jpg">Connect your data platform@2x.jpg</a></td><td><a href="/2026.2/configuration/integrations">Connect Integrations</a></td><td></td></tr><tr><td>3 - <strong>Add metadata and users</strong></td><td>For automated policies, tag data and use those tags in policy. Tag your data by connecting Immuta to data catalogs you already use or run identification.</td><td><a href="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/5AQH1YYyMHc5fi5PESkl/Manage%20data%20metadata%20and%20add%20users@2x.jpg">Manage data metadata and add users@2x.jpg</a></td><td><a href="/2026.2/configuration/manage-data-metadata">Manage Data Metadata</a></td><td></td></tr><tr><td>4 - <strong>Organize data into domains</strong></td><td>Just like your organization compartmentalizes ownership of data to different teams and within different platforms, your data in Immuta should be organized into domains.</td><td><a href="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/RimgyjFffgVDmVIkS776/Organize%20data%20into%20domains@2x.jpg">Organize data into domains@2x.jpg</a></td><td><a href="/2026.2/configuration/domains">Organize Data into Domains</a></td><td></td></tr></tbody></table>

### Explore Immuta

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Governance</strong></td><td>Unify data access control across multiple data platforms.</td><td></td><td></td><td></td><td><a href="/2026.2/governance/getting-started-with-secure">Introduction</a></td></tr><tr><td><strong>Configuration</strong></td><td>Connect your data, metadata, and users.</td><td></td><td></td><td></td><td><a href="/2026.2/configuration/integrations">Connect Integrations</a></td></tr><tr><td><strong>Developer guides</strong></td><td>Interact with Immuta through the Immuta CLI and API.</td><td></td><td></td><td></td><td><a href="/2026.2/developer-guides/api-intro">The Immuta API</a></td></tr></tbody></table>


# Deploy Immuta

This section illustrates how to install Immuta on Kubernetes using the Immuta Enterprise Helm chart.

## [Requirements](/2026.2/configuration/self-managed-deployment/deployment-requirements)

This reference guide provides an overview of the Immuta Enterprise Helm chart version requirements and infrastructure recommendations.

## [Install](/2026.2/configuration/self-managed-deployment/install)

The guides in this section illustrate how to install and deploy Immuta in your Kubernetes environment.

## [Upgrade Immuta](/2026.2/configuration/self-managed-deployment/upgrade-immuta)

This guide illustrates how to upgrade Immuta.

## [Guides](/2026.2/configuration/self-managed-deployment/configure)

The guides in this section illustrate how to configure your Immuta Enterprise Helm chart for various scenarios, including optimizing your deployment for production environments.

## [Disaster recovery](/2026.2/configuration/self-managed-deployment/disaster-recovery)

This guide provides links to additional resources for disaster recovery strategies.

## [Troubleshooting](/2026.2/configuration/self-managed-deployment/troubleshooting)

This page provides troubleshooting guidance and outlines frequently asked questions for the Immuta installation.

## [Conventions](/2026.2/configuration/self-managed-deployment/conventions)

This page introduces the core concepts and terminology essential for understanding the installation material.


# Requirements

Immuta comprises three core services: Secure, Discover, and Detect. These services rely on PostgreSQL and Elasticsearch to store their states, a caching layer, and Temporal for job execution. The illustration below shows the relationships among these services.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/XbEghCkcRNtwXhS0pd5U/Immuta%20Enterprise%20Helm%20Chart.png" alt=""><figcaption></figcaption></figure>

The Immuta Enterprise Helm chart (IEHC) does not include the deployment of PostgreSQL or Elasticsearch, so you must deploy them separately.

Although Immuta recommends using Elasticsearch because it supports all audit, you can deploy Immuta without Elasticsearch. The table below outlines the Immuta features supported with and without Elasticsearch and the dependencies you must deploy and manage yourself.

<table><thead><tr><th></th><th width="257.75">Immuta with Elasticsearch</th><th width="250.5">Immuta without Elasticsearch</th></tr></thead><tbody><tr><td>Dependencies</td><td><ul><li><a href="#metadata-database-postgresql">Externalized PostgreSQL</a></li><li><a href="#elasticsearch">Elasticsearch / OpenSearch</a></li></ul></td><td><a href="#metadata-database-postgresql">Externalized PostgreSQL</a></td></tr><tr><td>Immuta Detect</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Audit of Immuta and data platform events</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Legacy audit</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Immuta Monitors</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Identification</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr></tbody></table>

For information about legacy databases and services no longer enabled in the recommended deployment of Immuta, see the [Legacy databases section](#legacy-features-and-services).

## Version requirements

### Kubernetes versions

* Kubernetes 1.29 - 1.35

### Metadata database (PostgreSQL)

{% hint style="danger" %}
**PostgreSQL incompatibilities**

Immuta is not compatible with PostgreSQL abstraction layers, such as Amazon Aurora.
{% endhint %}

* PostgreSQL 15.0 or newer
* The `pgcrypto` and `btree_gin` extensions must be enabled

### Elasticsearch

* Elasticsearch v7 API or newer
* AWS OpenSearch Service compatible with Elasticsearch v7 API or newer
  * AWS OpenSearch Serverless is **not supported**

#### OpenSearch user

The user provided during the install must have the following [permissions](https://opensearch.org/docs/latest/security/access-control/permissions/):

* Cluster permissions:
  * cluster:monitor/health
  * indices:data/write/bulk
  * indices:data/write/bulk\*
  * indices:data/read/scroll
  * indices:data/read/scroll/clear
  * indices:monitor/settings/get
* Index permissions:
  * indices:admin/aliases
  * indices:admin/aliases\*
  * indices:admin/exists
  * indices:admin/create
  * indices:admin/delete
  * indices:admin/settings/update
  * indices:admin/get
  * indices:admin/refresh
  * indices:admin/refresh\*
  * indices:admin/mapping/put
  * indices:data/read/search
  * indices:data/read/scroll
  * indices:data/read/scroll/clear
  * indices:data/write/delete
  * indices:data/write/delete/byquery
  * indices:data/write/index
  * indices:data/write/bulk
  * indices:data/write/bulk\*
  * indices:data/write/update/byquery
  * indices:monitor/settings/get

Follow OpenSearch documentation to [create the user](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/createupdatedomains.html#createdomains) and add permissions, or see the [OpenSearch authentication guides](/2026.2/configuration/self-managed-deployment/configure/opensearch-authentication).

### Cache (Redis/Memcached)

{% hint style="info" %}
**Built-in cache**

The IEHC manages its own Memcached deployment inside the cluster. The key-value cache can optionally be externalized post installation.
{% endhint %}

* Redis 7.0 or newer
* Memcached 1.6 or newer

### Temporal

{% hint style="info" %}
Built-in Temporal server

The IEHC deploys a Temporal server and its requisite components. However, you may choose to use your own Temporal instance.
{% endhint %}

* Temporal 1.24.2 or newer

## Infrastructure recommendations

<table><thead><tr><th>Kubernetes distribution</th><th>Ingress</th><th>External metadata database</th><th>External Elasticsearch</th><th data-hidden>External cache</th></tr></thead><tbody><tr><td>Amazon Elastic Kubernetes Service (EKS)</td><td>AWS Load Balancer Controller</td><td><a href="https://docs.aws.amazon.com/rds/">Amazon RDS for PostgreSQL</a></td><td><a href="https://docs.aws.amazon.com/opensearch-service/">Amazon OpenSearch</a></td><td><a href="https://docs.aws.amazon.com/elasticache/">Amazon ElastiCache for Redis</a></td></tr><tr><td>Azure Kubernetes Service (AKS)</td><td>Azure Application Gateway Ingress Controller</td><td><a href="https://learn.microsoft.com/en-us/azure/postgresql/">Azure Database for PostgreSQL</a></td><td><a href="https://www.elastic.co/partners/microsoft-azure">Elastic Cloud on Azure</a></td><td><a href="https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/">Azure Cache for Redis</a></td></tr><tr><td>Google Kubernetes Engine (GKE)</td><td>GKE Ingress Controller</td><td><a href="https://cloud.google.com/sql/docs/postgres">Google Cloud SQL for PostgreSQL</a></td><td><a href="https://www.elastic.co/partners/google-cloud">Elastic Cloud on Google Cloud</a></td><td><a href="https://cloud.google.com/memorystore/docs/redis">Memorystore for Redis</a></td></tr><tr><td>Red Hat OpenShift</td><td>OpenShift Ingress Operator</td><td><a data-footnote-ref href="#user-content-fn-1">Cloud-managed PostgreSQL</a></td><td><a data-footnote-ref href="#user-content-fn-2">Cloud-managed Elasticsearch</a></td><td><a data-footnote-ref href="#user-content-fn-3">Cloud-managed Redis</a></td></tr></tbody></table>

### Legacy databases <a href="#legacy-features-and-services" id="legacy-features-and-services"></a>

Some legacy databases are no longer available when deploying Immuta using the recommended configuration of the IEHC. See the [Enable the legacy query engine guide](/2026.2/configuration/self-managed-deployment/configure/enabling-legacy-query-engine) to enable support for these [databases](/2026.2/releases/support-matrix#legacy-databases).

[^1]: Cloud-managed PostgreSQL, such as Amazon RDS, Azure Database for PostgreSQL, or Google Cloud SQL for PostgreSQL, is recommended when running Kubernetes in cloud environments.

[^2]: Cloud-managed Elasticsearch, such as Amazon OpenSearch, or Elastic Cloud, is recommended when running Kubernetes in cloud environments.

[^3]: Cloud-managed Redis/Memcached, such as Amazon ElastiCache, Azure Cache, or Google Cloud Memorystore, is recommended when running Kubernetes in cloud environments.


# Install

The guides in this section illustrate how to install and deploy Immuta in your Kubernetes environment.

## Prerequisites

{% hint style="info" %}
**Helm installation**

The following guides use the `helm` command to manage Kubernetes resources; ensure it's installed before proceeding. Refer to the [Helm documentation](https://helm.sh/docs/intro/install/) for further assistance.
{% endhint %}

### Checklist

* [ ] [RBAC permissions](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) have been granted to create resources in the cluster.

## Quickstart

{% hint style="info" %}
**Encountering issues?**

Ensure you can communicate with all required services from within the Kubernetes cluster. Consult the [troubleshooting](/2026.2/configuration/self-managed-deployment/troubleshooting) section for solutions to common problems.
{% endhint %}

Get started quickly with these essential guides. For a more comprehensive understanding and advanced configurations, [explore the full suite of guides](/2026.2/configuration/self-managed-deployment/configure).

1. Complete the guide that corresponds with your Kubernetes cluster's distribution.
   * [Managed public cloud](/2026.2/configuration/self-managed-deployment/install/managed-public-cloud): This guide includes instructions for
     * Amazon Elastic Kubernetes Service (EKS)
     * Google Kubernetes Engine (GKE)
     * Microsoft Azure Kubernetes Service (AKS)
   * [Red Hat OpenShift](/2026.2/configuration/self-managed-deployment/install/red-hat-openshift)
2. Complete the [Ingress configuration](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration) guide.
3. Complete the [Production best practices](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production) guide.


# Managed Public Cloud

This is a guide on how to deploy Immuta on Kubernetes in the following managed public cloud providers:

* Amazon Web Services (AWS)
* Microsoft Azure
* Google Cloud Platform (GCP)

## Prerequisites

The following managed services must be provisioned and running before proceeding. For further assistance consult the [recommendations table](/2026.2/configuration/self-managed-deployment/deployment-requirements#infrastructure-recommendations) for your respective cloud provider.

{% hint style="warning" %}
**Feature availability**

If deployed without ElasticSearch/OpenSearch, several core services and features will be unavailable. See the [deployment requirements](/2026.2/configuration/self-managed-deployment/deployment-requirements) for details.
{% endhint %}

{% tabs %}
{% tab title="Amazon Web Services (AWS)" %}

* [Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/rds/)
* (Optional) [Amazon OpenSearch](https://docs.aws.amazon.com/opensearch-service/)
  {% endtab %}

{% tab title="Microsoft Azure" %}

* [Azure Database for PostgreSQL](https://learn.microsoft.com/en-us/azure/postgresql/)
* (Optional) [Elastic Cloud on Azure](https://www.elastic.co/partners/microsoft-azure)
  {% endtab %}

{% tab title="Google Cloud Platform (GCP)" %}

* [Google Cloud SQL for PostgreSQL](https://cloud.google.com/sql/docs/postgres)
* (Optional) [Elastic Cloud on Google Cloud](https://www.elastic.co/partners/google-cloud)
  {% endtab %}
  {% endtabs %}

### Checklist

This checklist outlines the necessary prerequisites for successfully deploying Immuta.

#### Credentials

* [ ] You have the credentials needed to access the ocir.immuta.com OCI registry. There is currently no self-service lookup; if you do not have them, contact your Immuta representative or Immuta Support.

#### PostgreSQL

* [ ] The PostgreSQL instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](/2026.2/configuration/self-managed-deployment/troubleshooting#common).
* [ ] The PostgreSQL instance is [accepting connections](/2026.2/configuration/self-managed-deployment/troubleshooting#postgresql).
* [ ] You have a PostgreSQL user account with the necessary privileges to create databases, extensions, and roles.
* [ ] You have username/password credentials for the PostgreSQL user. Username/password is the only authentication mechanism the Helm chart supports for PostgreSQL.

#### Elasticsearch

* [ ] The Elasticsearch instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](/2026.2/configuration/self-managed-deployment/troubleshooting#common).
* [ ] The Elasticsearch instance is [accepting connections](/2026.2/configuration/self-managed-deployment/troubleshooting#elasticsearch).
* [ ] The user must have the [required permissions](/2026.2/configuration/self-managed-deployment/deployment-requirements#opensearch-user).
* [ ] You have credentials for one of the two supported authentication methods: [username and password](/2026.2/configuration/self-managed-deployment/configure/opensearch-authentication/setting-up-opensearch-user-permissions-for-username-and-password-authentication) or [AWS assumed role for OpenSearch](/2026.2/configuration/self-managed-deployment/configure/opensearch-authentication/setting-up-opensearch-user-permissions-for-an-aws-role). Other authentication mechanisms are not supported.

## Setup

### Helm

#### Authenticate with OCI registry

```bash
echo <token> | helm registry login --password-stdin --username <username> ocir.immuta.com
```

### Kubernetes

{% hint style="info" %}
Creating a dedicated namespace ensures a logically isolated environment for your Immuta deployment, preventing resource conflicts with other applications.
{% endhint %}

#### Create namespace

1. Create a Kubernetes namespace named `immuta`.

   ```bash
   kubectl create namespace immuta
   ```
2. Switch to namespace `immuta`. All subsequent `kubectl` commands will default to this namespace.

   ```bash
   kubectl config set-context --current --namespace=immuta
   ```

#### Create registry secret

Create a container registry pull secret. Your credentials to authenticate with ocir.immuta.com are provided by Immuta; there is currently no self-service lookup — contact your Immuta representative or Immuta Support if you do not have them.

```
kubectl create secret docker-registry immuta-oci-registry \
    --docker-server=https://ocir.immuta.com \
    --docker-username="<username>" \
    --docker-password="<token>" \
    --docker-email=support@immuta.com
```

### PostgreSQL

{% hint style="info" %}
**Connecting a client**

There are numerous ways to connect to a PostgreSQL database. This step demonstrates how to connect with psql by creating an ephemeral Kubernetes pod.
{% endhint %}

#### Connect to the database

Connect to the database as an admin (e.g., `postgres`) by creating an ephemeral container inside the Kubernetes cluster. A shell prompt will not be displayed after executing the `kubectl run` command outlined below. Wait 5 seconds, and then proceed by entering a password.

```sh
kubectl run pgclient \
    --stdin \
    --tty \
    --rm \
    --image docker.io/bitnami/postgresql -- \
    psql --host <postgres-fqdn> --username <postgres-admin> --dbname postgres --port 5432 --password
```

#### Create role

{% hint style="info" %}
Temporal's upgrade mechanism utilizes SQL command `CREATE EXTENSION` when managing database schema changes. However, in cloud-managed PostgreSQL offerings, this command is typically restricted to roles with elevated privileges to protect the database and maintain the stability of the cloud environment.

To ensure Temporal can successfully manage its schema, an administrator role must be granted temporarily. The role name varies depending on the cloud-managed service:

* Amazon RDS: `rds_superuser`
* Azure Database: `azure_pg_admin`
* Google Cloud SQL: `cloudsqlsuperuser`
  {% endhint %}

1. Create the `immuta` role.

   ```sql
   CREATE ROLE immuta with LOGIN ENCRYPTED PASSWORD '<postgres-password>';
   ALTER ROLE immuta SET search_path TO bometadata,public;
   ```
2. Grant administrator privileges to the `immuta` role, where `<admin-role>` is `rds_superuser` (Amazon RDS), `azure_pg_admin` (Azure Database), or `cloudsqlsuperuser` (Google Cloud SQL). Upon successfully completing this installation guide, you can optionally revoke this role grant.

   ```plsql
   GRANT <admin-role> TO immuta;
   ```
3. Grant the `immuta` role to the current user. Upon successfully completing this installation guide, you can optionally revoke this role grant.

   ```plsql
   GRANT immuta TO CURRENT_USER;
   ```

#### Create databases

1. Create databases.

   ```plsql
   CREATE DATABASE immuta OWNER immuta;
   CREATE DATABASE temporal OWNER immuta;
   CREATE DATABASE temporal_visibility OWNER immuta;
   ```
2. Grant role `immuta` additional privileges. Refer to the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/ddl-priv.html) for further details on database roles and privileges.

   ```plsql
   GRANT ALL ON DATABASE immuta TO immuta;
   GRANT ALL ON DATABASE temporal TO immuta;
   GRANT ALL ON DATABASE temporal_visibility TO immuta;
   ```
3. Configure the `immuta` database.

   ```plsql
   \c immuta
   CREATE EXTENSION pgcrypto;
   ```
4. Configure the `temporal` database.

   ```plsql
   \c temporal
   GRANT CREATE ON SCHEMA public TO immuta;
   ```
5. Configure the `temporal_visibility` database.

   <pre class="language-plsql"><code class="lang-plsql">\c temporal_visibility
   <strong>GRANT CREATE ON SCHEMA public TO immuta;
   </strong>CREATE EXTENSION btree_gin;
   </code></pre>
6. Exit the interactive prompt. Type `\q`, and then press `Enter`.

## Install Immuta

This section demonstrates how to deploy Immuta using the Immuta Enterprise Helm chart once the prerequisite cloud-managed services are configured.

{% hint style="warning" %}
**Feature availability**

If deployed without Elasticsearch/OpenSearch, several core services and features will be unavailable. See the [deployment requirements](/2026.2/configuration/self-managed-deployment/deployment-requirements) for details.
{% endhint %}

{% tabs %}
{% tab title="Default" %}

<pre class="language-yaml" data-title="immuta-values.yaml" data-line-numbers><code class="lang-yaml">global:
  imageRegistry: ocir.immuta.com
  imagePullSecrets:
    - name: immuta-oci-registry
  postgresql:
    host: &#x3C;postgres-fqdn>
    port: 5432
    username: immuta
    password: &#x3C;postgres-password>

audit:
  config:
    elasticsearchEndpoint: &#x3C;elasticsearch-endpoint>
    searchAuthenticationType: &#x3C;<a data-footnote-ref href="#user-content-fn-1">'UsernamePassword'</a> or '<a data-footnote-ref href="#user-content-fn-2">AWS</a>'>
  # If you use OpenSearch and authenticate with username and password, uncomment the lines below by deleting the hash symbols
    #elasticsearchUsername: &#x3C;elasticsearch-username>
    #elasticsearchPassword: &#x3C;elasticsearch-password>
  # If you use OpenSearch and authenticate with AWS role, uncomment the lines below by deleting the hash symbols. When using AWS role authentication, elasticsearchUsername (above) must be set to ''.
    #searchAwsRegion: '&#x3C;deployment-OS-region>'
  # If Immuta is deployed in an AWS account that is different than OpenSearch, then you must configure a trust relationship between the Immuta role and an OpenSearch role 
    #searchAwsRoleArn: '&#x3C;assumed-role-arn>'
  postgresql:
    database: immuta
  #init:
     #extraEnvVars:
        # <a data-footnote-ref href="#user-content-fn-3">Audit retention</a> defaults to 7 days. To change the retention period, uncomment the lines below by deleting the hash symbols and update the value
        #- name: AUDIT_RETENTION_POLICY_IN_DAYS
          #value: 90

onboarding:
  postgresql:
    database: immuta

secure:
  postgresql:
    database: immuta
    ssl: true

temporal:
  enabled: true
  schema:
    createDatabase:
      enabled: false
  server:
    config:
      persistence:
        default:
          sql:
            database: temporal
            tls: 
              enabled: true
        visibility:
          sql:
            database: temporal_visibility
            tls:
              enabled: true
</code></pre>

{% endtab %}

{% tab title="Without Elasticsearch" %}
{% code title="immuta-values.yaml" lineNumbers="true" %}

```yaml
global:
  imageRegistry: ocir.immuta.com
  imagePullSecrets:
    - name: immuta-oci-registry
  postgresql:
    host: <postgres-fqdn>
    port: 5432
    username: immuta
    password: <postgres-password>

audit:
  enabled: false

onboarding:
  postgresql:
    database: immuta

secure:
  postgresql:
    database: immuta
    ssl: true
  extraEnvVars:
    - name: FeatureFlag_AuditService
      value: false
    
temporal:
  enabled: true
  schema:
    createDatabase:
      enabled: false
  server:
    config:
      persistence:
        default:
          sql:
            database: temporal
            tls: 
              enabled: true
        visibility:
          sql:
            database: temporal_visibility
            tls:
              enabled: true
```

{% endcode %}
{% endtab %}
{% endtabs %}

1. Create a file named `immuta-values.yaml` with the above content, making sure to update all [placeholder values](/2026.2/configuration/self-managed-deployment/conventions).

{% hint style="warning" %}
**Avoid these special characters in generated passwords**

whitespace, `$`, `&`, `:`, `\`, `/`, `'`, `"`
{% endhint %}

2. Deploy Immuta.

   ```bash
   helm install immuta oci://ocir.immuta.com/stable/immuta-enterprise \
       --values immuta-values.yaml \
       --version 2026.2.2
   ```
3. Wait for all pods to become ready.

   ```bash
   kubectl wait --for=condition=Ready pods --all
   ```

## Validation

{% hint style="info" %}
This section helps you validate your Immuta installation by temporarily accessing the application locally. However, this access is limited to your own computer. To enable access for other devices, you must proceed with configuring Ingress outlined in the [Next steps](#next-steps) section.
{% endhint %}

1. Determine the name of the gateway service.

   ```bash
   kubectl get service --selector "app.kubernetes.io/component=gateway" --output name
   ```
2. Listen on local port `8080`, forwarding TCP traffic to the gateway service's port named `http`.

   ```bash
   kubectl port-forward <service-name> 8080:http
   ```
3. In a web browser, navigate to [localhost:8080](http://localhost:8080), to ensure the Immuta application loads.
4. Press `Control+C` to stop port forwarding.

## Next steps

{% tabs %}
{% tab title="Amazon Web Services (AWS)" %}

* [Configure Ingress for EKS](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration#aws-load-balancer-controller) (required).
* [Configure TLS certificates for EKS](/2026.2/configuration/self-managed-deployment/configure/tls-configuration#aws-load-balancer-controller).
* [Learn about best practices for running Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production).
  {% endtab %}

{% tab title="Microsoft Azure" %}

* [Configure Ingress for AKS](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration#aks-application-gateway-ingress-controller) (required).
* [Configure TLS certificates for AKS](/2026.2/configuration/self-managed-deployment/configure/tls-configuration#aks-application-gateway-ingress-controller).
* [Learn about best practices for running Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production).
  {% endtab %}

{% tab title="Google Cloud Platform (GCP)" %}

* [Configure Ingress for GKE](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration#gke-ingress-controller) (required).
* [Configure TLS certificates for GKE](/2026.2/configuration/self-managed-deployment/configure/tls-configuration#gke-ingress-controller).
* [Learn about best practices for running Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production).
  {% endtab %}
  {% endtabs %}

[^1]: If using `UsernamePassword`, you must include the `elasticsearchUsername` and `elasticsearchPassword` values.

[^2]: If using `AWS` role authentication, `elasticsearchUsername` must be set to `''` and you must include the `searchAwsRegion` value.

[^3]: For more details about Immuta's audit retention, see the [Audit best practices page](/2026.2/configuration/self-managed-deployment/configure/audit-best-practices#retention-period).


# Red Hat OpenShift

This is a guide on how to deploy Immuta on OpenShift.

## Prerequisites

The following managed services must be provisioned and running before proceeding. For further assistance consult the [recommendations table](/2026.2/configuration/self-managed-deployment/deployment-requirements#infrastructure-recommendations) for your respective cloud provider.

{% hint style="warning" %}
**Feature availability**

If deployed without Elasticsearch/OpenSearch, several core services and features will be unavailable. See the [deployment requirements](/2026.2/configuration/self-managed-deployment/deployment-requirements) for details.
{% endhint %}

* PostgreSQL
* (Optional) Elasticsearch/OpenSearch Service

### Checklist

This checklist outlines the necessary prerequisites for successfully deploying Immuta.

#### Credentials

* [ ] You have the credentials needed to access the ocir.immuta.com OCI registry. There is currently no self-service lookup; if you do not have them, contact your Immuta representative or Immuta Support.

#### PostgreSQL

* [ ] The PostgreSQL instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](/2026.2/configuration/self-managed-deployment/troubleshooting#common).
* [ ] The PostgreSQL instance is [accepting connections](/2026.2/configuration/self-managed-deployment/troubleshooting#postgresql).
* [ ] You have a PostgreSQL user account with the necessary privileges to create databases, extensions, and roles.
* [ ] You have username/password credentials for the PostgreSQL user. Username/password is the only authentication mechanism the Helm chart supports for PostgreSQL.

#### Elasticsearch

* [ ] The Elasticsearch instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](/2026.2/configuration/self-managed-deployment/troubleshooting#common).
* [ ] The Elasticsearch instance is [accepting connections](/2026.2/configuration/self-managed-deployment/troubleshooting#elasticsearch).
* [ ] The user must have the [required permissions](/2026.2/configuration/self-managed-deployment/deployment-requirements#opensearch-user).
* [ ] You have credentials for one of the two supported authentication methods: [username and password](/2026.2/configuration/self-managed-deployment/configure/opensearch-authentication/setting-up-opensearch-user-permissions-for-username-and-password-authentication) or [AWS assumed role for OpenSearch](/2026.2/configuration/self-managed-deployment/configure/opensearch-authentication/setting-up-opensearch-user-permissions-for-an-aws-role). Other authentication mechanisms are not supported.

## Setup

### Helm

#### Authenticate with OCI registry

```bash
echo <token> | helm registry login --password-stdin --username <username> ocir.immuta.com
```

### Kubernetes

{% hint style="info" %}
Creating a dedicated namespace ensures a logically isolated environment for your Immuta deployment, preventing resource conflicts with other applications.
{% endhint %}

#### Create project

1. Create an OpenShift project named `immuta`.

   ```bash
   oc new-project immuta
   ```
2. Get the UID range allocated to the project. Each running container's UID must fall within this range. This value will be referenced later on.

   ```bash
   oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
   ```
3. Get the GID range allocated to the project. Each running container's GID must fall within this range. This value will be referenced later on.

   ```bash
   oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
   ```
4. Switch to project `immuta`.

   ```bash
   oc project immuta
   ```

#### Create registry secret

Create a container registry pull secret. Your credentials to authenticate with ocir.immuta.com are provided by Immuta; there is currently no self-service lookup — contact your Immuta representative or Immuta Support if you do not have them.

```bash
oc create secret docker-registry immuta-oci-registry \
    --docker-server=https://ocir.immuta.com \
    --docker-username="<username>" \
    --docker-password="<token>" \
    --docker-email=support@immuta.com
```

### PostgreSQL

{% hint style="info" %}
**Connecting a client**

There are numerous ways to connect to a PostgreSQL database. This step demonstrates how to connect with psql by creating an ephemeral Kubernetes pod.
{% endhint %}

#### Connect to the database

Connect to the database as an admin (e.g., `postgres`) by creating an ephemeral container inside the Kubernetes cluster. A shell prompt will not be displayed after executing the `kubectl run` command outlined below. Wait 5 seconds, and then proceed by entering a password.

```sh
oc run pgclient \
    --stdin \
    --tty \
    --rm \
    --image docker.io/bitnami/postgresql -- \
    psql --host <postgres-fqdn> --username <postgres-admin> --dbname postgres --port 5432 --password
```

#### Create role

{% hint style="info" %}
Temporal's upgrade mechanism utilizes SQL command `CREATE EXTENSION` when managing database schema changes. However, in cloud-managed PostgreSQL offerings, this command is typically restricted to roles with elevated privileges to protect the database and maintain the stability of the cloud environment.

To ensure Temporal can successfully manage its schema, a pre-defined administrator role must be granted. The role name varies depending on the cloud-managed service:

* Amazon RDS: `rds_superuser`
* Azure Database: `azure_pg_admin`
* Google Cloud SQL: `cloudsqlsuperuser`
  {% endhint %}

1. Create the `immuta` role.

   <pre class="language-plsql"><code class="lang-plsql"><strong>CREATE ROLE immuta with LOGIN ENCRYPTED PASSWORD '&#x3C;postgres-password>';
   </strong>ALTER ROLE immuta SET search_path TO bometadata,public;
   </code></pre>
2. Grant administrator privileges to the `immuta` role, where `<admin-role>` is `rds_superuser` (Amazon RDS), `azure_pg_admin` (Azure Database), or `cloudsqlsuperuser` (Google Cloud SQL). Upon successfully completing this installation guide, you can optionally revoke this role grant.

   ```plsql
   GRANT <admin-role> TO immuta;
   ```

#### Create databases

1. Create databases.

   ```plsql
   CREATE DATABASE immuta OWNER immuta;
   CREATE DATABASE temporal OWNER immuta;
   CREATE DATABASE temporal_visibility OWNER immuta;
   ```
2. Grant role `immuta` additional privileges. Refer to the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/ddl-priv.html) for further details on database roles and privileges.

   ```plsql
   GRANT ALL ON DATABASE immuta TO immuta;
   GRANT ALL ON DATABASE temporal TO immuta;
   GRANT ALL ON DATABASE temporal_visibility TO immuta;
   ```
3. Configure the `immuta` database.

   ```plsql
   \c immuta
   CREATE EXTENSION pgcrypto;
   ```
4. Configure the `temporal` database.

   ```plsql
   \c temporal
   GRANT CREATE ON SCHEMA public TO immuta;
   ```
5. Configure the `temporal_visibility` database.

   <pre class="language-plsql"><code class="lang-plsql">\c temporal_visibility
   <strong>GRANT CREATE ON SCHEMA public TO immuta;
   </strong>CREATE EXTENSION btree_gin;
   </code></pre>
6. Exit the interactive prompt. Type `\q`, and then press `Enter`.

## Install Immuta

This section demonstrates how to deploy Immuta using the Immuta Enterprise Helm chart once the prerequisite cloud-managed services are configured.

{% hint style="info" %}
**Why disable Ingress?**

In OpenShift, Ingress resources are managed by OpenShift Routes. These routes provide a more integrated and streamlined way to handle external access to your applications. To avoid conflicts and ensure proper functionality, it's necessary to disable the pre-defined Ingress resource in the Helm chart.
{% endhint %}

{% hint style="warning" %}
**Feature availability**

If deployed without Elasticsearch/OpenSearch, several core services and features will be unavailable. See the [deployment requirements](/2026.2/configuration/self-managed-deployment/deployment-requirements) for details.
{% endhint %}

{% tabs %}
{% tab title="Default" %}

<pre class="language-yaml" data-title="immuta-values.yaml" data-line-numbers><code class="lang-yaml">global:
  imageRegistry: ocir.immuta.com
  imagePullSecrets:
    - name: immuta-oci-registry
  postgresql:
    host: &#x3C;postgres-fqdn>
    port: 5432
    username: immuta
    password: &#x3C;postgres-password>

audit:
  config:
    elasticsearchEndpoint: &#x3C;elasticsearch-endpoint>
    searchAuthenticationType: &#x3C;'<a data-footnote-ref href="#user-content-fn-1">UsernamePassword</a>' or '<a data-footnote-ref href="#user-content-fn-2">AWS</a>'>
  # If you use OpenSearch and authenticate with username and password, uncomment the lines below by deleting the hash symbols
    #elasticsearchUsername: &#x3C;elasticsearch-username>
    #elasticsearchPassword: &#x3C;elasticsearch-password>
  # If you use OpenSearch and authenticate with AWS role, uncomment the lines below by deleting the hash symbols. When using AWS role authentication, elasticsearchUsername (above) must be set to ''.
    #searchAwsRegion: '&#x3C;deployment-OS-region>'
  # If Immuta is deployed in an AWS account that is different than OpenSearch, then you must configure a trust relationship between the Immuta role and an OpenSearch role 
    #searchAwsRoleArn: '&#x3C;assumed-role-arn>'
  postgresql:
    database: immuta 

  deployment:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: &#x3C;user-id>
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: &#x3C;group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  #init:
    #extraEnvVars:
      # <a data-footnote-ref href="#user-content-fn-3">Audit retention</a> defaults to 7 days. To change the retention period, uncomment the lines below by deleting the hash symbols and update the value
      #- name: AUDIT_RETENTION_POLICY_IN_DAYS
        #value: 90      
        
  worker:
    podSecurityContext:  
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: &#x3C;user-id>
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: &#x3C;group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL 

discover:
  deployment:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: &#x3C;user-id>
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: &#x3C;group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

onboarding:
  postgresql:
    database: immuta

secure:

  postgresql:
    database: immuta
    ssl: false

  web:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: &#x3C;user-id>
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: &#x3C;group-id>
      seccompProfile:
        type: RuntimeDefault
  
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

  backgroundWorker:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: &#x3C;user-id>
      # A number that is within the project range:
      #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: &#x3C;group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  
temporal:
  enabled: true
  schema:
    createDatabase:
      enabled: false
  server:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: &#x3C;user-id>
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: &#x3C;group-id>
        seccompProfile:
          type: RuntimeDefault
    config:
      persistence:
        default:
          sql:
            database: temporal
            tls:
              enabled: true
        visibility:
          sql:
            database: temporal_visibility
            tls:
              enabled: true
    frontend:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    history:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    matching:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    worker:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
  schema:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: &#x3C;user-id>
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: &#x3C;group-id>
        seccompProfile:
          type: RuntimeDefault
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  proxy:
    deployment:
      podSecurityContext:
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: &#x3C;user-id>
        # A number that is within the project range:
        #   oc get project &#x3C;project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: &#x3C;group-id>
        seccompProfile:
          type: RuntimeDefault
      containerSecurityContext:
        enabled: true
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
</code></pre>

{% endtab %}

{% tab title="Without Elasticsearch" %}
{% code title="immuta-values.yaml" lineNumbers="true" %}

```yaml
global:
  imageRegistry: ocir.immuta.com
  imagePullSecrets:
    - name: immuta-oci-registry
  postgresql:
    host: <postgres-fqdn>
    port: 5432
    username: immuta
    password: <postgres-password>

audit:
  enabled: false

discover:
  deployment:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault

    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

onboarding:
  postgresql:
    database: immuta

secure:

  extraEnvVars:
    - name: FeatureFlag_AuditService
      value: false

  postgresql:
    database: immuta
    ssl: true

  web:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault

    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

  backgroundWorker:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault

    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

temporal:
  enabled: true
  schema:
    createDatabase:
      enabled: false
  server:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
    config:
      persistence:
        default:
          sql:
            database: temporal
            tls:
              enabled: true
        visibility:
          sql:
            database: temporal_visibility
            tls:
              enabled: true
    frontend:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    history:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    matching:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    worker:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
  schema:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  proxy:
    deployment:
      podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
      containerSecurityContext:
        enabled: true
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
```

{% endcode %}
{% endtab %}
{% endtabs %}

1. Create a file named `immuta-values.yaml` with the above content, making sure to update all [placeholder values](/2026.2/configuration/self-managed-deployment/conventions).

{% hint style="warning" %}
**Avoid these special characters in generated passwords**

whitespace, `$`, `&`, `:`, `\`, `/`, `'`, `"`
{% endhint %}

2. Deploy Immuta.

   ```bash
   helm install immuta oci://ocir.immuta.com/stable/immuta-enterprise \
       --values immuta-values.yaml \
       --version 2026.2.2
   ```
3. Wait for all pods to become ready.

   ```bash
   oc wait --for=condition=Ready pods --all
   ```

## Validation

{% hint style="info" %}
This section helps you validate your Immuta installation by temporarily accessing the application locally. However, this access is limited to your own computer. To enable access for other devices, you must proceed with configuring Ingress outlined in the [Next steps](#next-steps) section.
{% endhint %}

1. Determine the name of the gateway service.

   ```bash
   oc get service --selector "app.kubernetes.io/component=gateway" --output name
   ```
2. Listen on local port `8080`, forwarding TCP traffic to the gateway service's port named `http`.

   ```bash
   oc port-forward <service-name> 8080:http
   ```
3. In a web browser, navigate to [localhost:8080](http://localhost:8080), to ensure the Immuta application loads.
4. Press `Control+C` to stop port forwarding.

## Next steps

* [Configure Ingress for OpenShift (required)](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration#openshift-ingress-operator).
* [Learn about best practices for running Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production).

[^1]: If using `UsernamePassword`, you must include the `elasticsearchUsername` and `elasticsearchPassword` values.

[^2]: If using `AWS` role authentication, `elasticsearchUsername` must be set to `''` and you must include the `searchAwsRegion` value.

[^3]: For more details about Immuta's audit retention, see the [Audit best practices page](/2026.2/configuration/self-managed-deployment/configure/audit-best-practices#retention-period).


# Upgrade to 2026.2

## Requirement

* You must be on the most [recent LTS release](/2026.2/releases/release-lifecycle#release-lifecycle-schedule) or newer to upgrade directly to this version of Immuta.
* Back up the audit database.

## Changes introduced in 2026.2

The following changes are new to 2026.2 and will require additional action before you upgrade. See details about each change in the linked sections below:

* [**Helm chart changes**](#helm-chart-changes)
  * [**Ingress migration**](#ingress-migration): The ingress configuration values in the Helm chart have moved.
  * [**Onboarding service**](#onboarding-service): The Immuta deployment now has an onboarding service, which must be represented in the Helm chart.
  * [**Tenant ID**](#tenant-id): A global tenant ID must now be manually set in the Helm chart as a UUID.
  * [**OpenSearch index**](#opensearch-index-names): Your OpenSearch cluster index names must now be manually set in the Helm chart.
* [**Guardrail subscription policies**](#guardrail-subscription-policies): Global policies now have the option to grant or guardrail users' access. The migration to these two options is automated, but you should check your subscription policies before the upgrade to ensure you understand the impact.

## Upgrade Immuta

1. [**Add the Onboarding service**](#onboarding-service) to your `immuta-values.yaml` file. This value is required and must be set to use the same database as `secure.postgresql.database`.

   <pre class="language-yaml" data-expandable="true"><code class="lang-yaml">secure:
     postgresql:
       database: immuta
       ssl: true

   onboarding:
     postgresql:
       database: immuta
   </code></pre>

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><strong>If you store database credentials in a Kubernetes secret</strong> (<code>secure.existingSecret.name</code>), you must also add an <code>ONBOARDING_DATABASE_URL</code> key to that secret and set <code>onboarding.existingSecret</code>. Otherwise, the upgrade fails with <code>onboarding.postgresql.password is required</code>. See the <a href="#existing-kubernetes-secrets">Existing Kubernetes secrets section</a> for more details.</p></div>
2. [Set the **new tenant ID**](#tenant-id) as a UUID under `global.tenantId` in `immuta-values.yaml`:

   ```yaml
   global:
     tenantId: <NEW_UUID>
   ```
3. [Set your **OpenSearch cluster index names**](#opensearch-index-names) under `audit.config.searchIndexName` and `audit.config.searchIndexAliasName` in `immuta-values.yaml`:

   ```yaml
   audit:
     config:
       searchIndexName: <INDEX-NAME>
       searchIndexAliasName: <INDEX-ALIAS>
   ```
4. [Migrate **`secure.ingress` Helm values** **to `gateway.ingress`**](#ingress-migration) , [check the impact of the **guardrail policy upgrade**](#guardrail-subscription-policies), and [upgrade Immuta](#user-content-fn-1)[^1] using one of the methods below.

<details>

<summary><strong>Method A: Zero load-balancer impact (recommended)</strong></summary>

{% hint style="danger" %}
Upgrading with a migrated values file WITHOUT the keep annotation deletes the ingress resource and the load balancer, and there is no self-service recovery without DNS control.
{% endhint %}

Your load balancer is bound to your ingress resource. This migration method keeps that resource across the upgrade and only changes what it points at.

{% hint style="warning" %}
The `keep` annotation only works through values plus a Helm upgrade. Annotating the live object with `kubectl` does not work.
{% endhint %}

1. Edit the `immuta-values.yaml` file and mark this ingress to be kept by adding `helm.sh/resource-policy: "keep"` to `secure.ingress.annotations`. For example,

   <pre class="language-yaml" data-expandable="true"><code class="lang-yaml">secure:
     ingress:
       enabled: true
       hostname: &#x3C;immuta-fqdn>
       ingressClassName: nginx
       annotations:
         nginx.ingress.kubernetes.io/proxy-body-size: '64m'
         helm.sh/resource-policy: "keep"
   </code></pre>
2. Run a same-version upgrade. Replace the content in angle brackets with your release name and the version of Immuta you're currently on (not the one you will upgrade to), respectively.

   <pre data-expandable="true"><code>helm upgrade &#x3C;release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version &#x3C;your-current-immuta-version>
   </code></pre>
3. Edit your `immuta-values.yaml` file and remove `secure.ingress` (or set `secure.ingress: null`) and set `gateway.ingress.enabled: false`.

   <pre class="language-yaml" data-expandable="true"><code class="lang-yaml">gateway:
     ingress:
       enabled: false
   </code></pre>
4. Run an impact assessment for the [guardrail policy migration](#guardrail-subscription-policies) to get a list of data sources that fall into one of the two outlined [policy migration scenarios](#policy-migration-scenarios). The access criteria for any data sources listed under **Scenario 2 (ACCESS CHANGES)** in the report has become less restrictive, potentially leading to more users getting subscribed to those data sources after the upgrade. Determine whether to accept those changes or adjust those policies to be **always required** before upgrading Immuta. For guidance, see the [second policy migration scenario](#migration-scenario-2-always-required-and-shared-responsibility-policies-applied-to-a-data-source).\
   \
   The sequence of commands below does not upgrade Immuta or run the full Helm chart; it only runs the temporary Kubernetes Job that generates a list of data sources affected by the guardrail policy migration and then deletes the Job.

   <pre data-expandable="true"><code>helm template immuta oci://ocir.immuta.com/stable/immuta-enterprise --version 2026.2.2 -n &#x3C;ns> -f immuta-values.yaml \
     --show-only charts/secure/templates/guardrail-report-job.yaml | kubectl -n &#x3C;ns> apply -f -
   kubectl -n &#x3C;ns> wait --for=condition=complete job/immuta-secure-guardrail-report --timeout=5m
   kubectl -n &#x3C;ns> logs job/immuta-secure-guardrail-report
   kubectl -n &#x3C;ns> delete job immuta-secure-guardrail-report
   </code></pre>
5. Upgrade to 2026.2. The kept ingress will be skipped, not deleted. During the migration, audit history queries are slower and audit writes pause for a few minutes. Do not interrupt the command, and do not run it a second time while the first is still running.

   1. Replace the content in angle brackets with your release name.
   2. Set a Helm timeout. The upgrade rebuilds indexes on the `auditrecord` table, and on a large table this takes longer than Helm’s default 5 minutes. If this default is not adjusted, when Helm times out it will mark the release as failed while the migration keeps running. [Budget about 30 minutes for every 100 million rows in `bometadata.auditrecord` and pass it as `--timeout`.](#user-content-fn-2)[^2]

   <pre data-expandable="true"><code>helm upgrade &#x3C;release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2 --timeout 3h
   </code></pre>
6. Verify the pods are running and jobs are complete.

   <pre data-expandable="true"><code>kubectl -n &#x3C;ns> get pods                       # all Running / Completed
   kubectl -n &#x3C;ns> get jobs                       # all Complete, incl. onboarding-db-migrator and temporal-cleanup
   kubectl -n &#x3C;ns> get ingress                    # &#x3C;release>-secure still present
   kubectl -n &#x3C;ns> get deploy &#x3C;release>-gateway   # 1/1 ready
   </code></pre>
7. Cut over the kept ingress backend to `<release>-gateway`, port `8000`. Expect up to about 10 seconds of HTTP 503 at the cutover. The kept ingress will be unmanaged by Helm.

   <pre data-expandable="true"><code>kubectl -n &#x3C;ns> patch ingress &#x3C;release>-secure --type=json -p '[
     {"op":"replace","path":"/spec/rules/0/http/paths/0/backend/service/name","value":"&#x3C;release>-gateway"},
     {"op":"replace","path":"/spec/rules/0/http/paths/0/backend/service/port","value":{"number":8000}}
   ]'
   </code></pre>
8. Confirm that traffic transits the gateway.

   <pre data-expandable="true"><code>kubectl -n &#x3C;ns> logs deploy/&#x3C;release>-gateway --since=1m | grep -c DownstreamStatus
   </code></pre>

The ingress is now **unmanaged by Helm** and will keep working indefinitely; future `helm upgrade` runs will not affect it. If you later want a chart-managed ingress, complete the steps outlined in [Method B](#method-b-chart-managed-ingress-requires-dns-control) at any time.

</details>

<details>

<summary><strong>Method B: Chart-managed ingress (requires DNS control)</strong></summary>

1. Edit the `immuta-values.yaml` file and mark this ingress to be kept by adding `helm.sh/resource-policy: "keep"` to `secure.ingress.annotations`. For example,

   <pre class="language-yaml" data-expandable="true"><code class="lang-yaml">secure:
     ingress:
       enabled: true
       hostname: &#x3C;immuta-fqdn>
       ingressClassName: nginx
       annotations:
         nginx.ingress.kubernetes.io/proxy-body-size: '64m'
         helm.sh/resource-policy: "keep"
   </code></pre>
2. Run a same-version upgrade. Replace the content in angle brackets with your release name and the version of Immuta you're currently on (not the one you will upgrade to), respectively.

   <pre data-expandable="true"><code>helm upgrade &#x3C;release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version &#x3C;your-current-immuta-version>
   </code></pre>
3. Edit the `immuta-values.yaml` file and move the `secure.ingress` values to `gateway.ingress`. See the [Ingress configuration guide](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration) for instructions specific to your ingress controller. For example,

   <pre class="language-yaml" data-expandable="true"><code class="lang-yaml">gateway:
     ingress:
       enabled: true
       hostname: immuta.example.com
       ingressClassName: alb
       annotations: { ...your ALB annotations, cert ARN, etc... }
   </code></pre>
4. Run an impact assessment for the [guardrail policy migration](#guardrail-subscription-policies) to get a list of data sources that fall into one of the two outlined [policy migration scenarios](#policy-migration-scenarios). The access criteria for any data sources listed under **Scenario 2 (ACCESS CHANGES)** in the report has become less restrictive, potentially leading to more users getting subscribed to those data sources after the upgrade. Determine whether to accept those changes or adjust those policies to be **always required** before upgrading Immuta. For guidance, see the [second policy migration scenario](#migration-scenario-2-always-required-and-shared-responsibility-policies-applied-to-a-data-source).\
   \
   The sequence of commands below does not upgrade Immuta or run the full Helm chart; it only runs the temporary Kubernetes Job that generates a list of data sources affected by the guardrail policy migration and then deletes the Job.

   <pre data-expandable="true"><code>helm template immuta oci://ocir.immuta.com/stable/immuta-enterprise --version 2026.2.2 -n &#x3C;ns> -f immuta-values.yaml \
     --show-only charts/secure/templates/guardrail-report-job.yaml | kubectl -n &#x3C;ns> apply -f -
   kubectl -n &#x3C;ns> wait --for=condition=complete job/immuta-secure-guardrail-report --timeout=5m
   kubectl -n &#x3C;ns> logs job/immuta-secure-guardrail-report
   kubectl -n &#x3C;ns> delete job immuta-secure-guardrail-report
   </code></pre>
5. Upgrade to 2026.2. A **second** load balancer is provisioned for the new `<release>-gateway` ingress while the old one keeps serving. During the migration, audit history queries are slower and audit writes pause for a few minutes. Do not interrupt the command, and do not run it a second time while the first is still running.

   1. Replace the content in angle brackets with your release name.
   2. Set a Helm timeout. The upgrade rebuilds indexes on the `auditrecord` table, and on a large table this takes longer than Helm’s default 5 minutes. If this default is not adjusted, when Helm times out it will mark the release as failed while the migration keeps running. [Budget about 30 minutes for every 100 million rows in `bometadata.auditrecord` and pass it as `--timeout`.](#user-content-fn-2)[^2]

   <pre data-expandable="true"><code>helm upgrade &#x3C;release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2 --timeout 3h
   </code></pre>
6. Validate the new load balancer directly by its DNS name, and then flip your DNS record (lower TTL beforehand). Both load balancers serve during the transition; rollback is a DNS flip.
7. Delete the kept legacy ingress.

{% hint style="warning" %}
If external-dns manages records by ingress hostname, two ingresses claiming the same host will fight. Use a temporary hostname for validation or an external-dns exclusion annotation until the flip.
{% endhint %}

</details>

<details>

<summary><strong>Method C: Not using the Helm chart's ingress</strong></summary>

OpenShift routes and external load balancers targeting the `<release>-secure` service keep working.

1. Re-point the backend to `<release>-gateway:8000`, as the gateway strips the `immuta-service-id` header from external requests and is the trust boundary for machine-to-machine auth.
2. Run an impact assessment for the [guardrail policy migration](#guardrail-subscription-policies) to get a list of data sources that fall into one of the two outlined [policy migration scenarios](#policy-migration-scenarios). The access criteria for any data sources listed under **Scenario 2 (ACCESS CHANGES)** in the report has become less restrictive, potentially leading to more users getting subscribed to those data sources after the upgrade. Determine whether to accept those changes or adjust those policies to be **always required** before upgrading Immuta. For guidance, see the [second policy migration scenario](#migration-scenario-2-always-required-and-shared-responsibility-policies-applied-to-a-data-source).\
   \
   The sequence of commands below does not upgrade Immuta or run the full Helm chart; it only runs the temporary Kubernetes Job that generates a list of data sources affected by the guardrail policy migration and then deletes the Job.

   <pre data-expandable="true"><code>helm template immuta oci://ocir.immuta.com/stable/immuta-enterprise --version 2026.2.2 -n &#x3C;ns> -f immuta-values.yaml \
     --show-only charts/secure/templates/guardrail-report-job.yaml | kubectl -n &#x3C;ns> apply -f -
   kubectl -n &#x3C;ns> wait --for=condition=complete job/immuta-secure-guardrail-report --timeout=5m
   kubectl -n &#x3C;ns> logs job/immuta-secure-guardrail-report
   kubectl -n &#x3C;ns> delete job immuta-secure-guardrail-report
   </code></pre>
3. Upgrade Immuta to the latest release. During the migration, audit history queries are slower and audit writes pause for a few minutes. Do not interrupt the command, and do not run it a second time while the first is still running.

   1. Replace the content in angle brackets with your release name.
   2. Set a Helm timeout. The upgrade rebuilds indexes on the `auditrecord` table, and on a large table this takes longer than Helm’s default 5 minutes. If this default is not adjusted, when Helm times out it will mark the release as failed while the migration keeps running. [Budget about 30 minutes for every 100 million rows in `bometadata.auditrecord` and pass it as `--timeout`.](#user-content-fn-2)[^2]

   ```sh
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2 --timeout 3h
   ```

</details>

If you encounter an upgrade failure, see the [Troubleshooting page](/2026.2/configuration/self-managed-deployment/troubleshooting#upgrade-failure) for a list of error messages and remediation steps.

## Changes introduced in 2026.2 that require action before upgrading

This section describes changes that require action before you upgrade Immuta. For a full list of new features and behavior changes, see the [2026.2 release notes](/2026.2/releases/releases/index).

### Helm chart changes

#### Ingress migration

{% hint style="danger" %}
Upgrading with a migrated values file WITHOUT the keep annotation deletes the ingress resource and the load balancer, and there is no self-service recovery without DNS control. See the [Method A migration instructions](#method-a-zero-load-balancer-impact-recommended) for guidance.
{% endhint %}

The ingress configuration values that were previously in `secure.ingress` in the `immuta-values.yaml` file have moved to `gateway.ingress`.

The snippets below show a sample comparison of the 2026.1 ingress configuration and the 2026.2 ingress configuration.

{% columns %}
{% column %}
**2026.1 Helm values**

{% code expandable="true" %}

```yaml
secure:
  postgresql:
    database: immuta
    ssl: true
  ingress:
    enabled: true
    hostname: <immuta-fqdn>
    annotations:
      # Determines which type of load balancer is provisioned
      #   gce-internal
      #   gce
      kubernetes.io/ingress.class: gce
      # Listen on both 80 and 443
      kubernetes.io/ingress.allow-http: 'true'
      # Redirect traffic from 80 to 443
      cloud.google.com/frontend-config: immuta
```

{% endcode %}
{% endcolumn %}

{% column %}
**2026.2 Helm values**

{% code expandable="true" %}

```yaml
secure:
  postgresql:
    database: immuta
    ssl: true
gateway:
  ingress:
    enabled: true
    hostname: <immuta-fqdn>
    annotations:
      # Determines which type of load balancer is provisioned
      #   gce-internal
      #   gce
      kubernetes.io/ingress.class: gce
      # Listen on both 80 and 443
      kubernetes.io/ingress.allow-http: 'true'
      # Redirect traffic from 80 to 443
      cloud.google.com/frontend-config: immuta
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

The Helm chart will not upgrade if `secure.ingress` is still present; however, removing that content without following one of the migration methods linked below will delete your ingress resource and load balancer irrevocably. In order to upgrade Immuta, use one of the following methods detailed in the upgrade Immuta section to migrate ingress:

* [**Method A: Zero load-balancer impact (recommended)**](#method-a-zero-load-balancer-impact-recommended)**:** This migration method keeps the ingress resource across the upgrade and only changes what it points at.
* [**Method B: Chart-managed ingress (requires DNS control)**](#method-b-chart-managed-ingress-requires-dns-control)**:** You can use this method if your team controls DNS and load-balancer provisioning directly. This method gets you a fully chart-managed ingress at the cost of one planned DNS cutover.
* [**Method C: Not using the Helm chart's ingress**](#method-c-not-using-the-helm-charts-ingress)**:** Use this method if you do not use the Helm chart's ingress and instead use OpenShift or a corporate load balancer pointed at the secure service. This method has minimal impact, but includes one recommended follow-up.

#### Onboarding service

2026.2 introduces the Onboarding service. The Helm value `onboarding.postgresql.database` is required and must be set to use the same database as `secure.postgresql.database`, not a new database. The upgrade will fail without it. See the [upgrade Immuta section](#upgrade-immuta) for instructions.

{% columns %}
{% column %}
**2026.1 Helm values**

{% code expandable="true" %}

```yaml
secure:
  postgresql:
    database: immuta
    ssl: true
```

{% endcode %}
{% endcolumn %}

{% column %}
**2026.2 Helm values**

{% code expandable="true" %}

```yaml
secure:
  postgresql:
    database: immuta
    ssl: true

onboarding:
  postgresql:
    database: immuta
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

**Existing Kubernetes secrets**

If your values file references database credentials in an existing Kubernetes secret with `secure.existingSecret.name`, the chart cannot build the Onboarding database connection string for you. Complete these steps before you upgrade:

1. Add an `ONBOARDING_DATABASE_URL` key to the secret, using the process you normally use to manage it. Use the same user, host, and database that Secure uses, and URL-encode any special characters in the password (for example, `@` becomes `%40` and `%` becomes `%25`).

   ```
   postgres://<user>:<url-encoded-password>@<postgres-fqdn>:5432/<database>?schema=onboarding
   ```
2. Set `onboarding.existingSecret` to the secret's name. This value takes the name as a string, unlike `secure.existingSecret.name`.

   ```yaml
   secure:
     existingSecret:
       name: immuta-secret

   onboarding:
     existingSecret: immuta-secret
     postgresql:
       database: immuta
   ```

{% hint style="info" %}
Secure's web and background worker pods also read `ONBOARDING_DATABASE_URL` from `secure.existingSecret` in 2026.2. If the key is missing, those pods fail to start with `couldn't find key ONBOARDING_DATABASE_URL in Secret`, so add the key even if you configure Onboarding another way.
{% endhint %}

The Onboarding migrator creates an `onboarding` schema inside the existing database, so the database user must be able to create a schema there.

#### Tenant ID

This section applies to self-managed deployments with `audit-service` enabled.

As part of the upgrade to 2026.2, update the audit tenant ID in the Helm values and the configuration used to send events to `audit-service`. The tenant ID must be a UUID. It will identify your audit history and must stay the same for future upgrades.

#### OpenSearch index names

This section applies to self-managed deployments with `audit-service` enabled.

**Before you begin**

Confirm that the OpenSearch user has the `indices:data/write/update/byquery` permission for the audit index. This is a new [permission requirement](/2026.2/configuration/self-managed-deployment/deployment-requirements#opensearch-user) for 2026.2.

**Find your OpenSearch index names**

Run the following report on your current deployment, before upgrading:

```sh
helm template <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --version 2026.2.2 -n <namespace> -f immuta-values.yaml \
  --show-only charts/audit/templates/search-index-report-job.yaml | kubectl -n <namespace> apply -f -
kubectl -n <namespace> wait --for=condition=complete job/<release-name>-audit-search-index-report --timeout=5m
kubectl -n <namespace> logs job/<release-name>-audit-search-index-report
kubectl -n <namespace> delete job <release-name>-audit-search-index-report
```

This report reads your search cluster through the audit service’s own credentials, changes nothing, and prints the values to set when upgrading.

**Output example**:

```yaml
[SEARCH-INDEX-REPORT] Existing audit index for tenant <id>: <index> (alias <alias>). Add to your values file:
audit:
  config:
    searchIndexName: <index>
    searchIndexAliasName: <alias>
```

Use those names in the `immuta-values.yaml` file when [upgrading Immuta](#upgrade-immuta).

### Guardrail subscription policies

[Guardrail subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies#guardrail-subscription-policy) prevent users from gaining access to data unless they meet specific conditions. For some customers, moving to this new feature entails an automated migration of existing subscription policy logic. Subscription policies that use the **shared responsibility** option become grant policies. Subscription policies that use the **always required** option also become grant policies, and the migration creates a matching guardrail policy only when the always required policy is merged with another subscription policy on at least one data source. See the [policy migration scenarios](#policy-migration-scenarios) for details.

| Before upgrade                                                            | After upgrade                       |
| ------------------------------------------------------------------------- | ----------------------------------- |
| Always required, merged with another subscription policy on a data source | Grant policy and a guardrail policy |
| Always required, not merged with another subscription policy              | Grant policy (no guardrail policy)  |
| Shared responsibility                                                     | Grant policy                        |

When migrating always required to guardrail subscription policies, there is one key difference in behavior: An always required policy would still subscribe users, but a guardrail policy will not; instead, guardrail policies ensure that users only get access to data if they are part of the eligible set of users, but no user will be actually subscribed unless there is also at least one grant policy targeting the data source. The table below illustrates this behavior with a policy example.

<table><thead><tr><th width="118.51953125"></th><th>Before upgrade (always required policy)</th><th>After upgrade (guardrail policy)</th></tr></thead><tbody><tr><td><strong>Policy</strong></td><td>Subscribe users when user is a member of group <code>Finance</code> on all data sources tagged sales.</td><td>Prevent users from gaining access unless user is a member of group <code>Finance</code> on all data sources tagged sales.</td></tr><tr><td><strong>Result</strong></td><td>Everyone from <code>Finance</code> gets subscribed</td><td>Nobody gets subscribed, but if there is any grant policy trying to give access to someone that is not in <code>Finance</code>, those users will be blocked</td></tr></tbody></table>

Before you upgrade Immuta to 2026.2, [run an impact assessment by following the steps in the upgrade Immuta section](#upgrade-immuta) to identify what data sources have subscription policies applied to them that will be affected by the upgrade.

#### Policy migration scenarios

Click below to expand explanations of the migration scenarios so that you understand policies that will be created in your tenant and how they will affect users' access.

<details>

<summary>Migration Scenario 1: Multiple always required policies applied to a data source</summary>

This scenario applies to any data source that has multiple always required policies applied to them. The table below outlines the migration logic.

|                         | Before upgrade                                                                                                                                                                                                                                                                                                                 | After upgrade                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Policies**            | <ul><li>Policy 1 (always required): Subscribe users when user is a member of group <code>Finance</code></li><li>Policy 2 (always required): Subscribe users when user is a member of group <code>Marketing</code></li><li>Policy 3 (always required): Subscribe users when user is a member of group <code>HR</code></li></ul> | <ul><li>Policy 1 (grant policy): Subscribe users when user is a member of group <code>Finance</code></li><li>Policy 1.1 (guardrail policy): Prevent users from gaining access unless user is a member of group <code>Finance</code></li><li>Policy 2 (grant policy): Subscribe users when user is a member of group <code>Marketing</code></li><li>Policy 2.1 (guardrail policy): Prevent users from gaining access unless user is a member of group <code>Marketing</code></li><li>Policy 3 (grant policy): Subscribe users when user is a member of group <code>HR</code></li><li>Policy 3.1 (guardrail policy): Prevent users from gaining access unless user is a member of group <code>HR</code></li></ul> |
| **Merged policy logic** | <p>Users will be subscribed to the data source</p><p>when they are member of group <code>Finance</code> AND <code>Marketing</code> AND <code>HR</code>.</p><p><br></p>                                                                                                                                                         | <p>Users will be subscribed to the data source when they are (a member of group <code>Finance</code> OR <code>Marketing</code> OR <code>HR</code>)</p><p>AND</p><p>(a member of group <code>Finance</code> AND <code>Marketing</code> AND <code>HR</code>).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

In this scenario, the final access criteria **remains the same**: A user will not get subscribed to this data source unless they are a member of all the three required groups. However, in order for nobody to lose access, the migration turns each always required policy into two policies — one grant policy and one corresponding guardrail policy — ultimately resulting in a higher number of policies than before the upgrade.

</details>

<details>

<summary>Migration Scenario 2: Always required and shared responsibility policies applied to a data source</summary>

This scenario applies to any data source that has exactly one shared responsibility and one or more always required policies applied. The table below outlines the migration logic.

|                         | Before upgrade                                                                                                                                                                                                                      | After upgrade                                                                                                                                                                                                                                                                                                                                                |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Policies**            | <ul><li>Policy 1 (shared responsibility): Subscribe users when user is a member of group <code>Sales</code></li><li>Policy 2 (always required): Subscribe users when user is a member of group <code>Manufacturing</code></li></ul> | <ul><li>Policy 1 (grant policy): Subscribe users when user is a member of group <code>Sales</code></li><li>Policy 2 (grant policy): Subscribe users when user is a member of group <code>Manufacturing</code></li><li>Policy 2.1 (guardrail policy): Prevent users from gaining access unless user is a member of group <code>Manufacturing</code></li></ul> |
| **Merged policy logic** | <p>Users will be subscribed they are a member of group <code>Sales</code> AND <code>Manufacturing</code>.</p><p>In this example, the policies are combined with AND because there is an always required policy in play.</p>         | Users will be subscribed to this data source when they are (a member of group `Sales` OR `Manufacturing`) AND (a member of group `Manufacturing`).                                                                                                                                                                                                           |

In this scenario, the final access criteria **does not remain the same**: A user will now get subscribed to this data source as long as they are a member of group `Manufacturing`; being a member of group `Sales` is no longer a hard requirement. The access criteria for this data source has become less restrictive, potentially leading to more users getting subscribed to this data source after the upgrade.

Given that this scenario leads to a change in access, you have the following options:

1. Do nothing and accept the change in behavior for affected data sources
2. Change the shared responsibility policy into an always required policy, which will turn the data source into a [scenario 1 migration case](#migration-scenario-1-multiple-always-required-policies-applied-to-a-data-source) instead.

Contact your Immuta representative if you would like receive guidance in making the right decision for your case.

</details>

<details>

<summary>Migration Scenario 3: Always required policy not merged with another subscription policy</summary>

This scenario applies to any always required policy that is not merged with another subscription policy on a data source. This includes always required policies that apply to no data sources and always required policies that are the only subscription policy on the data sources they apply to. The table below outlines the migration logic.

|                         | Before upgrade                                                                       | After upgrade                                                                      |
| ----------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| **Policies**            | Policy 1 (always required): Subscribe users when user is a member of group `Finance` | Policy 1 (grant policy): Subscribe users when user is a member of group `Finance`  |
| **Merged policy logic** | Users are subscribed to the data source when they are a member of group `Finance`.   | Users are subscribed to the data source when they are a member of group `Finance`. |

In this scenario, the final access criteria **remains the same**. The always required option only affects how a policy combines with other subscription policies on a data source, so the migration converts the policy to a grant policy and does not create a guardrail policy.

After the upgrade, if another grant policy applies to the same data source, the two grant policies combine with OR. To keep a condition mandatory on a data source, create a [guardrail policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies#guardrail-subscription-policy) with that condition.

</details>

#### API changes

Once the guardrail feature is enabled, the Immuta system will automatically handle the `shareResponsibility` parameter in [subscription policy payloads](/2026.2/developer-guides/api-intro/immuta-v1-api/manage-data-access/policy#request-example).

The system enforces the following rules:

* `"subscriptionType": "policy"` always equals `"shareResponsibility": true`
* `"subscriptionType": "guardrail"` always equals `"shareResponsibility": false`

This ensures backwards compatibility so that you can continue sending your existing policy payloads. However, user-provided values for the `shareResponsibility` parameter will be ignored, as they are now implicitly defined as part of the `subscriptionType`. See the below table for a summary of the behavior change.

| Policy payload                                                                                   | System behavior                                                                                  |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| <p><code>"subscriptionType": "policy"</code><br><code>"shareResponsibility": true</code></p>     | <p><code>"subscriptionType": "policy"</code><br><code>"shareResponsibility": true</code></p>     |
| <p><code>"subscriptionType": "policy"</code><br><code>"shareResponsibility": false</code></p>    | <p><code>"subscriptionType": "policy"</code><br><code>"shareResponsibility": true</code></p>     |
| <p><code>"subscriptionType": "guardrail"</code><br><code>"shareResponsibility": true</code></p>  | <p><code>"subscriptionType": "guardrail"</code><br><code>"shareResponsibility": false</code></p> |
| <p><code>"subscriptionType": "guardrail"</code><br><code>"shareResponsibility": false</code></p> | <p><code>"subscriptionType": "guardrail"</code><br><code>"shareResponsibility": false</code></p> |

### Connections

{% hint style="info" %}
With connections enabled, some API endpoints will be blocked. Please see the [API changes page](/2026.2/configuration/self-managed-deployment/upgrade-immuta/api-changes) for details about API endpoints that will become unavaible for Snowflake, Databricks Unity Catalog, and Starburst (Trino) integrations after you upgrade to 2026.2.
{% endhint %}

After you complete the upgrade to 2026.2, connections will be enabled by default and you will see a banner to upgrade your integrations to connections. [Follow the steps in the UI to complete the upgrade](/2026.2/configuration/integrations/registering-metadata/connections/how-to-guides/use-the-connection-upgrade-manager).

[^1]: Upgrades from 2025.1 can leave behind an orphaned Temporal schedule that floods the Temporal logs with `pq: syntax error in tsvector` errors. A post-upgrade job removes the orphaned schedule automatically during the upgrade; no action is required.

[^2]: If you do not know the row count, ask your database administrator to run `SELECT count(*) FROM bometadata.auditrecord`.


# Connection API Changes

When upgrading to 2026.2, all Snowflake, Databricks Unity Catalog, and Starburst (Trino) integrations will be immediately available to upgrade to connections. This will have some instant API changes and other changes that happen after the upgrade to connections is complete. Please see the tables below for all impacted endpoints.

## Deprecated endpoints

The following endpoints have been deprecated with connections. Use the recommended endpoint instead.

<table><thead><tr><th width="187">Action</th><th width="192">Deprecated endpoint</th><th>Use this with connections instead</th></tr></thead><tbody><tr><td>Create a single data source</td><td><ul><li><a data-footnote-ref href="#user-content-fn-1"><code>POST /{technology}/handler</code></a></li><li><a data-footnote-ref href="#user-content-fn-1"><code>POST /api/v2/data</code></a></li></ul></td><td><p>Step 1: Ensure your system user has been granted access to the relevant object in the data platform.</p><p></p><p>Step 2: Wait until the next object sync or manually trigger a metadata crawl using <a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#post-api-connections-connectionkey-tasks"><code>POST /api/connections/{connectionKey}/tasks</code></a> with type <code>DATA_OBJECT_SYNC</code> in the payload.<br></p><p>Step 3: If the parent schema has <code>activateNewChildren: false</code>, use </p><p><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: true</code>.</p></td></tr><tr><td>Bulk create data sources</td><td><ul><li><a data-footnote-ref href="#user-content-fn-1"><code>POST /{technology}/handler</code></a></li><li><a data-footnote-ref href="#user-content-fn-1"><code>POST /api/v2/data</code></a></li></ul></td><td><p>Step 1: Ensure your system user has been granted access to the relevant object in the data platform.</p><p></p><p>Step 2: Wait until the next object sync or manually trigger a metadata crawl using <a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#post-api-connections-connectionkey-tasks"><code>POST /api/connections/{connectionKey}/tasks</code></a> with type <code>DATA_OBJECT_SYNC</code> in the payload.<br></p><p>Step 3: If the parent schema has <code>activateNewChildren: false</code>, use </p><p><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: true</code>.</p></td></tr><tr><td>Edit a data source connection</td><td><a data-footnote-ref href="#user-content-fn-2"><code>POST /api/v2/data</code></a></td><td>No substitute. Data sources no longer have their own separate connection details but are tied to the parent connection.</td></tr><tr><td>Bulk edit data source's connections</td><td><ul><li><a data-footnote-ref href="#user-content-fn-2"><code>PUT /{technology}/bulk</code></a></li><li><a data-footnote-ref href="#user-content-fn-2"><code>POST /api/v2/data</code></a></li><li><a data-footnote-ref href="#user-content-fn-2"><code>PUT /{technology}/handler/{handlerId}</code></a></li></ul></td><td>No substitute. Data sources no longer have their own separate connection details but are tied to the parent connection.</td></tr><tr><td>Run schema detection (object sync)</td><td><a data-footnote-ref href="#user-content-fn-2"><code>PUT /dataSource/detectRemoteChanges</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#post-api-connections-connectionkey-tasks"><code>POST /api/connections/{connectionKey}/tasks</code></a> with type <code>DATA_OBJECT_SYNC</code> in the payload</td></tr><tr><td>Delete a data source</td><td><a data-footnote-ref href="#user-content-fn-2"><code>DELETE /dataSource/{dataSourceId}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#delete-api-connections-connectionkey-dataobjects-id"><code>DELETE /api/connections/{connectionKey}/dataObjects/{id}</code></a></td></tr><tr><td>Bulk delete data sources</td><td><ul><li><a data-footnote-ref href="#user-content-fn-2"><code>PUT /dataSource/bulk/{delete}</code></a></li><li><a data-footnote-ref href="#user-content-fn-2"><code>DELETE /api/v2/data/{connectionKey}</code></a></li><li><a data-footnote-ref href="#user-content-fn-2"><code>DELETE /{technology}/handler/{handlerId}</code></a></li><li><a data-footnote-ref href="#user-content-fn-2"><code>DELETE /dataSource/{dataSourceId}</code></a></li></ul></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#delete-api-connections-connectionkey-dataobjects-id"><code>DELETE /api/connections/{connectionKey}/dataObjects/{id}</code></a></td></tr><tr><td>Enable a single data source</td><td><a data-footnote-ref href="#user-content-fn-3"><code>PUT /dataSource/{dataSourceId}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: true</code></td></tr><tr><td>Bulk enable data sources</td><td><a data-footnote-ref href="#user-content-fn-2"><code>PUT /dataSource/bulk/{restore}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: true</code></td></tr><tr><td>Disable a single data source</td><td><a data-footnote-ref href="#user-content-fn-3"><code>PUT /dataSource/{dataSourceId}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: false</code></td></tr><tr><td>Bulk disable data sources</td><td><a data-footnote-ref href="#user-content-fn-2"><code>PUT /dataSource/bulk/{disable}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: syncPolicy: false</code></td></tr><tr><td>Edit a data source name</td><td><a data-footnote-ref href="#user-content-fn-4"><code>PUT /dataSource/{dataSourceId}</code></a></td><td>No substitute. Data source names are automatically generated based on information from your data platform.</td></tr><tr><td>Edit a display name</td><td><a data-footnote-ref href="#user-content-fn-5"><code>POST /api/v2/data/{connectionKey}</code></a></td><td>No substitute. Data sources no longer have their own separate connection details but are tied to the parent connection.</td></tr><tr><td>Override a host name</td><td><a data-footnote-ref href="#user-content-fn-2"><code>PUT /dataSource/{dataSourceId}/overrideHost</code></a></td><td>No substitute. Data sources no longer have their own separate connection details but are tied to the parent connection.</td></tr><tr><td>Create an integration/connection</td><td><a data-footnote-ref href="#user-content-fn-6"><code>POST /integrations</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#post-api-connections"><code>POST /api/connections</code></a></td></tr><tr><td>Update an integration/connection</td><td><a data-footnote-ref href="#user-content-fn-7"><code>PUT /integrations/{integrationId}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey"><code>PATCH /api/connections/{connectionKey}</code></a></td></tr><tr><td>Delete an integration/connection</td><td><a data-footnote-ref href="#user-content-fn-8"><code>DELETE /integrations/{integrationId}</code></a></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#delete-api-connections-connectionkey"><code>DELETE /api/connections/{connectionKey}</code></a></td></tr><tr><td>Delete and update data source columns</td><td><ul><li><a data-footnote-ref href="#user-content-fn-2"><code>DELETE /dictionary/{dataSourceId}</code></a></li><li><a data-footnote-ref href="#user-content-fn-5"><code>POST /dictionary/{dataSourceId}</code></a></li><li><code>PUT</code> <a data-footnote-ref href="#user-content-fn-2"><code>/dictionary/{dataSourceId}</code></a></li></ul></td><td>No substitute. Data source columns are automatically generated based on information from your data platform.</td></tr><tr><td>Update a data source owner</td><td><ul><li><a data-footnote-ref href="#user-content-fn-9"><code>PUT /dataSource/{dataSourceId}/access/{id}</code></a></li><li><a data-footnote-ref href="#user-content-fn-9"><code>DELETE /dataSource/{dataSourceId}/unsubscribe</code></a></li></ul></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: owners</code></td></tr><tr><td>Response to a data source owner request</td><td><ul><li><a data-footnote-ref href="#user-content-fn-9"><code>POST /subscription/deny</code></a></li><li><a data-footnote-ref href="#user-content-fn-9"><code>POST /subscription/deny/bulk</code></a></li></ul></td><td><a href="/2026.2/developer-guides/api-intro/connections-api/connections-api#patch-api-connections-connectionkey-dataobjects-id"><code>PATCH /api/connections/{connectionKey}/dataObjects/{id}</code></a> with <code>settings: owners</code></td></tr></tbody></table>

## Impacted endpoints

If you have any automated actions using the following APIs, ensure you do the required change after the upgrade to ensure they continue working as expected.

| Action                   | Impacted endpoint                                                                                                                                                                                                                                                                                                                                                                                               | Required change                                                                                                                                                                                                                                                                                             |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Search for a data source | <ul><li><a href="https://documentation.immuta.com/saas/developer-guides/api-intro/immuta-v1-api/data-sources/get-data-sources#get-datasourcenamedatasourcename"><code>GET /dataSource/name/{dataSourceName}</code></a></li><li><a href="https://documentation.immuta.com/saas/developer-guides/api-intro/immuta-v1-api/data-sources/get-data-sources#get-datasource"><code>GET /dataSource</code></a></li></ul> | <p></p><ul><li>Data source names will change with the upgrade. Update <code>{dataSourceName}</code> in the request with the new data source name.</li><li>Data source names will change with the upgrade. Update the <code>searchText</code> in the payload with the new data source name.</li></ul>        |
| Search schema names      | [`GET /schemas`](https://documentation.immuta.com/saas/developer-guides/api-intro/immuta-v1-api/manage-data-access/schemas)                                                                                                                                                                                                                                                                                     | This endpoint will not search the schemas of connection data sources. Instead use the [`GET /api/connections/{connectionKey}/dataObjects/{id}`](/2026.2/developer-guides/api-intro/connections-api/connections-api#get-api-connections-connectionkey-dataobjects-id) and search for the schema data object. |

[^1]: Once the upgrade begins, any calls to this endpoint for Snowflake, Databricks Unity Catalog, or Starburst (Trino) will error with a `400`.

[^2]: Once the upgrade begins, any calls to this endpoint for data sources belonging to the Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^3]: Once the upgrade begins, any calls to this endpoint to modify the `deleted` parameter for data sources belonging to the Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^4]: Once the upgrade begins, any calls to this endpoint to modify the `name` parameter for data sources belonging to the Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^5]: Once the upgrade begins, any calls to this endpoint for data sources belonging to the Snowflake,  Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^6]: Once the upgrade begins, any calls to this endpoint for Snowflake, Databricks Unity Catalog, or Starburst (Trino) technologies will error with a `400`.

[^7]: Once the upgrade begins, any calls to this endpoint to update the `connection` parameter for Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^8]: Once the upgrade begins, any calls to this endpoint for Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.

[^9]: Once the upgrade begins, any calls to this endpoint to update data source owners of data sources belonging to the Snowflake, Databricks Unity Catalog, or Starburst (Trino) upgraded connections will error with a `400`.


# Guides

The following guides offer practical guidance for handling common challenges and configurations.

## [Ingress configuration](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration)

Configure [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) to complete your installation and access your Immuta application.

## [TLS configuration](/2026.2/configuration/self-managed-deployment/configure/tls-configuration)

Configure TLS termination for an Ingress resource.

## [Cosign verification](/2026.2/configuration/self-managed-deployment/configure/cosign-verification)

Verify artifacts hosted on the ocir.immuta.com OCI registry.

## [Production best practices](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production)

Follow these best practices when deploying Immuta in your production environment.

## [Rotating credentials](/2026.2/configuration/self-managed-deployment/configure/rotating-credentials)

Update the credentials referenced in the Immuta Enterprise Helm chart.

## [External cache configuration](/2026.2/configuration/self-managed-deployment/configure/external-cache-configuration)

Configure an external key-value cache (such as Redis or Memcached) with the Immuta Enterprise Helm chart.

## [Enabling legacy query engine](/2026.2/configuration/self-managed-deployment/configure/enabling-legacy-query-engine)

Enable this legacy service for your deployment if you are using any of the [legacy data platforms](/2026.2/releases/support-matrix#legacy-databases).

## [Private container registries](/2026.2/configuration/self-managed-deployment/configure/private-container-registries)

Configure pulling images from a private registry.

## [Air-gapped environments](/2026.2/configuration/self-managed-deployment/configure/immuta-in-an-air-gapped-environment)

Tips when installing Immuta without internet access.


# Ingress Configuration

This guide demonstrates how to configure [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). Ingress can be configured in numerous ways. Configurations for the most popular controllers are outlined below.

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the Immuta Enterprise Helm chart was deployed into namespace `immuta` and that the current namespace is `immuta`.
{% endhint %}

The Immuta web service listens on the following ports:

| Port | Protocol | Description               | Optional |
| ---- | -------- | ------------------------- | -------- |
| 443  | TCP      | HTTPS                     | False    |
| 80   | TCP      | HTTP (redirects to HTTPS) | True     |

## [Ingress NGINX Controller](https://kubernetes.github.io/ingress-nginx/)

{% hint style="warning" %}
**Deprecation notice**

Kubernetes is ending support for Ingress NGINX. See the official [Kubernetes announcement](https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/) for details.
{% endhint %}

{% hint style="info" %}
**Ingress hostname**

This is the fully qualified domain name (FQDN) as defined by RFC 3986 used to access the Immuta UI. If a FQDN has yet to be determined set Secure's ingress hostname to `immuta.local`.
{% endhint %}

1. Edit the `immuta-values.yaml` file to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       enabled: true
       hostname: <immuta-fqdn>
       ingressClassName: nginx
       annotations:
         nginx.ingress.kubernetes.io/proxy-body-size: '64m'
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Ingress-Nginx Controller documentation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/) for further assistance.

## [GKE Ingress Controller](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       enabled: true
       hostname: <immuta-fqdn>
       annotations:
         # Determines which type of load balancer is provisioned
         #   gce-internal
         #   gce
         kubernetes.io/ingress.class: gce
         # Listen on both 80 and 443
         kubernetes.io/ingress.allow-http: 'true'
         # Redirect traffic from 80 to 443
         cloud.google.com/frontend-config: immuta
   ```
2. Create a file named `frontendconfig.yaml` with the following content.

   ```yaml
   apiVersion: networking.gke.io/v1beta1
   kind: FrontendConfig
   metadata:
     name: immuta
   spec:
     redirectToHttps:
       enabled: true
       responseCodeName: RESPONSE_CODE
   ```
3. Apply the `FrontendConfig` CRD.

   ```bash
   kubectl apply -f frontendconfig.yaml
   ```
4. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Google Cloud documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress#summary_of_external_ingress_annotations) for further assistance.

## [AWS Load Balancer Controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       enabled: true
       hostname: <immuta-fqdn>
       ingressClassName: alb
       annotations:
         # Determines which type of load balancer is provisioned
         #   internal
         #   internet-facing
         alb.ingress.kubernetes.io/scheme: internet-facing
         alb.ingress.kubernetes.io/target-type: ip
         # Listen on both 80 and 443
         alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
         # Redirect traffic from 80 to 443
         alb.ingress.kubernetes.io/ssl-redirect: '443'
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [AWS Load Balancer Controller documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/) for further assistance.

## [AKS Application Gateway Ingress Controller](https://azure.github.io/application-gateway-kubernetes-ingress/)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       enabled: true
       hostname: <immuta-fqdn>
       ingressClassName: webapprouting.kubernetes.azure.com
       # https://azure.github.io/application-gateway-kubernetes-ingress/annotations/
       annotations:
         appgw.ingress.kubernetes.io/ssl-redirect: 'true'
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Application Gateway Ingress Controller documentation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/) for further assistance.

## [Traefik](https://traefik.io/traefik/)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       enabled: true
       hostname: <immuta-fqdn>
       ingressClassName: traefik
       annotations:
         # Listen on ports 80 and 443
         traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
         # Redirect HTTP to HTTPS
         # When referencing middleware you must prefix the name with its namespace
         # <namespace>-<middleware-name>@kubernetescrd
         traefik.ingress.kubernetes.io/router.middlewares: immuta-https-redirectscheme@kubernetescrd
   ```
2. Create a file named `middleware.yaml` with the following content.

   ```yaml
   apiVersion: traefik.containo.us/v1alpha1
   kind: Middleware
   metadata:
     name: https-redirectscheme
   spec:
     redirectScheme:
       scheme: https
       permanent: true
   ```
3. Apply the `Middleware` CRD.

   ```bash
   kubectl apply -f middleware.yaml
   ```
4. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Traefik documentation](https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress/) for further assistance.

## [OpenShift Ingress Operator](https://docs.redhat.com/en/documentation/openshift_dedicated/4/html/networking_operators/configuring-ingress)

1. Edit `immuta-values.yaml` to include the following Helm values. Because the Ingress resource will be managed by the OpenShift route you create and not the Immuta Enterprise Helm chart, `ingress` is set to `false` below.

   ```yaml
   gateway:
     ingress:
       enabled: false
   ```
2. Get the service name for gateway.

   ```bash
   oc get service --selector "app.kubernetes.io/component=gateway" --output template='{{ .metadata.name }}'
   ```
3. Create a file named `route.yaml` with the following content. Update all [placeholder values](/2026.2/configuration/self-managed-deployment/conventions) with your own values.

   ```yaml
   apiVersion: route.openshift.io/v1
   kind: Route
   metadata:
     name: immuta
   spec:
     host: <immuta-fqdn>
     to:
       kind: Service
       name: gateway
     port:
       targetPort: http
     tls:
       termination: edge
       insecureEdgeTerminationPolicy: Redirect
   ```
4. Apply the `Route` CRD.

   ```bash
   oc apply -f route.yaml
   ```
5. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Red Hat OpenShift documentation](https://docs.redhat.com/en/documentation/openshift_dedicated/4/html/networking_operators/configuring-ingress) for further assistance.


# TLS Configuration

This guide demonstrates how to configure TLS termination for an [Ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/).

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the Immuta Enterprise Helm chart was deployed into namespace `immuta` and that the current namespace is `immuta`.
{% endhint %}

## Prerequisite

The [Ingress configuration](/2026.2/configuration/self-managed-deployment/configure/ingress-configuration) must be completed before proceeding.

## [Ingress-NGINX Controller](https://kubernetes.github.io/ingress-nginx/)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       hostname: <immuta-fqdn>
       annotations:
         nginx.ingress.kubernetes.io/auth-tls-secret: <namespace>/<secret-name>
   ```
2. [Create a TLS secret](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_create/kubectl_create_secret_tls/) from a given public/private PEM formatted key pair.

   ```bash
   kubectl create secret tls <secret-name> --cert=path/to/tls.cert --key=path/to/tls.key
   ```
3. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Ingress-Nginx Controller documentation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#client-certificate-authentication) for further assistance.

## [GKE Ingress Controller](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       hostname: <immuta-fqdn>
       annotations:
         ingress.gcp.kubernetes.io/pre-shared-cert: <certificate-name>
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [GKE Ingress Controller documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs) for further assistance.

## [AWS Load Balancer Controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       hostname: <immuta-fqdn>
       annotations:
         alb.ingress.kubernetes.io/certificate-arn: <certificate-arn>
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [AWS Load Balancer Controller documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/#ssl) for further assistance.

## [AKS Application Gateway Ingress Controller](https://azure.github.io/application-gateway-kubernetes-ingress/)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       hostname: <immuta-fqdn>
       annotations:
         appgw.ingress.kubernetes.io/appgw-ssl-certificate: <certificate-name>
   ```
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Application Gateway Ingress Controller documentation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#appgw-ssl-certificate) for further assistance.

## [Traefik](https://traefik.io/traefik/)

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   gateway:
     ingress:
       annotations:
         traefik.ingress.kubernetes.io/router.tls: "true"
       hostname: <immuta-fqdn>
       tls: true
       # If left unset the TLS secret name defaults to <hostname>-tls
       secretName: <secret-name>
   ```
2. [Create a TLS secret](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_create/kubectl_create_secret_tls/) from a given public/private PEM formatted key pair.

   ```bash
   kubectl create secret tls <secret-name> --cert=path/to/tls.cert --key=path/to/tls.key
   ```
3. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```

Refer to the [Traefik documentation](https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress/#certificates-management) for further assistance.


# Cosign Verification

This guide demonstrates how to verify signed artifacts (i.e., container images, Helm charts) hosted on ocir.immuta.com using [Cosign](https://github.com/sigstore/cosign) from [Sigstore](https://sigstore.dev/).

{% hint style="info" %}
**Cosign installation**

This guide utilizes the `cosign` command to verify artifacts; ensure it's installed before proceeding. Refer to the [Cosign documentation](https://docs.sigstore.dev/cosign/system_config/installation/) for further assistance.
{% endhint %}

## Download public key

The provided key is used to sign the Helm chart and container images.

## Identify container images

A `DIGESTS.md` markdown file comes bundled in the Helm chart and contains a comprehensive list of images and digests referenced. To view the file, follow these steps:

1. Download and extract the Helm chart into the working directory.

   ```shell
   helm pull oci://ocir.immuta.com/stable/immuta-enterprise --destination . --untar --version 2026.2.2
   ```
2. Open file `immuta-enterprise/DIGESTS.md`

## Verify signature

Verify an artifact's signature by referencing Immuta's public key.

```bash
cosign verify --key ./immuta-cosign.pub <image>
```


# Production Best Practices

This guide highlights best practices when deploying Immuta in a production environment.

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the Immuta Enterprise Helm chart was deployed into namespace `immuta` and that the current namespace is `immuta`.
{% endhint %}

## Database sizing recommendations

Provisioning an appropriately resourced PostgreSQL database for Immuta is critical to application performance. The recommendations below are based on the number of data sources registered multiplied (\*) by the number of users on the deployment:

| Size                                | CPU | Memory | Storage    |
| ----------------------------------- | --- | ------ | ---------- |
| Small (data sources \* users <100k) | 2   | 8GB    | 100 GB SSD |
| Normal                              | 4   | 16GB   | 100 GB SSD |
| Large (data sources \* users >1M)   | 8   | 32GB   | 100 GB SSD |

## Elasticsearch/OpenSearch sizing recommendations

This recommendation assumes approximately 1 million events per day with a 90-day data retention policy:

* 2 nodes
* 2 CPUs/node
* 4GB RAM/node
* Storage 100GB SSD/node

## Helm values

Back up or source control your `immuta-values.yaml` Helm values file.

## Kubernetes resource requests and limits

Assign [memory resource limits](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/) to pods.

### Edit Helm values

Edit `immuta-values.yaml` to include the following recommended resource requests and limits for most Immuta deployments.

{% hint style="info" %}
Increase replica count to 3 on `web` and `backgroundWorker` for large deployments.
{% endhint %}

```yaml
audit:
  worker:
    replicaCount: 1
    resources:
      requests:
        cpu: 1000m
        memory: 1024Mi
      limits:
        cpu: 1000m
        memory: 2048Mi  
  deployment:
    replicaCount: 1
    resources:
      requests:
        cpu: 1000m
        memory: 4096Mi
      limits:
        cpu: 3000m
        memory: 8192Mi
secure:
  backgroundWorker:
    replicaCount: 2
    resources:
      requests:
        cpu: 1000m
        memory: 4096Mi
      limits:
        cpu: 4000m
        memory: 4096Mi  
  web:
    replicaCount: 2 
    resources:
      requests:
        cpu: 1000m
        memory: 4096Mi
      limits:
        cpu: 4000m
        memory: 4096Mi
discover:
  deployment:
    replicaCount: 1
    resources:
      requests:
        cpu: 500m
        memory: 4096Mi
      limits:
        cpu: 3000m
        memory: 4096Mi
cache:
  deployment:
    replicaCount: 1
    resources:
      requests:
        cpu: 500m
        memory: 512Mi
      limits:
        cpu: 1000m
        memory: 512Mi
```

## Kubernetes secrets

Use [Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/) in the `immuta-values.yaml` file instead of passwords and tokens. The following section demonstrates how to create a secret and reference it in the Helm values file. For guidance on updating these credentials based on your specific security policies, [refer to the Rotating credentials guide](/2026.2/configuration/self-managed-deployment/configure/rotating-credentials).

### Create secret

1. Create a file named `secret-data.env` with the following content.

   ```bash
   # audit
   ELASTICSEARCH_USERNAME=<elasticsearch-username>
   ELASTICSEARCH_PASSWORD=<elasticsearch-password>

   # PostgreSQL connection string used by audit for the metadata database
   #   postgresql://<user>:<password>@<postgres-fqdn>:5432/<database>?schema=audit
   #
   # More info
   #   https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
   DATABASE_CONNECTION_STRING=postgresql://immuta:<postgres-password>@<postgres-fqdn>:5432/immuta?schema=audit

   # secure
   IMMUTA_DATABASES_IMMUTA_CONNECTIONS_IMMUTADB_PASSWORD=<postgres-password>

   # onboarding and secure
   # PostgreSQL connection string for the onboarding schema in the metadata database.
   # URL-encode any special characters in the password.
   ONBOARDING_DATABASE_URL=postgres://immuta:<postgres-password>@<postgres-fqdn>:5432/immuta?schema=onboarding
   ```
2. Create secret named `immuta-secret` from file `secret-data.env`.

   ```bash
   kubectl create secret generic immuta-secret --from-env-file=secret-data.env
   ```
3. Delete file `secret-data.env`, as it's no longer needed.

   ```bash
   rm -i secret-data.env
   ```

### Edit Helm values

1. Edit `immuta-values.yaml` to include the following Helm values.

   ```yaml
   audit:
     deployment:
       existingSecret: immuta-secret
     export:
       cronJob:
         existingSecret: immuta-secret

   secure:
     existingSecret:
       name: immuta-secret
       # Optional. Map expected keys with keys in existing secret
       # keyMapping: {}

   onboarding:
     existingSecret: immuta-secret
   ```
2. Remove any sensitive key-value pairs from the `immuta-values.yaml` Helm values that were made redundant after the secret was created.

### Apply Helm values

Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

```shell
helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
```


# Rotating Credentials

This guide demonstrates how to update credentials referenced in the Immuta Enterprise Helm chart (IEHC).

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the IEHC was deployed into namespace `immuta` and that the current namespace is `immuta`.
{% endhint %}

## Kubernetes secrets

### Edit secrets

{% hint style="info" %}
**Using an alternative editor**

Set environment variable `KUBE_EDITOR` to specify an alternative text editor.
{% endhint %}

1. Validate that secret `immuta-secret` exists in the current namespace.

   ```bash
   kubectl get secret/immuta-secret
   ```
2. Edit secret `immuta-secret` in place.

   ```bash
   kubectl edit secret/immuta-secret
   ```
3. Edit secret `immuta-legacy-secret` in place. *Skip this step if the legacy query engine is disabled (the default).*

   ```sh
   kubectl edit secret/immuta-legacy-secret
   ```
4. Restart pods.

   ```bash
   kubectl rollout restart deployment --selector "app.kubernetes.io/component in (audit, secure)"
   ```

### Legacy query engine

{% hint style="info" %}
**Considerations when using the legacy query engine**

The following section is only necessary if the [legacy query engine service has been enabled](/2026.2/configuration/self-managed-deployment/configure/enabling-legacy-query-engine).
{% endhint %}

1. Validate that secret `immuta-legacy-secret` exists in the current namespace.

   ```bash
   kubectl get secret/immuta-legacy-secret
   ```
2. Get the query engine replica count, this value will be referenced in subsequent step(s).

   ```bash
   kubectl get statefulset --all --selector "app.kubernetes.io/component=query-engine" --output template='{{ .status.replicas }}'
   ```
3. Scale the replica count down to `1`.

   ```bash
   kubectl scale statefulset --all --replicas 1 --selector "app.kubernetes.io/component=query-engine"
   ```
4. Get the query engine pod name, this value will be referenced in subsequent step(s).

   ```bash
   kubectl get pod --selector "app.kubernetes.io/component=query-engine"
   ```
5. Update the [placeholder value](/2026.2/configuration/self-managed-deployment/conventions) with a query engine superuser password.

   ```bash
   kubectl exec pod/<query-engine-pod-name> -- \
       psql -d immuta -c \
       "ALTER USER postgres WITH ENCRYPTED PASSWORD '<new-patroni-superuser-password>'"
   ```
6. Update the [placeholder value](/2026.2/configuration/self-managed-deployment/conventions) with a query engine replication password.

   ```bash
   kubectl exec pod/<query-engine-pod-name> -- \
       psql -d immuta -c \
       "ALTER USER replicator WITH ENCRYPTED PASSWORD '<new-patroni-replication-password>'"
   ```
7. Update the [placeholder value](/2026.2/configuration/self-managed-deployment/conventions) with a query engine feature password.

   ```bash
   kubectl exec pod/<query-engine-pod-name> -- \
       psql -d immuta -c \
       "ALTER USER feature_service WITH ENCRYPTED PASSWORD '<new-immuta-feature-password>'"
   ```
8. Scale the replica count back up to the previous value by updating the [placeholder value](/2026.2/configuration/self-managed-deployment/conventions).

   ```bash
   kubectl scale statefulset --all --replicas <query-engine-previous-replica-count> --selector "app.kubernetes.io/component=query-engine"
   ```

## Apply Helm values

1. Update credentials in the `immuta-values.yaml` file.
2. Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`. Update the [placeholder value](/2026.2/configuration/self-managed-deployment/conventions) with your own release name.

   ```shell
   helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
   ```


# External Cache Configuration

This guide demonstrates how to configure an external key-value cache (such as Redis or Memcached) with the Immuta Enterprise Helm chart (IEHC).

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the IEHC was deployed into namespace `immuta` and that the current namespace is `immuta`.
{% endhint %}

## Prerequisite

The [Production best practices](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production) guide must be completed before proceeding.

### Redis

1. Edit secret `immuta-secret` that was created in the [Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production) guide.

   ```bash
   kubectl edit secret/immuta-secret
   ```
2. Add key-value `IMMUTA_SERVER_CACHE_PROVIDER_OPTIONS_PASSWORD=<cache-password>`.

## Edit Helm values

Edit the `immuta-values.yaml` file to include the relevant Helm values listed below. Update all [placeholder values](/2026.2/configuration/self-managed-deployment/conventions) with your own values.

### Redis

{% hint style="info" %}
**TLS configuration**

TLS must be configured both client-side and server-side. The following Helm values demonstrate connecting to Redis with TLS enabled.
{% endhint %}

```yaml
cache:
  enabled: false

secure:
  extraConfig:
    server:
      cache:
        provider:
          constructor: catbox-redis
          options:
            host: <redis-fqdn>
            port: <port>
            # Setting options.tls to an empty dict enables TLS without configuring any other options.
            tls: {}

            # Dict representation of TLS config options json-object for package ioredis
            # https://github.com/redis/ioredis
            #
            # tls:
            #   ca:
            #   key:
            #   cert:

  extraEnvVars:
  - name: IMMUTA_SERVER_CACHE_PROVIDER_OPTIONS_PASSWORD
    valueFrom:
      secretKeyRef:
        key: IMMUTA_SERVER_CACHE_PROVIDER_OPTIONS_PASSWORD
        name: immuta-secret
```

### Memcached

```yaml
cache:
  enabled: false

secure:
  extraConfig:
    server:
      cache:
        provider:
          constructor: catbox-memcached
          options:
            host: <memcached-fqdn>
            port: <port>
```

## Apply Helm values

Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

```shell
helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
```


# Enabling Legacy Query Engine

The query engine is no longer installed by default. This guide demonstrates how to enable the query engine using the Immuta Enterprise Helm chart (IEHC).

If you are using any of the [legacy data platforms](/2026.2/releases/support-matrix#legacy-databases), you must enable the query engine.

{% hint style="info" %}
**Kubernetes namespace**

The following section(s) presume the IEHC was deployed into namespace `immuta`, and that the current namespace is `immuta`.
{% endhint %}

## Prerequisites

{% hint style="info" %}
When migrating from the IHC to IEHC, query engine state is not retained. You must enable query engine rehydration to restore existing data source tables. If SQL credentials are used, they must be recreated by using LDAP sync or manually with the following command executed in the `bometadata` database:

`TRUNCATE bometadata."profile-sql";`
{% endhint %}

* The [Immuta in production](/2026.2/configuration/self-managed-deployment/configure/immuta-in-production#kubernetes-secrets) guide must be completed before proceeding.
* Validate that secret `immuta-secret` exists in the current namespace.

  ```bash
  kubectl get secret/immuta-secret
  ```

## Create Kubernetes secret

1. Create a file named `secret-data.env` with the following content.

   ```bash
   # query-engine
   IMMUTA_FEATURE_PASSWORD=<immuta-feature-password>
   PATRONI_SUPERUSER_PASSWORD=<patroni-superuser-password>
   PATRONI_REPLICATION_PASSWORD=<patroni-replication-password>
   PATRONI_RESTAPI_PASSWORD=<patroni-api-password>
   ```
2. Create secret named `immuta-legacy-secret` from file `secret-data.env`

   ```bash
   kubectl create secret generic immuta-legacy-secret --from-env-file=secret-data.env
   ```
3. Delete file `secret-data.env`, as it's no longer needed.

   ```bash
   rm -i secret-data.env
   ```

## Edit Helm values

1. Edit the `immuta-values.yaml` file to include the following Helm values.

   <pre class="language-yaml"><code class="lang-yaml">legacy:
     enabled: true

     queryEngine:
       statefulset:
         extraEnvVars:
         - name: IMMUTA_FEATURE_PASSWORD
           valueFrom:
             secretKeyRef:
               name: immuta-legacy-secret
               key: IMMUTA_FEATURE_PASSWORD
         - name: PATRONI_SUPERUSER_PASSWORD
           valueFrom:
             secretKeyRef:
               name: immuta-legacy-secret
               key: PATRONI_SUPERUSER_PASSWORD
         - name: PATRONI_REPLICATION_PASSWORD
           valueFrom:
             secretKeyRef:
               name: immuta-legacy-secret
               key: PATRONI_REPLICATION_PASSWORD
         - name: PATRONI_RESTAPI_PASSWORD
           valueFrom:
             secretKeyRef:
               name: immuta-legacy-secret
               key: PATRONI_RESTAPI_PASSWORD

       postgres:
         # Query Engine feature user
         # Instead use queryEngine.statefulset.extraEnvVars[].name[IMMUTA_FEATURE_PASSWORD]
         # password: &#x3C;immuta-feature-password>

         # Query Engine superuser user
         # Instead use queryEngine.statefulset.extraEnvVars[].name[PATRONI_SUPERUSER_PASSWORD]
         # superuserPassword: &#x3C;patroni-superuser-password>

         # Query Engine replication user
         # Instead use queryEngine.statefulset.extraEnvVars[].name[PATRONI_REPLICATION_PASSWORD]
         # replicationPassword: &#x3C;patroni-replication-password>

         # Query Engine patroni api user
         # Instead use queryEngine.statefulset.extraEnvVars[].name[PATRONI_RESTAPI_PASSWORD]
         # patroniApiPassword: &#x3C;patroni-api-password>
       immutaSecurity:
         # Each Kubernetes Service has a DNS record associated with it. See: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
         # The anatomy of a domain name is as followed:
         #   &#x3C;service>.&#x3C;namespace>.svc.&#x3C;cluster-domain>
         #
         # Where the default cluster domain is: cluster.local
         authEndpoint: "http://immuta-secure.immuta.svc.cluster.local:8823"

   secure:
     extraEnvVars:
     - name: IMMUTA_DATABASES_IMMUTA_CONNECTIONS_FEATURESTOREDB_PASSWORD
       valueFrom:
         secretKeyRef:
           name: immuta-legacy-secret
           key: IMMUTA_FEATURE_PASSWORD

     extraConfig:
       <a data-footnote-ref href="#user-content-fn-1">queryEngineRehydration</a>:
         enabled: true
       disableFeatureStore: false
       databases:
         immuta:
           connections:
             featureStoreDb:
               # Each Kubernetes Service has a DNS record associated with it. See: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
               # The anatomy of a domain name is as followed:
               #   &#x3C;service>.&#x3C;namespace>.svc.&#x3C;cluster-domain>
               #
               # Where the default cluster domain is: cluster.local
               host: "immuta-legacy-query-engine-service.immuta.svc.cluster.local"
               port: 5432
               ssl: false
               # Query Engine feature user
               # Instead use secure.extraEnvVars[].name[IMMUTA_DATABASES_IMMUTA_CONNECTIONS_FEATURESTOREDB_PASSWORD]
               # password: &#x3C;immuta-feature-password>
   </code></pre>
2. Update all [placeholder values](/2026.2/configuration/self-managed-deployment/conventions) in the `immuta-values.yaml` file.

{% hint style="warning" %}
**Avoid these special characters in generated passwords**

whitespace, `$`, `&`, `:`, `\`, `/`, `'`, `"`
{% endhint %}

## Apply Helm values

Perform a [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) to apply the changes made to `immuta-values.yaml`.

```shell
helm upgrade <release-name> oci://ocir.immuta.com/stable/immuta-enterprise --values immuta-values.yaml --version 2026.2.2
```

[^1]: You must enable query engine rehydration to restore existing data source tables.


# Private Container Registries

This guide demonstrates how to point the Immuta Enterprise Helm chart (IEHC) at a private container registry.

{% hint style="info" %}
**Image availability**

This guide assumes the Immuta container images are already in your private registry. To copy them there with their digests intact, see the [Air-gapped environments guide](/2026.2/configuration/self-managed-deployment/configure/immuta-in-an-air-gapped-environment). The same download/push process applies even when the environment is not air-gapped.
{% endhint %}

## Registry with preserved repository paths

If the images keep their original repository paths (for example, `stable/immuta-service` stays `stable/immuta-service`), the only value required is the registry itself:

```yaml
global:
  imageRegistry: <private-registry-fqdn>
```

## Registry with a path prefix

If your registry imposes a path prefix (common with Artifactory or Harbor project layouts), map each repository with `global.imageRepositoryMap`. Do not override each component's `image.repository` individually:

```yaml
global:
  imageRegistry: <private-registry-fqdn>
  imageRepositoryMap:
    stable/immuta-service: <prefix>/stable/immuta-service
    stable/audit-service: <prefix>/stable/audit-service
    # ...one entry per repository
```

List every repository the chart references:

```bash
helm show values oci://ocir.immuta.com/stable/immuta-enterprise --version 2026.2.2 | grep 'repository:' | sort -u
```

## Pull secret

If your private registry requires authentication, create a pull secret and reference it globally:

```bash
kubectl create secret docker-registry immuta-private-registry \
    --docker-server=<private-registry-fqdn> \
    --docker-username=<username> \
    --docker-password=<password>
```

```yaml
global:
  imagePullSecrets:
    - name: immuta-private-registry
```


# Air-Gapped Environments

This guide demonstrates how to move the Immuta Enterprise Helm chart and its container images into an environment with no internet access. Two artifacts cross the boundary:

* The Helm chart archive (`.tgz`)
* The container images, copied by digest into archive files

The same process applies to the initial install and to every upgrade: Each release is one chart archive plus one set of images.

Every image is copied **by digest**, taken from the `DIGESTS.md` file inside the chart itself. A digest is content-addressed, so an image that arrives in your registry with the expected digest is bit-for-bit the image Immuta published; the transfer method cannot silently alter it.

## Requirements

* [Skopeo](https://github.com/containers/skopeo) and [Helm](https://helm.sh/docs/intro/install/) on both the connected machine and a machine inside the air-gapped environment (skopeo moves the images; Helm pulls the chart on one side and installs it on the other).
* On the connected machine, skopeo and Helm are authenticated with ocir.immuta.com. Credentials are provided by Immuta; there is currently no self-service lookup. Contact your Immuta representative or [Immuta Support](https://support.immuta.com) if you do not have them.
* On the air-gapped machine, skopeo is authenticated with your private registry.

## On the connected machine: Download the Helm chart and archive images

1. Download the Helm chart.

   ```bash
   mkdir ./immuta-2026.2.2
   helm pull oci://ocir.immuta.com/stable/immuta-enterprise --destination ./immuta-2026.2.2 --version 2026.2.2
   ```
2. Extract `DIGESTS.md` (the chart's own manifest of every image it references, with digests) and convert it into a plain image list.

   ```bash
   tar --extract --gzip --strip-components=1 --directory=./immuta-2026.2.2 --file ./immuta-2026.2.2/immuta-enterprise-2026.2.2.tgz immuta-enterprise/DIGESTS.md
   awk -F '|' '/sha256:/ { gsub(/ /, ""); print $2, $3 }' ./immuta-2026.2.2/DIGESTS.md > ./immuta-2026.2.2/images.txt
   ```

   Each line of `images.txt` is `<image>:<tag> <digest>`. This file travels with the archives and drives every later step.
3. (Optional) Verify Immuta's signature on each image before archiving, following the [Cosign verification guide](/2026.2/configuration/self-managed-deployment/configure/cosign-verification).
4. Archive every image, by digest, in one pass. `--all` preserves every architecture; `--preserve-digests` makes skopeo fail rather than alter content. A failed copy stops the loop, so a partial bundle cannot be mistaken for a complete one.

   ```bash
   while read -r image digest; do
       skopeo copy --all --preserve-digests \
           "docker://${image%:*}@${digest}" \
           "oci-archive:./immuta-2026.2.2/$(basename "${image%:*}")-${image##*:}.tar:${image}" || exit 1
   done < ./immuta-2026.2.2/images.txt
   ```

## Transfer

Move the `immuta-2026.2.2` directory into the air-gapped environment using your organization's approved transfer process. Everything needed is in that one directory: the chart archive, `images.txt`, and one `.tar` per image.

## In the air-gapped environment: Push images to your private registry

1. Push every image to your private registry, preserving each image's repository path and digest. Replace `<private-registry-fqdn>` with your registry.

   ```bash
   while read -r image digest; do
       path="${image#*/}"
       skopeo copy --all --preserve-digests \
           "oci-archive:./immuta-2026.2.2/$(basename "${image%:*}")-${image##*:}.tar" \
           "docker://<private-registry-fqdn>/${path}" || exit 1
   done < ./immuta-2026.2.2/images.txt
   ```

   If your registry requires a path prefix (for example, an Artifactory repository), push to `<private-registry-fqdn>/<prefix>/${path}` instead, verify the same location in the next step, and map the repositories as described in the [Private container registries guide](/2026.2/configuration/self-managed-deployment/configure/private-container-registries#registry-with-a-path-prefix).
2. Verify the pushed images. Every digest in your registry must equal the digest in `images.txt`. Any mismatch fails loudly.

   ```bash
   while read -r image digest; do
       path="${image#*/}"
       actual=$(skopeo inspect --raw "docker://<private-registry-fqdn>/${path}" | skopeo manifest-digest /dev/stdin)
       [ "$actual" = "$digest" ] && echo "OK    ${path}" || { echo "FAIL  ${path}: ${actual} != ${digest}"; exit 1; }
   done < ./immuta-2026.2.2/images.txt
   ```

## Install or upgrade

1. Point the chart at your registry. Because the repository paths were preserved, pointing the chart at your registry is a single value — no per-image overrides:

   ```yaml
   global:
     imageRegistry: <private-registry-fqdn>
   ```

   If your registry requires authentication, also create a pull secret and set `global.imagePullSecrets`, as described in the [Private container registries guide](/2026.2/configuration/self-managed-deployment/configure/private-container-registries#pull-secret). The credentials skopeo used to push are not used by Kubernetes to pull.

   If your registry requires a path prefix (for example, an Artifactory repository), map the repositories instead of overriding each image. See the [Private container registries guide](/2026.2/configuration/self-managed-deployment/configure/private-container-registries#registry-with-a-path-prefix) for details.
2. Install or upgrade from the local chart archive. Wherever other guides reference `oci://ocir.immuta.com/stable/immuta-enterprise`, substitute the archive path and omit `--version`:

   ```bash
   helm upgrade --install <release-name> ./immuta-2026.2.2/immuta-enterprise-2026.2.2.tgz --values immuta-values.yaml
   ```


# OpenSearch Authentication


# Setting Up OpenSearch User Permissions for an AWS Role

If you're using AWS OpenSearch in your Immuta installation, use this how-to to set up the proper access and permissions needed for AWS role authentication.

## Requirements

* An OpenSearch domain
* The user setting up the permissions must have the following permissions:
  * Administrative access to your AWS account
  * Master user on your OpenSearch domain

## Create an IAM role for Immuta audit

Create an AWS IAM role that Immuta will assume to send audit events to your OpenSearch domain.

1. [Create an AWS IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-custom.html) with credentials using the [AWS SDK's default credential provider chain](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html). This method requires a configured [IAM role for a service account (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). Contact your Immuta representative to customize your deployment and set up an IAM role for a service account that can give Immuta the credentials to set up the integration.
2. Create the [access policy](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html#ac-types-identity) for this role. It should include at least the permissions provided in the example below, but might need additional permissions depending on other local setup factors. You can find the full list of permissions in the AWS docs on the [AWS actions, resources, and condition keys page](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonopensearchservice.html).\
   \
   Note: If you use this example, replace the **content in angle brackets** with your region, AWS account ID, and domai&#x6E;**.**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "es:ESHttpDelete",
                "es:ESHttpGet",
                "es:ESHttpHead",
                "es:ESHttpPatch",
                "es:ESHttpPost",
                "es:ESHttpPut",
                "es:DescribeDomains",
                "es:ListDomainNames"
            ],
            "Resource": "arn:aws:es:<region>:<Your AWS Account ID>:domain/<your-domain>/*"
        }
    ]
}
```

3. Name the role and save.

## Set up domain access policy

Amazon OpenSearch Service domains are controlled by a [resource-based access policy](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html#ac-types) that determines which IAM users or roles can connect to the domain and perform operations.

1. Follow [AWS documentation](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html#ac-types) for updating a resource-based policy. Immuta supports two options for domain access:
   1. **Only use fine-grained access control**: If you select this option, no additional actions are required this step.
   2. **Configure domain access policy**:
      1. Edit the access policy to allow the role OpenSearch access and management operations. Grant your AWS IAM `es:*` through a [resource-based policy](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html#ac-types-resource).\
         Note: If you use this example, replace the **content in angle brackets** with your region, AWS account ID, and domain.

         ```json
         {
             "Version": "2012-10-17",
             "Statement": [
                 {
                     "Effect": "Allow",
                     "Principal": {
                         "AWS": "arn:aws:iam::<Your AWS Account ID>:role/ImmutaAuditRole"
                     },
                     "Action": "es:*",
                     "Resource": "arn:aws:es:<region>:<Your AWS Account ID>:domain/<your-domain>/*"
                 }
             ]
         }
         ```
2. Save your changes.

### Configure OpenSearch permissions

In the OpenSearch console, you must create or edit a role that grants Immuta’s IAM role access to the appropriate cluster and index permissions.

1. Follow [AWS documentation](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html#ac-types) for creating a new OpenSearch role for your audit IAM role.
2. [Grant the following permissions](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html#fgac-access-control) to the new role.
   1. Cluster-level permissions:

      ```
      cluster:monitor/health
      indices:data/write/bulk*
      indices:data/write/bulk
      indices:monitor/settings/get
      indices:data/read/scroll
      indices:data/read/scroll/clear
      ```
   2. Index-level permissions for `*` index:

      ```
      indices:admin/aliases
      indices:admin/aliases*
      indices:data/read/search
      indices:admin/exists
      indices:admin/create
      indices:admin/delete
      indices:admin/settings/update
      indices:admin/get
      indices:data/write/delete/byquery
      indices:data/write/index
      indices:admin/mapping/put
      indices:data/write/bulk
      indices:data/write/bulk*
      indices:data/write/update/byquery
      indices:monitor/settings/get
      indices:data/write/delete
      indices:data/read/scroll
      indices:data/read/scroll/clear
      indices:admin/refresh
      indices:admin/refresh*
      ```

### Map the IAM role to the OpenSearch role

Once the IAM role is created and OpenSearch permissions are updated, allow the role to assume permissions inside OpenSearch.

1. Follow [AWS documentation](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html#fgac-access-control) for updating a backend role in OpenSearch.
2. Select the OpenSearch role created for Immuta audit access.
3. Under **Backend roles**, add the ARN of your IAM role:

   ```
   arn:aws:iam::<Your AWS Account ID>:role/ImmutaAuditRole
   ```
4. Save your changes.

## Optionally create a trust relationship

If Immuta is deployed in an AWS account that is different than OpenSearch, then you must configure a trust relationship between the Immuta role and an OpenSearch role. Follow [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html) for creating IAM policies in the Amazon S3 console.

Once configured set `SEARCH_AWS_ROLE_ARN` with the role for Immuta to assume in the `immuta-values.yaml`.

After these steps are complete, your audit role should have the required permissions, and you can [complete the Immuta install](/2026.2/configuration/self-managed-deployment/install/managed-public-cloud) using the IAM role.


# Setting Up OpenSearch User Permissions for Username and Password Authentication

If you're using AWS OpenSearch in your Immuta installation, use this how-to to set up the proper permissions needed for username and password authentication.

1. In the AWS console, [create an OpenSearch domain](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/createupdatedomains.html#createdomains) and create a master user. This user will set up the permissions for the audit user.
2. In the OpenSearch console, [create a new user](https://opensearch.org/docs/latest/security/access-control/users-roles/#defining-users). This user will be the audit user. You will enter the username and password for this user when installing Immuta.
3. [Create a role](https://opensearch.org/docs/latest/security/access-control/users-roles/#defining-roles) for the audit user.
4. Add the audit user to the role.
5. Create the two additional roles to hold the following permission groups. Immuta recommends permission groups for a smooth configuration, but just ensure the user has all the following permissions.
   * **immuta\_cluster\_permission\_grp** with the following permissions:
     * cluster:monitor/health
     * indices:data/write/bulk
     * indices:data/write/bulk\*
     * indices:data/read/scroll
     * indices:data/read/scroll/clear
     * indices:monitor/settings/get
   * **immuta\_index\_permission\_grp** with the following permissions for the `*` index:
     * indices:admin/aliases
     * indices:admin/aliases\*
     * indices:admin/exists
     * indices:admin/create
     * indices:admin/delete
     * indices:admin/settings/update
     * indices:admin/get
     * indices:admin/refresh
     * indices:admin/refresh\*
     * indices:admin/mapping/put
     * indices:data/read/search
     * indices:data/read/scroll
     * indices:data/read/scroll/clear
     * indices:data/write/delete
     * indices:data/write/delete/byquery
     * indices:data/write/index
     * indices:data/write/bulk
     * indices:data/write/bulk\*
     * indices:data/write/update/byquery
     * indices:monitor/settings/get
6. Add the additional roles with the permission to the audit user's role.

After these steps are complete, your audit user should have the required permissions and you can [complete the Immuta install](/2026.2/configuration/self-managed-deployment/install/managed-public-cloud) using the user's username and password.


# Audit Best Practices

## Supported audit options

When installing Immuta, these are the supported options for getting audit logs from events in Immuta:

| Supported audit options                                                                           | Requirements                                                                             |
| ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| [Stream logs out of Kubernetes](#stream-logs-out-of-kubernetes)                                   | <ul><li><code>audit-service</code> enabled</li><li>Elasticsearch or OpenSearch</li></ul> |
| [Export logs out of Elasticsearch or OpenSearch](#export-logs-out-of-elasticsearch-or-opensearch) | <ul><li><code>audit-service</code> enabled</li><li>Elasticsearch or OpenSearch</li></ul> |

### Stream logs out of Kubernetes

{% hint style="success" %}
The recommended option is to stream logs out of Kubernetes for your audit needs.
{% endhint %}

Connect a SIEM integration to the `audit-service` pod and use STDOUT to stream audit logs from the container to your SIEM provider. The Helm chart is configured for this by default.

To clear up noise, you can filter the log collection on a custom log level to `audit`. This will ensure only audit events are collected.

### Export logs out of Elasticsearch or OpenSearch

Use your preferred method to export the audit logs from the external Elasticsearch you have configured with your deployment.

## Retention period

{% hint style="info" %}
The retention period may be configured when starting the database while deploying Immuta and cannot be adjusted in an update.
{% endhint %}

The retention period for audit logs in Elasticsearch or OpenSearch is 7 days. However, this is configurable in your database. Before deploying Immuta, set the following in the [`immuta-values.yaml`](/2026.2/configuration/self-managed-deployment/install/managed-public-cloud#install-immuta) to configure audit retention. This example updates audit retention to 90 days:

```yaml
audit:
  init:
    extraEnvVars:
      - name: AUDIT_RETENTION_POLICY_IN_DAYS
        value: "90"
```

The Immuta UI supports a maximum retention period of 90 days. Any audit logs older than 90 days will not appear in the UI.

## Dependencies

The `audit-service` requires Elasticsearch or OpenSearch to function. If your deployment does not include Elasticsearch or OpenSearch, `audit-service` must be turned off. See the following deployment examples with the set dependencies and the resulting functionality.

|              | Audit service        | Elasticsearch or OpenSearch | Result                               |
| ------------ | -------------------- | --------------------------- | ------------------------------------ |
| Deployment 1 | :white\_check\_mark: | :white\_check\_mark:        | Full product and audit functionality |
| Deployment 2 | :white\_check\_mark: | ❌                           | Unsupported configuration            |
| Deployment 3 | ❌                    | ❌                           | Functional product with no audit     |

See the [Requirements page](/2026.2/configuration/self-managed-deployment/deployment-requirements) for a high-level overview of the Immuta deployment requirements.


# Disaster Recovery

{% hint style="info" %}
**Planning a disaster recovery strategy**

As of 2024.2 LTS, there is no longer a backup/restore mechanism built into the Immuta Enterprise Helm chart. Organizations are now solely responsible for creating and enacting an effective disaster recovery strategy for their installation.
{% endhint %}

All application state is stored in the PostgreSQL metadata database; therefore, recovering from a disaster event only entails restoring the aforementioned PostgreSQL database. Consult each cloud provider's point-in-time recovery (PITR) documentation for guidance:

* [Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/aws-backup/latest/devguide/point-in-time-recovery.html)
* [Azure Database for PostgreSQL](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-backup-restore)
* [Google Cloud SQL for PostgreSQL](https://cloud.google.com/sql/docs/postgres/backup-recovery/pitr)

For more details about point-in-time recovery, see the [PostgreSQL documentation](https://www.postgresql.org/docs/current/continuous-archiving.html).


# Troubleshooting

## Upgrade failure

1. List the upgrade jobs and find the one that failed.

   ```sh
   kubectl get jobs
   ```
2. Read the job's log.

   ```sh
   kubectl logs job/<job-name>
   ```
3. Use the [upgrade failure messages table](#upgrade-failure-messages) to determine remediation steps.

#### Upgrade failure messages

| Message                                                                                                                             | Description                                                                                                                                                                                                                                                                                             | Fix                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `secure.ingress was removed in 2026.2`                                                                                              | The chart refuses to upgrade while your values file contains a `secure.ingress` block because applying it would delete your existing [ingress](/2026.2/configuration/self-managed-deployment/upgrade-immuta#ingress-migration) and its cloud load balancer. No changes were applied to your deployment. | Follow the ingress migration steps in the [upgrade guide](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta), and then run the upgrade again.                                                                                   |
| `onboarding.postgres.database is required`                                                                                          | 2026.2 introduces the [Onboarding service](/2026.2/configuration/self-managed-deployment/upgrade-immuta#onboarding-service), which requires `onboarding.postgresql.database` to be set in your values file to the same database name Secure uses. No changes were applied to your deployment.           | Follow the [upgrade guide](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta) to add the Onboarding service, and then run the upgrade again.                                                                                    |
| `onboarding.postgresql.password is required`                                                                                        | Onboarding could not find a database password. This happens when your database password is stored in an existing Kubernetes secret (`secure.existingSecret`), because Onboarding does not read that secret. No changes were applied to your deployment.                                                 | Add `ONBOARDING_DATABASE_URL` to the secret and set `onboarding.existingSecret`, as described in [Existing Kubernetes secrets](/2026.2/configuration/self-managed-deployment/upgrade-immuta#existing-kubernetes-secrets), and then run the upgrade again. |
| `couldn't find key ONBOARDING_DATABASE_URL in Secret` on a secure pod                                                               | Your existing Kubernetes secret does not contain the `ONBOARDING_DATABASE_URL` key, which Secure reads in 2026.2.                                                                                                                                                                                       | Add the key to the secret as described in [Existing Kubernetes secrets](/2026.2/configuration/self-managed-deployment/upgrade-immuta#existing-kubernetes-secrets). The pods start once the key exists.                                                    |
| `global.tenantId must be a valid UUID`                                                                                              | The [tenant ID](/2026.2/configuration/self-managed-deployment/upgrade-immuta#tenant-id) is not set to a UUID. No changes were applied to your deployment.                                                                                                                                               | Set the tenant ID to a UUID and run the [upgrade again](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta).                                                                                                                     |
| `TENANT_ID must be a valid UUID and must not be the all-zeros UUID` (in the `audit-init` job)                                       | There is no `global.tenantId` set in the immuta-values.yaml file.                                                                                                                                                                                                                                       | Set the tenant ID to a UUID and run the [upgrade again](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta).                                                                                                                     |
| `Missing required environment variables for self-managed use: SEARCH_INDEX_NAME, SEARCH_INDEX_ALIAS_NAME` (in the `audit-init` job) | Index names were not set.                                                                                                                                                                                                                                                                               | Set these environment variables and run the [upgrade again](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta).                                                                                                                 |
| `UPGRADE FAILED: ... timed out` while the `secure-database-migrate` job is still running                                            | The Helm timeout was too short.                                                                                                                                                                                                                                                                         | Wait for the job to complete (`kubectl get jobs`), and then run the [upgrade again](/2026.2/configuration/self-managed-deployment/upgrade-immuta#upgrade-immuta) with a longer `--timeout`.                                                               |
| `ImagePullBackOff` on a job pod                                                                                                     | Registry credentials have expired.                                                                                                                                                                                                                                                                      | Recreate the registry secret from the [installation guide](/2026.2/configuration/self-managed-deployment/install/managed-public-cloud#create-registry-secret) and delete the stuck pod; the job will retry.                                               |

## PostgreSQL

### How do I determine if the database is accepting connections?

1. Create a pod named `debug-postgres` and spawn an interactive shell.

   ```bash
   kubectl run debug-postgres --stdin --tty --rm --image docker.io/bitnami/postgresql:latest -- sh
   ```
2. Validate that the database is listening.

   ```bash
   pg_isready --host <postgres-fqdn> --port 5432
   ```

## Redis

### How can a TCP connection be established without using Redis CLI?

1. Create a pod named `debug-redis` and spawn an interactive shell.

   ```bash
   kubectl run debug-redis --stdin --tty --rm --image docker.io/rockylinux/rockylinux:9 -- sh
   ```
2. Send a raw TCP message to the database using Netcat.

   ```bash
   nc -zv <redis-fqdn> 6379
   ```

### How do I establish a TCP connection?

1. Create a pod named `debug-redis` and spawn an interactive shell.

   ```bash
   kubectl run debug-redis --stdin --tty --rm --image docker.io/bitnami/redis:latest -- sh
   ```
2. Establish a connection to the database using the Redis client. If a connection can be established with Netcat and the `redis-cli` command does not return, then Redis could be expecting a TLS connection. Pass option `--tls`.

   ```sh
   redis-cli -h <redis-fqdn> -p 6379
   ```

## Elasticsearch

### How do I query the API using cURL?

1. Create a pod named `debug-elasticsearch` and spawn an interactive shell.

   ```bash
   kubectl run debug-elasticsearch --stdin --tty --rm --image docker.io/rockylinux/rockylinux:9 -- sh
   ```
2. Install package `curl`.

   ```bash
   dnf install curl
   ```
3. Check the [cluster health](https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html).

   ```sh
   curl --fail --request GET "http://<elasticsearch-fqdn>:9200/_cluster/health?pretty"
   ```

{% hint style="info" %}
**Basic authentication**

Depending on the cluster's configuration it might be necessary to use [basic auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication). Pass option `--header "Authorization: Basic $token"` where token equals `$(printf '%s:%s' "<username>" "<password>" | base64)`
{% endhint %}

## Helm

### When installing the helm chart from ocir.immuta.com, I get error `scheme "oci" not supported`. What's going on?

The Immuta Enterprise Helm chart (IEHC) is distributed as an OCI artifact, and your current Helm version might not support it. Refer to the [Helm documentation](https://helm.sh/docs/topics/registries/#oci-support-prior-to-v380) for further assistance.

1. Determine your Helm version.

   ```bash
   helm version
   ```
2. If older than 3.8.0 you'll need to upgrade. Before this version OCI support wasn't enabled by default.

## Kubernetes

### `kubectl wait` timed out and some pods never became ready. How do I find out why?

1. Identify the pods that are not ready.

   ```bash
   kubectl get pods
   ```
2. Inspect the events for a failing pod. Look for image pull errors (check your registry secret) and failed probes.

   ```bash
   kubectl describe pod <pod-name>
   ```
3. Read the pod's logs. Failed connections to PostgreSQL or Elasticsearch are the most common cause; verify that each [FQDN is resolvable](#how-can-i-ensure-the-fully-qualified-domain-name-fqdn-is-resolvable-from-within-the-kubernetes-cluster) and accepting connections from within the cluster.

   ```bash
   kubectl logs <pod-name> --previous
   ```

## Frequently asked questions

### How can I ensure the fully qualified domain name (FQDN) is resolvable from within the Kubernetes cluster?

1. Create a pod named `debug-dns` and spawn an interactive shell.

   ```bash
   kubectl run debug-dns --stdin --tty --rm --image docker.io/rockylinux/rockylinux:9 -- sh
   ```
2. Install package `bind-utils`.

   ```bash
   dnf install bind-utils
   ```
3. Perform DNS lookups on a given FQDN.

   ```bash
   dig <fqdn>
   ```

### I'm unsure which Kubernetes namespace or Helm release is associated with my Immuta installation. How can I find this out?

```bash
helm list --all-namespaces --output json | jq '.[]|select(.chart | startswith("immuta"))'
```

### I no longer have my `immuta-values.yaml` Helm values file. How do I recover this file?

```bash
helm get values <release-name> > immuta-values.yaml
```

### I don't want to keep passing option `--namespace` every time I run a Helm command. How do I set a default?

```bash
kubectl config set-context --current --namespace=<name>
```


# Conventions

The following conventions are used throughout the installation material.

## Angle brackets ( < and > )

Phrases wrapped in angle brackets (i.e., `<`, `>`) are placeholders used to indicate values that must be substituted with user-provided values. Placeholders are typically written in either [kebab case](https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case), or [snake case](https://developer.mozilla.org/en-US/docs/Glossary/Snake_case); the following placeholders are equivalent:

* `<the-quick-brown-fox>`
* `<the_quick_brown_fox>`

### Example

#### Input

```yaml
computerScientists:
- Alan Turing
- Grace Hopper
- Donald Knuth
- Tim Berners-Lee
- John McCarthy
- <first-name> <last-name>
```

#### Output

```yaml
computerScientists:
- Alan Turing
- Grace Hopper
- Donald Knuth
- Tim Berners-Lee
- John McCarthy
- Margaret Hamilton
```


# Connect Integrations

Immuta integrates with your data platforms so you can register your data and effectively manage access controls on that data.

This section includes guidance for connecting your data platform and keeping it synced with Immuta.

## [Integrations overview](/2026.2/configuration/integrations/integrations-overview)

This reference guide outlines the features, policies, and audit capabilities of each data platform Immuta supports.

## Integrations

The guides in these sections include information about how to connect your data platform to Immuta:

* [Amazon Redshift](/2026.2/configuration/integrations/redshift)
* [Amazon S3](/2026.2/configuration/integrations/amazon-s3)
* [Azure Synapse Analytics](/2026.2/configuration/integrations/azure-synapse-analytics)
* [Databricks Spark](/2026.2/configuration/integrations/databricks/databricks-spark)
* [Databricks Unity Catalog](/2026.2/configuration/integrations/databricks/databricks-unity-catalog)
* [Google BigQuery](/2026.2/configuration/integrations/google-bigquery)
* [Snowflake](/2026.2/configuration/integrations/snowflake)
* [Starburst (Trino)](/2026.2/configuration/integrations/starburst-trino)

## [Queries Immuta runs in remote platforms](/2026.2/configuration/integrations/queries-immuta-runs-in-remote-platforms)

This reference guide outlines the actions and features that trigger Immuta queries in your remote platform that may incur cost.

## [Connect your data](/2026.2/configuration/integrations/registering-metadata)

Immuta integrates with your data platforms so you can register your data and effectively manage access controls on that data. This section includes concept, reference, and how-to guides for registering and managing data sources.


# Integrations Overview

Immuta does not require users to learn a new API or language to access protected data. Instead, Immuta integrates with existing tools and data platforms while remaining invisible to downstream consumers.

The table below outlines features supported by each of Immuta's data platform integrations.

<table><thead><tr><th width="138"></th><th>Subscription policies</th><th>Data policies</th><th>Identification</th><th>Impersonation</th><th>Query audit</th><th>Tag ingestion</th></tr></thead><tbody><tr><td>Amazon Redshift</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Amazon S3</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Azure Synapse Analytics</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Databricks Spark</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Databricks Unity Catalog</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Google BigQuery</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td>Snowflake</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Starburst (Trino)</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>

## Subscription policy support matrix

The table below illustrates the subscription policy access types supported by each integration. If a data platform isn't included in the table, that integration does not support any subscription policies. For more details about read and write access policy support for these data platforms, see the [Subscription policy access types reference guide](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types).

<table><thead><tr><th>Integration</th><th width="199">Read access policies</th><th>Write access policies</th></tr></thead><tbody><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-redshift-privileges">Amazon Redshift</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span> View-based integrations are read-only</td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-amazon-s3-privileges">Amazon S3</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-azure-synapse-analytics-privileges">Azure Synapse Analytics</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span> View-based integrations are read-only</td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-databricks-spark-privileges">Databricks Spark</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span> Write access is controlled through <a href="/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/reference-guides/project-workspaces#databricks-spark-project-workspaces">workspaces</a> and <a href="/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration">scratch paths</a></td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-databricks-unity-catalog-privileges">Databricks Unity Catalog</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-google-bigquery-privileges">Google BigQuery</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span> View-based integrations are read-only</td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-snowflake-privileges">Snowflake</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-starburst-trino-privileges">Starburst (Trino)</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr></tbody></table>

## Data policy support matrix

The table below outlines the types of data policies supported for various data platforms. If a data platform isn't included in the table, that integration does not support any data policies.

For details about each of these policies, see the [Data policy types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies).

|                                           | Amazon Redshift      | Azure Synapse Analytics | Databricks Spark                                 | Databricks Unity Catalog                         | Google BigQuery      | Snowflake            | Starburst (Trino)    |
| ----------------------------------------- | -------------------- | ----------------------- | ------------------------------------------------ | ------------------------------------------------ | -------------------- | -------------------- | -------------------- |
| Cell-level masking                        | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :x:                  | :white\_check\_mark: | :white\_check\_mark: |
| [Custom function](#user-content-fn-1)[^1] | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Format preserving masking                 | :x:                  | :x:                     | :x:                                              | :x:                                              | :x:                  | :white\_check\_mark: | :x:                  |
| Hashing                                   | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Masking fields within STRUCT columns      | :x:                  | :x:                     | :white\_check\_mark:                             | [Supported with caveats](#user-content-fn-2)[^2] | :x:                  | :x:                  | :x:                  |
| Minimize                                  | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :x:                  | :white\_check\_mark: | :white\_check\_mark: |
| Only show data by time                    | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :x:                  | :white\_check\_mark: | :white\_check\_mark: |
| Only show rows (matching)                 | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Randomized response                       | :x:                  | :x:                     | :x:                                              | :x:                                              | :x:                  | :white\_check\_mark: | :x:                  |
| Regex                                     | :white\_check\_mark: | :x:                     | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Replace with NULL or constant             | :white\_check\_mark: | :white\_check\_mark:    | [Supported with caveats](#user-content-fn-3)[^3] | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Reversible masking                        | :white\_check\_mark: | :x:                     | :white\_check\_mark:                             | :x:                                              | :x:                  | :white\_check\_mark: | :white\_check\_mark: |
| Rounding                                  | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| WHERE clause                              | :white\_check\_mark: | :white\_check\_mark:    | :white\_check\_mark:                             | :white\_check\_mark:                             | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |

## Identification support matrix

Identification has varied support for data sources from different technologies based on the identifier type. For details about how identification works in Immuta, see the [Data identification page](/2026.2/configuration/manage-data-metadata/data-discovery).

| Technology              | Regex                | Dictionary           | Column name regex    |
| ----------------------- | -------------------- | -------------------- | -------------------- |
| Amazon Redshift         | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Amazon S3               | :x:                  | :x:                  | :white\_check\_mark: |
| Azure Synapse Analytics | :x:                  | :x:                  | :white\_check\_mark: |
| Databricks              | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Google BigQuery         | :x:                  | :x:                  | :white\_check\_mark: |
| Snowflake               | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |
| Starburst (Trino)       | :white\_check\_mark: | :white\_check\_mark: | :white\_check\_mark: |

## Query audit support for platform queries

The table below outlines what information is included in the query audit logs for each integration where query audit is supported.

<table data-full-width="false"><thead><tr><th></th><th>Databricks Spark</th><th>Databricks Unity Catalog</th><th>Snowflake</th><th>Starburst (Trino)</th></tr></thead><tbody><tr><td>Table and user coverage</td><td>Registered data sources and users</td><td>All tables and users</td><td>Registered data sources and users</td><td>Registered data sources and users</td></tr><tr><td>Object queried</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Columns returned</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Rows returned</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Query text</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Unauthorized information</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><a data-footnote-ref href="#user-content-fn-4">Limited support</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>

**Legend**:

* :white\_check\_mark: This is available and the information is included in audit logs.
* :x: This is not available and the information is not included in audit logs.

[^1]: Poorly written functions can lead to data leaks.

[^2]: Databricks Unity Catalog ARRAY, MAP, or STRUCT type columns only support masking with NULL.

[^3]: On Databricks data sources, joins will not be allowed on data protected with replace with NULL or constant policies.

[^4]: Unauthorized information is only available when the integration has table grants enabled. Unauthorized audit records will show a table name, but will not be connected to an Immuta data source.


# Amazon S3

{% hint style="info" %}
**Private preview**: This integration is available to select accounts. Contact your Immuta representative for details.
{% endhint %}

## Getting started

Immuta's Amazon S3 integration allows users to apply [subscription policies](#policy-enforcement) to data in S3 to restrict what prefixes, buckets, or objects users can access. To enforce access controls on this data, Immuta creates S3 grants that are administered by S3 Access Grants, an AWS feature that defines access permissions to data in S3.

### Requirements

* No location is registered in your AWS Access Grants instance before configuring the integration in Immuta.
* [**Enable** **AWS IAM Identity Center (IDC) (recommended)**](#user-content-fn-1)[^1]: [IDC](https://aws.amazon.com/iam/identity-center/) is the best approach for user provisioning because it treats users as users, not users as roles. Consequently, access controls are enforced for the querying user, nothing more. This approach eliminates over-provisioning and permits granular access control. Furthermore, IDC uses trusted identity propagation, meaning AWS propagates a user's identity wherever that user may operate within the AWS ecosystem. As a result, a user's identity always remains known and consistent as they navigate across AWS services, which is a key requirement for organizations to properly govern that user.\
  \
  Enabling IDC does not impact any existing access controls; it is additive. Immuta will manage the GRANTs for you using IDC if it is enabled and configured in Immuta. See the [protect data section](#protect-data) for instructions on mapping users from AWS IDC to user accounts in Immuta.

### Permissions

* `APPLICATION_ADMIN` Immuta permission to configure the integration
* `CREATE_S3_DATASOURCE` Immuta permission to register S3 prefixes
* The AWS account credentials or optional AWS IAM role you provide Immuta to configure the integration must
  * [have ownership of the buckets Immuta will enforce policies on](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-ownership-existing-bucket.html)
  * have the [permissions to perform the following actions](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazons3.html) to create locations and issue grants:
    * **accessgrantslocation** resource:
      * `s3:CreateAccessGrant`
      * `s3:DeleteAccessGrantsLocation`
      * `s3:GetAccessGrantsLocation`
      * `s3:UpdateAccessGrantsLocation`
    * **accessgrantsinstance** resource:
      * `s3:CreateAccessGrantsInstance`
      * `s3:CreateAccessGrantsLocation`
      * `s3:DeleteAccessGrantsInstance`
      * `s3:GetAccessGrantsInstance`
      * `s3:GetAccessGrantsInstanceForPrefix`
      * `s3:GetAccessGrantsInstanceResourcePolicy`
      * `s3:ListAccessGrants`
      * `s3:ListAccessGrantsLocations`
    * **accessgrant** resource:
      * `s3:DeleteAccessGrant`
      * `s3:GetAccessGrant`
    * **bucket** resource: `s3:ListBucket`
    * **role** resource:
      * `iam:GetRole`
      * `iam:PassRole`
    * **all resources**: `s3:ListAccessGrantsInstances`

### Set up S3 Access Grants instance

1. [Follow AWS documentation to create an Access Grants instance using the S3 console, AWS CLI, AWS SDKs, or the REST API](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-instance.html). AWS supports one Access Grants instance per region per AWS account.
2. [Follow the instructions at the top of the "Register a location" page in AWS documentation to create an AWS IAM role and edit the trust policy to give the S3 Access Grants service principal access to this role in the resource policy file](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-location.html). You will add this role to your integration configuration in Immuta so that Immuta can register this role with your Access Grants location. The policy should include at least the following permissions, but might need additional permissions depending on other local setup factors. An example trust policy is provided below.
   * `sts:AssumeRole`
   * `sts:SetSourceIdentity`

<details>

<summary>IAM role trust policy example</summary>

```json
{
  "Version": "2012-10-17",
    "Statement": [
    {
      "Sid": "Stmt1234567891011",
      "Effect": "Allow",
      "Principal": {
        "Service":"access-grants.s3.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole", 
        "sts:SetSourceIdentity"
      ]
    }
  ]
}           
```

</details>

3. [Follow the instructions at the top of the "Register a location" page in AWS documentation to create an IAM policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-location.html) with the following permissions, and attach the policy to the IAM role you created to grant the permissions to the role. The policy should include the following permissions. An example policy is provided below.

* `s3:GetObject`
* `s3:GetObjectVersion`
* `s3:GetObjectAcl`
* `s3:GetObjectVersionAcl`
* `s3:ListMultipartUploadParts`
* `s3:PutObject`
* `s3:PutObjectAcl`
* `s3:PutObjectVersionAcl`
* `s3:DeleteObject`
* `s3:DeleteObjectVersion`
* `s3:AbortMultipartUpload`
* `s3:ListBucket`
* `s3:ListAllMyBuckets`

<details>

<summary>IAM policy example</summary>

Replace **\<bucket\_arn>** in the example below with the ARN of the bucket scope that contains data you want to grant access to. If you plan to use [write access policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types), contact your Immuta representative to enable this feature. Otherwise, `ObjectLevelWritePermissions` can be omitted from your IAM policy.\
\
*Note: The resource for object-level permissions must end with a wildcard so that Immuta can grant access to objects inside that prefix.*

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ObjectLevelReadPermissions",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetObjectAcl",
                "s3:GetObjectVersionAcl",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "<bucket arn>/*"
            ]
        },
        {
            "Sid": "ObjectLevelWritePermissions",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectVersionAcl",
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "<bucket arn>/*"
            ]
        },
        {
            "Sid": "BucketLevelReadPermissions",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket"
            ],
            "Resource": [
                "<bucket arn>"
            ]
        }
    ]
}
```

</details>

If you use server-side encryption with AWS Key Management Service (AWS KMS) keys to encrypt your data, the following permissions are required for the IAM role in the policy. If you do not use this feature, do not include these permissions in your IAM policy:

* `kms:Decrypt`
* `kms:GenerateDataKey`

4. [Opt to create an AWS IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html) that Immuta can use to create Access Grants locations and issue grants. This role must have the S3 permissions listed in the [permissions section](#permissions). An example policy is provided below.

<details>

<summary>IAM policy example</summary>

Replace **\<role\_arn>** and **\<access\_grants\_instance\_arn>** in the example below with the ARNs of the role you created and your Access Grants instance, respectively. The Access Grants instance resource ARN should be scoped to apply to any future locations that will be created under this Access Grants instance. For example, `"Resource": "arn:aws:s3:us-east-2:6********499:access-grants/default*"` ensures that the role would have permissions for both of these locations:

* `arn:aws:s3:us-east-2:6********499:access-grants/default/newlocation1`
* `arn:aws:s3:us-east-2:6********499:access-grants/default/newlocation2`

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RolePermissions",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PassRole"
            ],
            "Resource": "<role_arn>"
        },
        {
            "Sid": "AccessGrants",
            "Effect": "Allow",
            "Action": [
                "s3:CreateAccessGrant",
                "s3:DeleteAccessGrantsLocation",
                "s3:GetAccessGrantsLocation",
                "s3:CreateAccessGrantsLocation",
                "s3:GetAccessGrantsInstance",
                "s3:GetAccessGrantsInstanceForPrefix",
                "s3:GetAccessGrantsInstanceResourcePolicy",
                "s3:ListAccessGrants",
                "s3:ListAccessGrantsLocations",
                "s3:ListAccessGrantsInstances",
                "s3:DeleteAccessGrant",
                "s3:GetAccessGrant"
            ],
            "Resource": [
                "<access_grants_instance_arn>"
            ]
        }
    ]
}
```

</details>

5. If you use AWS IAM Identity Center, associate [your IAM Identity Center instance with your S3 Access Grants instance](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-instance-idc.html). Then add the permissions listed in the sample policy below to your IAM policy, and attach the policy to the IAM role you created to grant the permissions to the role.

<details>

<summary>IAM policy example</summary>

Copy the JSON below and replace the following bracketed placeholder values with your own. For details about the actions and resource values, see the [IAM Identity Center API reference documentation](https://docs.aws.amazon.com/IAM/latest/APIReference/Welcome.html).

* **\<iam\_identity\_center\_instance\_arn>**: The [ARN of the instance of IAM Identity Center (`InstanceArn`)](https://docs.aws.amazon.com/singlesignon/latest/APIReference/API_Application.html) that is configured with the application.
* **\<iam\_identity\_center\_application\_arn\_for\_s3\_access\_grants>**: The [ARN of the S3 Access Grants instance (`ApplicationArn`)](https://docs.aws.amazon.com/singlesignon/latest/APIReference/API_Application.html) configured with IAM Identity Center.
* **\<aws\_account>**: Your AWS account ID.
* **\<identity\_store\_id>**: The globally [unique identifier for the identity store (`IdentityStoreId`)](https://docs.aws.amazon.com/singlesignon/latest/APIReference/API_InstanceMetadata.html) that is connected to the Identity Center instance. This value is generated when a new identity store is created.

```json
{
  "Sid": "sso",
  "Effect": "Allow",
  "Action": [
    "sso:DescribeInstance",
    "sso:DescribeApplication",
    "sso-directory:DescribeUsers"
  ],
  "Resource": [
    "<iam_identity_center_instance_arn>",
    "<iam_identity_center_application_arn_for_s3_access_grants>",
    "arn:aws:identitystore:::user/*",
    "arn:aws:identitystore::<aws_account>:identitystore/<identity_store_id>"
  ]
}, {
  "Sid": "idc",
  "Effect": "Allow",
  "Action": [
    "identitystore:DescribeUser",
    "identitystore:DescribeGroup"
  ],
  "Resource": [
    "<iam_identity_center_instance_arn>",
    "<iam_identity_center_application_arn_for_s3_access_grants>",
    "arn:aws:identitystore:::user/*",
    "arn:aws:identitystore::<aws_account>:identitystore/<identity_store_id>"
  ]
}
```

</details>

### Configure the integration in Immuta

1. In Immuta, click <i class="fa-gear">:gear:</i> **App Settings** in the navigation menu and click the **Integrations** tab.
2. Click **+ Add Integration**.
3. Select **Amazon S3** from the dropdown menu and click **Continue Configuration**.
4. Complete the connection details fields, where
   * **Friendly Name** is a name for the integration that is unique across all Amazon S3 integrations configured in Immuta.
   * **AWS Account ID** is the ID of your AWS account.
   * **AWS Region** is the AWS region to use.
   * **S3 Access Grants Location IAM Role ARN** is the role the S3 Access Grants service assumes to vend credentials to the grantee. When a grantee accesses S3 data, the Access Grants service attaches session policies and assumes this role in order to vend credentials scoped to a prefix or bucket to the grantee. This role needs full access to all paths under the S3 location prefix.
   * **S3 Access Grants S3 Location Scope** is the base S3 location that Immuta will use for this connection when registering S3 prefixes. This path must be unique across all S3 integrations configured in Immuta. During data source registration, this prefix is prepended to the data source prefixes to build the final path used to grant or revoke access to that data in S3. For example, a location prefix of `s3://research-data` would be prepended to the data source prefix `/demographics` to generate a final path of `s3://research-data/demographics`.
5. Select your authentication method:
   * **Automatically discover AWS credentials**: Searches and obtains credentials using the [AWS SDK's default credential provider chain](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html). This method requires a configured [IAM role for a service account (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). Contact your Immuta representative to customize your deployment and set up an IAM role for a service account that can give Immuta the credentials to set up the integration. Then, complete the steps below.
   * **Access using access key and secret access key**: Provide your **AWS Access Key ID** and **AWS Secret Access Key**.
6. Click **Verify Credentials**.
7. Click **Next** to review and confirm your connection information, and then click **Complete Setup**.

### Register S3 data

1. Follow the [Create an S3 data source guide](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/s3-tutorial) to register prefixes in Immuta.
2. [Recommended: Organize your data sources into domains and assign domain permissions to accountable teams.](/2026.2/configuration/domains/configure-domains)

To create an S3 data source using the API, see the [Create and manage an Amazon S3 data source API guide](/2026.2/developer-guides/api-intro/immuta-v1-api/connect-your-data/s3).

#### Editing an integration

You can edit the following settings for an existing Amazon S3 integration on the app settings page:

* friendly name
* authentication type and values (access key, secret, and role)

To edit settings for an existing integration via the API, see the [Configure an Amazon S3 integration API guide](/2026.2/developer-guides/api-intro/integrations-api/how-to-guides/s3-api#update-an-integration-configuration).

### Protect data

**Requirements**: `USER_ADMIN` Immuta permission and either the `GOVERNANCE` or `CREATE_S3_DATASOURCE` Immuta permission

1. [Build read or write subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types) in Immuta to enforce access controls.
2. Map AWS IAM principals to each Immuta user to ensure Immuta properly enforces policies:

   1. Click <i class="fa-users">:users:</i> **Identities** and select **Users** in the navigation menu.
   2. Navigate to the user's page and click the **more actions** icon next to their username.
   3. Select **Change S3 User** or **AWS IAM Role** from the dropdown menu.
   4. Use the dropdown menu to select the **User Type**. Then complete the S3 field. User and role names are case-sensitive. See the [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) for details.
      * [**AWS IAM role principals**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-roles): Only a single Immuta user can be mapped to an IAM role. This restriction prohibits enforcing policies on AWS users who could assume that role. Therefore, if using role principals, create a new user in Immuta that represents the role so that the role then has the permissions applied specifically to it.
      * [**AWS IAM user principals**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-users)
      * **AWS Identity Center user IDs**: You must use the numeric `User ID` value found in AWS IAM Identity Center, not the user's email address. Ensure that you have added the content to your IAM policy JSON as outlined in the [Set up S3 Access Grants instance section](#set-up-s3-access-grants-instance) above to allow Immuta to use AWS Identity Center.
      * **Unset (fallback to Immuta username)**: When selecting this option, the S3 username is assumed to be the same as the Immuta username.
   5. Click **Save**.

   See the [Mapping IAM principals in Immuta section](#mapping-iam-principals-in-immuta) for details about supported principals.

### Access data

**Requirement**: User must be subscribed to the data source in Immuta

1. [Request access to Amazon S3 data through S3 Access Grants](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-credentials.html). If you're accessing S3 data through one of the supported [S3 Access Grants integrations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-integrations.html) (such as Amazon EMR on EC2), that application will make this request on your behalf, so you can skip this step.
2. [Use the temporary credentials you received in the previous step to access the data in S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-get-data.html).

## S3 integration overview

Immuta's Amazon S3 integration allows users to apply [subscription policies](#policy-enforcement) to data in S3 to restrict what prefixes, buckets, or objects users can access. To enforce access controls on this data, Immuta creates S3 grants that are administered by S3 Access Grants, an AWS feature that defines access permissions to data in S3.

With this integration, users can avoid

* hand-writing AWS IAM policies
* managing AWS IAM role limits
* manually tracking what user or role has access to what files in AWS S3 and verifying those are consistent with intent

### S3 Access Grants components

To enforce controls on S3 data, Immuta interacts with several S3 Access Grants components:

* **Access Grants instance**: An Access Grants instance is a logical container for individual grants that specify who can access what level of data in S3 in your AWS account and region. AWS supports one Access Grants instance per region per AWS account.
* **Location**: A location specifies what data the Access Grants instance can grant access to. For example, registering a location with a scope of `s3://` allows Access Grants to manage access to all S3 buckets in that AWS account and region, whereas setting the bucket `s3://research-data` as the scope limits Access Grants to managing access to that single bucket for that location. When you configure the S3 integration in Immuta, you specify a location's scope and IAM assumed role, and Immuta registers the location in your Access Grants instance and associates it with the provided IAM role for you. Each S3 integration you configure in Immuta is associated with one location, and Immuta manages all grants in that location. Therefore, grants cannot be manually created by users in an Access Grants instance location that Immuta has registered and manages. During data source registration, this location scope is prepended to the data source prefixes to build the final path used to grant or revoke access to that data in S3. For example, a location scope of `s3://research-data` would be prepended to the data source prefix `/demographics` to generate a final path of `s3://research-data/demographics`.
* **Individual grants**: Individual permission grants in S3 Access Grants specify the identity that can access the data, the access level, and the location of the S3 data. Immuta creates a grant for each user subscribed to a prefix, bucket, or object by interacting with the Access Grants API. Each grant has its own ID and gives the user or role principle access to the data.
* **IAM assumed role**: This is an IAM role you create in S3 that has full access to all prefixes, buckets, and objects in the Access Grants location registered by Immuta. This IAM role is used to vend temporary credentials to users or applications. When a grantee requests temporary credentials, the S3 Access Grants service assumes this role to vend credentials scoped to the prefix, bucket, or object specified in the grant to the grantee. The grantee then uses these credentials to access S3 data. When configuring the integration in Immuta, you specify this role, and then Immuta associates this role with the registered location in the Access Grants instance.
* **Temporary credentials**: These just-in-time access credentials provide access to a prefix, bucket, or object with a permission level of READ or READWRITE in S3. When a user or application requests temporary credentials to access S3 data, the S3 Access Grants instance evaluates the request against the grants Immuta has created for that user. If a matching grant exists, S3 Access Grants assumes the IAM role associated with the location of the matching grant and scopes the permissions of the IAM session to the S3 prefix, bucket, or object specified by the grant and vends these temporary credentials to the requester. These credentials have a default timeout of 1 hour, but [this duration can be changed by the requester](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-credentials.html).

The diagram below illustrates how these S3 Access Grants components interact.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/2x1O1xdiHhydprRPXQbr/s3-integration.avif" alt=""><figcaption></figcaption></figure>

For more details about these Access Grants concepts, see the [S3 Access Grants documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-concepts.html).

### How does the integration work?

After an administrator creates an Access Grants instance and an assumed IAM role in their AWS account, an application administrator configures the Amazon S3 integration in Immuta. During configuration, the administrator provides the following connection information so that Immuta can create and register a location in that Access Grants instance:

* AWS account ID and region
* ARN for the existing Access Grants instance
* ARN for the assumed IAM role

When Immuta registers this location, it associates the assumed IAM role with the location. This allows the IAM role to create temporary credentials with access scoped to a particular S3 prefix, bucket, or object in the location. The IAM role you create for this location must have all the object- and bucket-level permissions listed in the [set up S3 Access Grants instance section](#set-up-s3-access-grants-instance) on all buckets and objects in the location; if it is missing permissions, the IAM role will not be able to grant those missing permissions to users or applications requesting temporary credentials.

In the example below, an application administrator registers the following location prefix and IAM role for their Access Grants instance in AWS account `123456`:

* **Location path**: `s3://`. This path allows a single Amazon S3 integration to manage all objects in S3 in that AWS account and region. Data owners can scope down access further when registering specific S3 prefixes and applying policies.
* **Location IAM role**: The `arn:aws:iam::123456:role/access-grants-role` IAM role will be used to vend temporary credentials to users and applications.

Immuta registers this location and associated IAM role in the user's Access Grants instance:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/qV20ljH3MErQw22LdCK9/s3-integration-configuration.png" alt=""><figcaption></figcaption></figure>

After the S3 integration is configured, a data owner can register S3 prefixes and buckets that are in the configured Access Grants location path to enforce access controls on resources. Immuta stores the connection information for the prefix so that the metadata can be used to create and enforce subscription policies on S3 data.

A data owner or governor can apply a subscription policy to a registered prefix, bucket, or object to control who can access objects beginning with that prefix or in that bucket after it is registered in Immuta. Once a subscription policy is created and Immuta users are subscribed to the prefix, bucket, or object, Immuta calls the Access Grants API to create a grant for each subscribed user, specifying the following parameters in the payload so that Access Grants can create and store a grant for each user:

* Access Grants location
* `READ` access
* User or role principle
* Registered prefix, bucket, or object

In the example below, a data owner registers the `s3://research-data/*` bucket, and Immuta stores the connection information in the Immuta metadata database. Once the user, Taylor, is subscribed to `s3://research-data/*`, Immuta calls the Access Grants API to create a grant for that user to allow them to read and write S3 data in that bucket:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/F8U9NltEgr7488aCFshn/s3-integration-prefix-registration.png" alt=""><figcaption></figcaption></figure>

### Integration health status

The status of the integration is visible on the integrations tab of the Immuta application settings page. If errors occur in the integration, a banner will appear in the Immuta UI with guidance for remediating the error.

The definitions for each status and the state of configured data platform integrations is available in the [response schema of the integrations API](/2026.2/developer-guides/api-intro/integrations-api/reference-guides/response-schema#integration-statuses). However, the UI consolidates these error statuses and provides detail in the error messages.

### Accessing S3 data

To access S3 data registered in Immuta, users must be subscribed to the prefix, bucket, or object in Immuta, and their principals must be [mapped to their Immuta user accounts](#mapping-iam-principals-in-immuta). Once users are subscribed, they request temporary credentials from S3 Access Grants. Access Grants looks up the grant ID associated with the requester. If no matching grant exists, they receive an access denied error. If one exists, Access Grants assumes the IAM role associated with the location and requests temporary credentials that are scoped to the prefix, bucket, or object and permissions specified by the individual grant. Access Grants vends the credentials to the requester, who uses those temporary credentials to access the data in S3.

In the example below, Taylor requests temporary credentials from S3 Access Grants. Access Grants looks up the grant ID (`1`) for that user, assumes the `arn:aws:iam::123456:role/access-grants-role` IAM role for the location, and vends temporary credentials to Taylor, who then uses the credentials to access the `research-data` bucket in S3:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/7fYi4n2Jdf9vmCjzcLah/s3-integration-access-data.png" alt=""><figcaption></figcaption></figure>

Note that when accessing data through S3 Access Grants, the user or application interacts directly with the Access Grants API to request temporary credentials; Immuta does not act in this process at all. See the diagram below for an illustration of the process for accessing data through S3 Access Grants.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/PXkZJV1DNOWMTPdKRMZ2/access-s3-process.png" alt=""><figcaption></figcaption></figure>

AWS services that support S3 Access Grants will request temporary credentials for users automatically. If users are not using a service that supports S3 Access Grants, they must have the [permissions listed in the AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetDataAccess.html) to [call the Access Grants API directly themselves](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-credentials.html) to request temporary credentials to access data through the access grant.

For a list of AWS services that support S3 Access Grants, see the [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-integrations.html).

### Policy enforcement

Immuta's S3 integration allows data owners and governors to apply object-level access controls on data in S3 through subscription policies. When a user is subscribed to a registered prefix, bucket, or object, Immuta calls the Access Grants API to create an individual grant that narrows the scope of access within the location to that registered prefix, bucket, or object. See the diagram below for a visualization of this process.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/zqsWdt6tB1y4VB4mly9R/s3-process-diagram.png" alt=""><figcaption></figcaption></figure>

When a user's entitlements change or a subscription policy is added to, updated, or deleted from a prefix, Immuta performs one of the following processes for each user subscribed to the registered prefix:

* **User added to the prefix**: Immuta specifies a permission (`READ` or `READWRITE`) for each user and uses the Access Grants API to create an individual grant for each user.
* **User updated**: Immuta deletes the current grant ID and creates a new one using the Access Grants API.
* **User deleted**: Immuta deletes the grant ID using the Access Grants API.

Immuta offers two [subscription policy access types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types) to manage read and write access to data in S3:

* **Read access policies** manage who can get objects from S3.
* **Write access policies** manage who can modify data in S3.

Data policies, which provide more granular controls by redacting or masking values in a table, are not supported for S3.

### Prefix registration

Data owners can register an S3 prefix at any level in the S3 path by [creating an Immuta data source](#register-s3-data). During this process, Immuta stores the connection information for use in [subscription policies](#policy-enforcement).

Each prefix added in the data registration workflow is created as a single Immuta data source, and a subscription policy added to a data source applies to any objects in that bucket or beginning with that prefix:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/kqeTgoSzN4pUsZrpADRI/registered-prefix-1.png" alt=""><figcaption></figcaption></figure>

Therefore, data owners should register prefixes or buckets at the lowest level of access control they need for that data. Using the example above, if the data owner needed to allow different users to access `s3://yellow-bucket/research-data/*` than those who should access `s3://yellow-bucket/analyst-data/*`, the data owner must register the `research-data/*` and `analyst-data/*` prefixes separately and then apply a subscription policy to those prefixes:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/Srvxe982eZvZmME1s1Dh/registered-prefix-2.png" alt=""><figcaption></figcaption></figure>

### Deleting registered prefixes

When an S3 data source is deleted, Immuta deletes all the grants associated with that prefix, bucket, or object in that location.

### User provisioning

Access can be managed in AWS using IAM users, roles, or Identity Center (IDC). Immuta [supports all three methods](#mapping-iam-principals-in-immuta) for user provisioning in the S3 integration.

However, if you manage access in AWS through IAM roles instead of users, user provisioning in Immuta must be done using IAM role principals. This means that if users share IAM roles, you could end up in a situation where you over-provision access to everyone in the IAM role.

See the guidelines below for the best practices to avoid this behavior if you currently use IAM roles to manage access.

1. **Enable** [**AWS IAM Identity Center (IDC)**](https://aws.amazon.com/iam/identity-center/) **(recommended)**: IDC is the best approach for user provisioning because it treats users as users, not users as roles. Consequently, access controls are enforced for the querying user, nothing more. This approach eliminates over-provisioning and permits granular access control. Furthermore, IDC uses trusted identity propagation, meaning AWS propagates a user's identity wherever that user may operate within the AWS ecosystem. As a result, a user's identity always remains known and consistent as they navigate across AWS services, which is a key requirement for organizations to properly govern that user.\
   \
   Enabling IDC does not impact any existing access controls; it is additive. Immuta will manage the GRANTs for you using IDC if it is enabled and configured in Immuta. See the [protect data section](#protect-data) for instructions on mapping users from AWS IDC to user accounts in Immuta.
2. **Create an IAM role per user**: If you do not have IDC enabled, create an IAM role per user that is unique to that user and assign that IAM role to each corresponding user in Immuta. Ensure that the IAM role cannot be shared with other users.\
   \
   This approach can be a challenge because there is an [IAM role max limit of 5,000 per AWS account](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entities).
3. **Request on behalf of IAM roles (not recommended)**: Create users in Immuta that map to each of your existing IAM roles. Then, when users request access to data, they request on behalf of the IAM role user rather than themselves.\
   \
   This approach is not recommended because everyone in that role will gain access to data when granted access through a policy, and adding future users to that role will also grant access. Furthermore, it requires policy authors and approvers to understand what role should have access to what data.

#### Mapping IAM principals in Immuta

{% hint style="info" %}
**Names are case-sensitive**

The IAM role name and IAM user name are case-sensitive. See the [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) for details.
{% endhint %}

Immuta supports mapping an Immuta user to AWS in one of the following ways:

* [AWS IAM Identity Center user IDs](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
* [IAM role principals](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-roles): Only a single Immuta user can be mapped to an IAM role. This restriction prohibits enforcing policies on AWS users who could assume that role. Therefore, if using role principals, create a new user in Immuta that represents the role so that the role then has the permissions applied specifically to it.
* [IAM user principals](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-users)

See the [protect data section](#protect-data) for instructions on mapping principals to user accounts in Immuta.

### Existing S3 integrations

The Amazon S3 integration will not interfere with existing legacy S3 integrations, and multiple S3 integrations can exist in a single Immuta tenant.

### Supported AWS services

AWS services that support S3 Access Grants will request temporary credentials for users automatically. If users are not using a service that supports S3 Access Grants, they must have the [permissions listed in the AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetDataAccess.html) to [call the Access Grants API directly themselves](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-credentials.html) to request temporary credentials to access data through the access grant.

For a list of AWS services that support S3 Access Grants, see the [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-integrations.html).

### Limitations

* During private preview, Immuta supports up to 500 prefixes (data sources) and up to 20 Immuta users that are mapped to S3 identities principals. This is a preview limitation that will be removed in a future phase of the integration.
* S3 Access Grants allows 100,000 grants per region per account. Thus, if you have 5 Immuta users with access to 20,000 registered prefixes, you would reach this limit. [See AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants-limitations.html) for details.
* The following Immuta features are not currently supported by the integration in private preview:
  * Audit
  * Data policies
  * Impersonation
  * Schema monitoring
  * Tag ingestion

[^1]: See the [User provisioning](#user-provisioning) section for more details about this recommendation and alternatives.


# Azure Synapse Analytics

Learn about how Immuta generates policy-enforced views in your Azure Synapse Analytics Dedicated SQL pool to govern your data

In this integration, Immuta generates policy-enforced views in a schema in your configured Azure Synapse Analytics Dedicated SQL pool for tables registered as Immuta data sources.

## [Getting started](/2026.2/configuration/integrations/azure-synapse-analytics/synapse)

This guide outlines how to integrate Azure Synapse Analytics with Immuta.

## How-to guide

[Azure Synapse Analytics configuration](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration): Configure the integration in Immuta.

## Reference guides

* [Azure Synapse Analytics integration reference guide](/2026.2/configuration/integrations/azure-synapse-analytics/reference-guides/azure-synapse-analytics): This guide describes the design and components of the integration.
* [Azure Synapse Analytics pre-configuration details](/2026.2/configuration/integrations/azure-synapse-analytics/reference-guides/pre-configuration): This guide describes the prerequisites, supported features, and limitations of the integration.


# Getting Started with Azure Synapse Analytics

Learn how to best implement Immuta with Azure Synapse Analytics in your data ecosystem

The how-to guides linked on this page illustrate how to integrate Azure Synapse Analytics with Immuta. See the [reference guide](/2026.2/configuration/integrations/azure-synapse-analytics/reference-guides/azure-synapse-analytics) for information about the Azure Synapse Analytics integration.

**Requirement**: A running Dedicated SQL pool

{% stepper %}
{% step %}
**Connect your technology**

These guides provide instructions on getting your data set up in Immuta.

1. [Configure your Azure Synapse Analytics integration](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration): Configure an Azure Synapse Analytics integration with Immuta so that Immuta can create policy protected views for your users to query.
2. [Register Azure Synapse Analytics data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/synapse-tutorial): This will register your data objects into Immuta and allow you to start dictating access through global policies.
3. [Organize your data sources into domains and assign domain permissions to accountable teams](/2026.2/configuration/domains/configure-domains): Use domains to segment your data and assign responsibilities to the appropriate team members. These domains will then be used in policies.
   {% endstep %}

{% step %}
**Register your users**

These guides provide instructions on getting your users set up in Immuta.

1. [Connect an IAM](/2026.2/configuration/people/getting-started): Bring the IAM your organization already uses and allow Immuta to register your users for you.
2. [Map external user IDs from Azure Synapse Analytics to Immuta](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping): Ensure the user IDs in Immuta, Azure Synapse Analytics, and your IAM are aligned so that the right policies impact the right users.
   {% endstep %}

{% step %}
**Add data metadata**

These guides provide instructions on getting your data metadata set up in Immuta.

1. [Connect an external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure): Bring the external catalog your organization already uses and allow Immuta to continually sync your tags with your data sources for you.
2. [Run identification](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/enable-sdd): Identification allows you to automate data tagging using identifiers that detect certain column names.
   {% endstep %}

{% step %}
**Start using policies**

These guides provide instructions on using policies and audit for the first time.

1. [Author a global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial): Once you add your data metadata to Immuta, you can immediately create policies that utilize your tags and apply to your tables. Subscription policies can be created to dictate access to data sources.
2. [Author a global data policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial): Data metadata can also be used to create data policies that apply to data sources as they are registered in Immuta. Data policies dictate what data a user can see once they are granted access to a data source. Using catalog tags you can create proactive policies, knowing that they will apply to data sources as they are added to Immuta with the automated tagging.
3. [Configure audit](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam): Once you have your data sources and users, and policies granting them access, you can set up audit export. This will export the audit logs from policy changes and tagging updates.
   {% endstep %}
   {% endstepper %}


# Configure Azure Synapse Analytics Integration

This page provides a tutorial for enabling the Azure Synapse Analytics integration on the Immuta app settings page. To configure this integration via the Immuta API, see the [Integrations API getting started guide](/2026.2/developer-guides/api-intro/integrations-api/getting-started).

For an overview of the integration, see the [Azure Synapse Analytics overview](/2026.2/configuration/integrations/azure-synapse-analytics/reference-guides/azure-synapse-analytics) documentation.

## Requirement

A running Dedicated SQL pool is required.

## Prerequisites

If you are using the OAuth authentication method,

* Ensure that Microsoft Entra ID is on the same account as the Azure Synapse Analytics workspace and dedicated SQL pool.
* [Set up OAuth via Microsoft Entra ID app registration with a **client secret**](https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-service-principal-tutorial?view=azuresql#create-an-application-in-microsoft-entra-id).
* Select **Accounts in this organizational directory only** as the account type.

## Add an Azure Synapse Analytics integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Click the **Integrations** tab.
3. Click the **+Add Integration** button and select **Azure Synapse Analytics** from the dropdown menu.
4. Complete the **Host**, **Port**, **Immuta Database**, and **Immuta Schema** fields.
5. Opt to check the **Enable Impersonation** box and customize the **Impersonation Role** name as needed. This will allow users to natively impersonate another user. Once you finish configuring the integration, you can grant the `IMPERSONATE_USER` permission to Immuta users. See the [Managing users and permissions guide](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#add-permission-to-user) for instructions.
6. Opt to update the **User Profile Delimiters**. This will be necessary if any of the provided symbols are used in user profile information.

### Select your configuration method

You have two options for configuring your Azure Synapse Analytic environment:

* [**Automatic setup**](#automatic-setup): Grant Immuta one-time use of credentials to automatically configure your environment and the integration.
* [**Manual setup**](#manual-setup): Run the Immuta script in your Azure Synapse Analytics environment yourself to configure the integration.

#### Automatic setup

Enter the username and password in the **Privileged User Credentials** section.

#### Manual setup

1. Select **Manual**.
2. Download, fill out the appropriate fields, and run the bootstrap master script and bootstrap script linked in the **Setup** section. *Note: The **master script** is not required if you're using the OAuth authentication method.*
3. Select the authentication method:
   1. **Username and Password**: Enter the **username** and **password** in the **Immuta System Account Credentials** section. The username and password provided must be the credentials that were set in the bootstrap master script when you created the user.
   2. **Entra ID OAuth Client Secret**: The values below can be found on the overview page of the application you created in Microsoft Entra ID. Before you enter this information, ensure you have completed the [prerequisites for OAuth authentication listed above](#prerequisites).

      1. **Display Name:** This must match the name of the OAuth application you registered.
      2. **Tenant Id**
      3. **Client Id**
      4. **Client Secret:** Enter the **Value** of the secret, not the secret ID.

      ![](https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/UdfuzFaQ11vM7sJnTzLp/oauth-client-secret-value.png)

### Save the configuration

Click **Save**.

### Register data

[Register Azure Synapse Analytics data in Immuta](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/synapse-tutorial).

## Edit an Azure Synapse Analytics integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Navigate to the Integrations tab and click the **down arrow** next to the Azure Synapse Analytics Integration.
3. Edit the field you want to change. *Note any field shadowed is not editable, and the integration must be disabled and re-installed to change it.*
4. Use the authentication method and credentials you provided when initially configuring the integration.
5. Click **Save**.

{% hint style="info" %}
**Immuta requires temporary, one-time use of credentials with specific permissions.**

When performing edits to an integration, Immuta requires temporary, one-time use of credentials of a Superuser or a user with the Manage GRANTS permission

Alternatively, you can download the **Edit Script** from your Azure Synapse Analytics configuration on the Immuta app settings page and run it in Azure Synapse Analytics.
{% endhint %}

## Remove an Azure Synapse Analytics integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Navigate to the Integrations tab and click the **down arrow** next to the Azure Synapse Analytics Integration.
3. Click the **checkbox** to disable the integration.
4. Enter the credentials that were used to initially configure the integration.
5. Click **Save**.


# Reference Guides


# Azure Synapse Analytics Integration

This page describes the Azure Synapse Analytics integration, through which Immuta applies policies directly in Azure Synapse Analytics. For a tutorial on configuring Azure Synapse Analytics see the [Azure Synapse Integration page](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration).

## Overview

The Azure Synapse Analytics is a policy push integration that allows Immuta to apply policies directly in Azure Synapse Analytics Dedicated SQL pools without the need for users to go through a proxy. Instead, users can work within their existing Synapse Studio and have per-user policies dynamically applied at query time.

## Architecture

This integration works on a per-Dedicated-SQL-pool basis: all of Immuta's policy definitions and user entitlements data need to be in the same pool as the target data sources because Dedicated SQL pools do not support cross-database joins. Immuta creates schemas inside the configured Dedicated SQL pool that contain policy-enforced views that users query.

When the integration is configured, the Application Admin specifies the

* **Immuta database**: This is the pre-existing database Immuta uses. Immuta will create views from the tables contained in this database, and all schemas and views created by Immuta will exist in this database, such as the schemas `immuta_system`, `immuta_functions`, and the `immuta_procedures` that contain the tables, views, UDFs, and stored procedures that support the integration.
* **Immuta schema**: The schema that Immuta manages. All views generated by Immuta for tables registered as data sources will be created in this schema.
* **User profile delimiters**: Since Azure Synapse Analytics dedicated SQL pools do not support array or hash objects, certain user access information is stored as delimited strings; the Application Admin can modify those delimiters to ensure they do not conflict with possible characters in strings.

For a tutorial on configuring the integration see the [Azure Synapse Integration page](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration).

### Data source naming convention

Synapse data sources are represented as views and are under one schema instead of a database, so their view names are a combination of their schema and table name, separated by an underscore.

For example, with a configuration that uses `IMMUTA` as the schema in the database `dedicated_pool`, the view name for the data source `dedicated_pool.tpc.case` would be `dedicated_pool.IMMUTA.tpc_case`.

You can see the view information on the data source details page under **Connection Information**.

## Policy enforcement

This integration uses webhooks to keep views up-to-date with the corresponding Immuta data sources. When a data source or policy is created, updated, or disabled, a webhook is called that creates, modifies, or deletes the dynamic view in the Immuta schema. *Note that only standard views are available because Azure Synapse Analytics Dedicated SQL pools do not support secure views.*

## Integration health status

The status of the integration is visible on the integrations tab of the Immuta application settings page. If errors occur in the integration, a banner will appear in the Immuta UI with guidance for remediating the error.

The definitions for each status and the state of configured data platform integrations is available in the [response schema of the integrations API](/2026.2/developer-guides/api-intro/integrations-api/reference-guides/response-schema#integration-statuses). However, the UI consolidates these error statuses and provides detail in the error messages.

## Data flow

1. An Immuta Application Administrator [configures the Azure Synapse Analytics integration](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration), registering their initial Synapse Dedicated SQL pool with Immuta.
2. Immuta creates Immuta schemas inside the configured Synapse Dedicated SQL pool.
3. A Data Owner [registers Azure Synapse Analytics tables](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/synapse-tutorial) in Immuta as data sources. A Data Owner, Data Governor, or Administrator [creates or changes a policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/policies-explained) or [user](/2026.2/configuration/people/immuta-users/how-to-guides/managing-attribute-and-group) in Immuta.
4. Data source metadata, tags, user metadata, and policy definitions are stored in Immuta's Metadata Database.
5. The Immuta Web Service calls a stored procedure that modifies the user entitlements or policies and updates data source view definitions as necessary.
6. An Azure Synapse Analytics user who is subscribed to the data source in Immuta [queries the corresponding data source view](/2026.2/governance/data-consumers/query-data/synapse) in Azure Synapse Analytics and sees policy-enforced data.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/2hf4xofEEOJYLd5r1Lp6/synapse-integration.png" alt=""><figcaption></figcaption></figure>


# Azure Synapse Analytics Pre-Configuration Details

This page describes the Azure Synapse integration, configuration options, and features. See the [Azure Synapse integration page](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration) for a tutorial on enabling the integration and these features through the app settings page.

## Feature availability

| Project Workspaces | Tag Ingestion | User Impersonation   | Query Audit | Multiple Integrations |
| ------------------ | ------------- | -------------------- | ----------- | --------------------- |
| :x:                | :x:           | :white\_check\_mark: | :x:         | :white\_check\_mark:  |

## Prerequisite

A running dedicated SQL pool

## Authentication methods

The Azure Synapse Analytics integration supports the following authentication methods to configure the integration and create data sources:

* **Username and password**: Immuta supports SQL authentication with username and password for Azure Synapse Analytics. See the [SQL Authentication in Azure Synapse Analytics documentation](https://learn.microsoft.com/en-us/azure/synapse-analytics/sql/sql-authentication?tabs=serverless) for details.
* **OAuth authentication with Microsoft Entra ID**: You can use this authentication method to register data sources or configure the Azure Synapse Analytics integration using the [manual setup method](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration#manual-setup). To use this authentication method, OAuth must be set up via [Microsoft Entra ID app registration with a **client secret**](https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-service-principal-tutorial?view=azuresql#create-an-application-in-microsoft-entra-id). See the [Microsoft Entra documentation](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols) for details about using OAuth authentication with Microsoft Entra ID.

## Tag ingestion

Immuta cannot ingest tags from Synapse, but you can connect any of these [supported external catalogs](/2026.2/configuration/manage-data-metadata/catalogs/reference-guides/pre-configuration) to work with your integration.

## User impersonation

Impersonation allows users to query data as another Immuta user in Azure Synapse Analytics. To enable user impersonation, see the [Configure Azure Synapse Analytics integration guide](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration).

## Multiple integrations

A user can [configure multiple integrations of Synapse](/2026.2/configuration/integrations/azure-synapse-analytics/configure-azure-synapse-analytics-integration) to a single Immuta tenant.

## Limitations

* Immuta does not support the following masking types in this integration because of limitations with dedicated SQL pools (linked below). Any column assigned one of these masking types will be masked to NULL:
  * Reversible Masking: Synapse UDFs currently only support SQL, but Immuta needs to execute code (such as JavaScript or Python) to support this masking feature. See the [Synapse Documentation for details](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-function-sql-data-warehouse?view=azure-sqldw-latest).
  * Format Preserving Masking: Synapse UDFs currently only support SQL, but Immuta needs to execute code (such as JavaScript or Python) to support this masking feature. See the [Synapse Documentation for details](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-function-sql-data-warehouse?view=azure-sqldw-latest).
  * Regex: The built in string replace function does not support full regex. See the [Synapse Documentation for details](https://docs.microsoft.com/en-us/sql/t-sql/functions/replace-transact-sql?view=azure-sqldw-latest).
* The delimiters configured when enabling the integration cannot be changed once they are set. To change the delimiters, the integration has to be disabled and re-enabled.
* If the generated view name is more than 128 characters, then the view name is shortened to 128 characters. This could cause collisions between view names if the shortened version is the same for two different data sources.
* For proper updates, the dedicated SQL pools have to be running when changes are made to users or data sources in Immuta.


# Databricks

Learn about Immuta's integrations for Databricks

Immuta offers two integrations for Databricks:

* [Databricks Unity Catalog integration](/2026.2/configuration/integrations/databricks/databricks-unity-catalog): This integration supports working with database objects registered in Unity Catalog.
* [Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark): This integration supports working with [database objects registered in the legacy Hive metastore](https://docs.databricks.com/en/database-objects/hive-metastore.html).

## Which integration should you use?

To determine which integration you should use, evaluate the following elements:

* **Cluster runtime**
  * **Databricks Runtime 11.3 and newer**: See the list below to determine which integration is supported for your data's location.
* **Location of data: Where is your data?**
  * **Legacy Hive metastore**: Databricks recommends that you migrate all data from the legacy Hive metastore to Unity Catalog. However, when this migration is not possible, use the [Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark) to protect securables registered in the Hive metastore.
  * **Unity Catalog**: To protect securables registered in the Unity Catalog metastore, use the [Databricks Unity Catalog integration](/2026.2/configuration/integrations/databricks/databricks-unity-catalog).
  * **Legacy Hive metastore and Unity Catalog**: If you need to work with database objects registered in both the legacy Hive metastore and in Unity Catalog, [metastore magic](#metastore-magic) allows you to use both integrations.

## Metastore magic

Databricks metastore magic allows you to migrate your data from the Databricks legacy Hive metastore to the Unity Catalog metastore while protecting data and maintaining your current processes in a single Immuta instance.

Databricks metastore magic is for organizations who intend to use the [Databricks Unity Catalog integration](/2026.2/configuration/integrations/databricks/databricks-unity-catalog), but must still protect tables in the Hive metastore until they can migrate all of their data to Unity Catalog.

### Requirement

Unity Catalog support is enabled in Immuta.

### Databricks metastores and Immuta policy enforcement

Databricks has two built-in metastores that contain metadata about your tables, views, and storage credentials:

* **Legacy Hive metastore**: Created at the workspace level. This metastore contains metadata of the registered securables in that workspace available to query.
* **Unity Catalog metastore**: Created at the account level and is attached to one or more Databricks workspaces. This metastore contains metadata of the registered securables available to query. All clusters on that workspace use the configured metastore and all workspaces that are configured to use a single metastore share those securables.

Databricks allows you to use the legacy Hive metastore and the Unity Catalog metastore simultaneously. However, Unity Catalog does not support controls on the Hive metastore, so you must attach a Unity Catalog metastore to your workspace and move existing databases and tables to the attached Unity Catalog metastore to use the governance capabilities of Unity Catalog.

Immuta's Databricks Spark integration and Unity Catalog integration enforce access controls on the Hive and Unity Catalog metastores, respectively. However, because these metastores have two distinct security models, users were discouraged from using both in a single Immuta instance before metastore magic; the Databricks Spark integration and Unity Catalog integration were unaware of each other, so using both concurrently caused undefined behavior.

### Databricks metastore magic solution

Metastore magic reconciles the distinct security models of the legacy Hive metastore and the Unity Catalog metastore, allowing you to use multiple metastores (specifically, the Hive metastore or [AWS Glue Data Catalog](https://docs.databricks.com/archive/external-metastores/aws-glue-metastore.html) alongside Unity Catalog metastores) within a Databricks workspace and single Immuta instance and keep policies enforced on all your tables as you migrate them. The diagram below shows Immuta enforcing policies on registered tables across workspaces.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/FZwy48p8qnGt464mqIO4/metastore-magic.png" alt=""><figcaption></figcaption></figure>

In clusters A and D, Immuta enforces policies on data sources in each workspace's Hive metastore and in the Unity Catalog metastore shared by those workspaces. In clusters B, C, and E (which don't have Unity Catalog enabled in Databricks), Immuta enforces policies on data sources in the Hive metastores for each workspace.

#### Enforce policies as you migrate

With metastore magic, the Databricks Spark integration enforces policies *only* on data in the Hive metastore, while the Unity Catalog integration enforces policies on tables in the Unity Catalog metastore.

To enforce plugin-based policies on Hive metastore tables and Unity Catalog native controls on Unity Catalog metastore tables, enable the [Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark) and the Databricks Unity Catalog integration. Note that some Immuta policies are not supported in the Databricks Unity Catalog integration. See the [Databricks Unity Catalog integration reference guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide#feature-limitations) for details.

#### Enforcing policies on Databricks SQL

Databricks SQL cannot run the Databricks Spark plugin to protect tables, so Hive metastore data sources will not be policy enforced in Databricks SQL.

To enforce policies on data sources in Databricks SQL, use [Hive metastore table access controls](https://docs.databricks.com/data-governance/table-acls/table-acl.html) to manually lock down Hive metastore data sources and the Databricks Unity Catalog integration to protect tables in the Unity Catalog metastore. Table access control is enabled by default on SQL warehouses, and any Databricks cluster without the Immuta plugin must have table access control enabled.


# Databricks Spark

Learn about how you can register data from the Databricks legacy Hive metastore and govern access to that data

This integration enforces policies on Databricks securables registered in the legacy Hive metastore. Once these securables are registered as Immuta data sources, users can query policy-enforced data on Databricks clusters.

The guides in this section outline how to integrate Databricks Spark with Immuta.

## [Getting started](/2026.2/configuration/integrations/databricks/databricks-spark/databricks-spark-getting-started)

This getting started guide outlines how to integrate Databricks with Immuta.

## How-to guides

* [Configure a Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration)
* [Manually update your Databricks cluster](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/cluster-update): Manually update your cluster to reflect changes in the Immuta init script or cluster policies.
* [Install a trusted library](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/installation): Register a Databricks library with Immuta as a trusted library to avoid Immuta security manager errors when using third-party libraries.
* [Project UDFs cache settings](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/project-udfs): Raise the caching on-cluster and lower the cache timeouts for the Immuta web service to allow use of project UDFs in Spark jobs.
* [Run R and Scala spark-submit jobs on Databricks](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/spark-submit): Run R and Scala `spark-submit` jobs on your Databricks cluster.
* [DBFS access](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/access-dbfs): Access DBFS in Databricks for non-sensitive data.
* [Troubleshooting](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/troubleshooting): Resolve errors in the Databricks Spark configuration.

## Reference guides

* [Databricks Spark integration configuration](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks): This guide describes the design and components of the integration.
* [Security and compliance](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/security-and-compliance): This guide provides an overview of the Immuta features that provide security for your users and Databricks clusters and that allow you to prove compliance and monitor for anomalies.
* [Registering and protecting data](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/registering-and-protecting-data): This guide provides an overview of registering Databricks securables and protecting them with Immuta policies.
* [Accessing data](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/accessing-data): This guide provides an overview of how Databricks users access data registered in Immuta.


# Getting Started with Databricks Spark

The how-to guides linked on this page illustrate how to integrate Databricks Spark with Immuta.

**Requirements**

* If **Databricks Unity Catalog is enabled** in a Databricks workspace, you must use an [Immuta cluster policy](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#cluster-policies) when you set up the Databricks Spark integration to create an Immuta-enabled cluster.
* If **Databricks Unity Catalog is not enabled** in your Databricks workspace, you must disable Unity Catalog in your Immuta tenant before proceeding with your configuration of Databricks Spark:
  1. Navigate to the <i class="fa-gear">:gear:</i> **App Settings** page and click **Integration Settings**.
  2. Uncheck the **Enable Unity Catalog** checkbox.
  3. Click **Save**.

{% stepper %}
{% step %}
**Connect your technology**

These guides provide instructions for getting your data set up in Immuta.

1. [Configure your Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration).
2. [Register Databricks securable objects in Immuta as data sources.](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/databricks-tutorial)
3. [Organize your data sources into domains and assign domain permissions to accountable teams (recommended)](/2026.2/configuration/domains/configure-domains): Use domains to segment your data and assign responsibilities to the appropriate team members. These domains will then be used in policies, audit, and identification.
   {% endstep %}

{% step %}
**Register your users**

These guides provide instructions on setting up your users in Immuta.

1. [Integrate an IAM with Immuta](/2026.2/configuration/people/getting-started): Connect the IAM your organization already uses and allow Immuta to register your users for you.
2. [Map external user IDs from Databricks to Immuta](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping): Ensure the user IDs in Immuta, Databricks, and your IAM are aligned so that the right policies impact the right users.
   {% endstep %}

{% step %}
**Add data metadata**

These guides provide instructions on getting your data metadata set up in Immuta for use in policies.

1. [Connect an external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure): Connect the external catalog your organization already uses and allow Immuta to continually sync your tags with your data sources for you.
2. [Run identification](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/enable-sdd): Identification allows you to automate data tagging using identifiers that detect certain data patterns.
   {% endstep %}

{% step %}
**Protect and monitor data access**

These guides provide instructions on authoring policies and auditing data access.

* [Author a global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial): Once you add your data metadata to Immuta, you can immediately create policies that utilize your tags and apply to your tables. Subscription policies can be created to dictate access to data sources.
* [Author a global data policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial): Data metadata can also be used to create data policies that apply to data sources as they are registered in Immuta. Data policies dictate what data a user can see once they are granted access to a data source. Using catalog and identification applied tags you can create proactive policies, knowing that they will apply to data sources as they are added to Immuta with the automated tagging.
* [Configure audit](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam): Once you have your data sources and users, and policies granting them access, you can set up audit export. This will export the audit logs from user queries, policy changes, and tagging updates.
  {% endstep %}
  {% endstepper %}


# How-to Guides


# Configure a Databricks Spark Integration

## Permissions

* `APPLICATION_ADMIN` Immuta permission
* `CAN MANAGE` Databricks privilege on the cluster

## Requirements

* A Databricks workspace with the Premium tier, which includes cluster policies (required to configure the Spark integration)
* A cluster that uses one of these supported Databricks Runtimes:
  * 11.3 LTS
  * 14.3
* Supported languages
  * Python
  * R (not supported for Databricks Runtime 14.3)
  * Scala (not supported for Databricks Runtime 14.3)
  * SQL
* A Databricks cluster that is one of these supported compute types:
  * [All-purpose compute](https://docs.databricks.com/en/compute/index.html#types-of-compute)
  * [Job compute](https://docs.databricks.com/en/compute/index.html#types-of-compute)
* Custom access mode
* A Databricks workspace and cluster with the ability to directly make HTTP calls to the Immuta web service. The Immuta web service also must be able to connect to and perform queries on the Databricks cluster, and to call [Databricks workspace APIs](https://docs.databricks.com/api/workspace/introduction).

## Prerequisites

* Enable [OAuth M2M authentication ](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html)(recommended) or [​personal access tokens](https://docs.databricks.com/administration-guide/access-control/tokens.html).
* [Disable Photon](https://docs.databricks.com/en/compute/photon.html#configure-photon-enablement) by setting `runtime_engine` to `STANDARD` using the [Clusters API](https://docs.databricks.com/api/workspace/clusters). Immuta does not support clusters with Photon enabled. Photon is enabled by default on compute running Databricks Runtime 9.1 LTS or newer and must be manually disabled before setting up the integration with Immuta.
* Restrict the set of Databricks principals who have `CAN MANAGE` [privileges on Databricks clusters](https://docs.databricks.com/en/compute/clusters-manage.html#compute-permissions) where the Spark plugin is installed. This is to prevent editing [environment variables or Spark configuration](https://docs.google.com/document/d/1QyXHVVD5wHVd3h28S7KkT-V3RDJbWqbtovphBhRSmZQ/edit#heading=h.8kwz75d2w1dv), editing cluster policies, or removing the Spark plugin from the cluster, all of which would cause the Spark plugin to stop working.
* If **Databricks Unity Catalog is enabled** in a Databricks workspace, you must use an Immuta cluster policy when you set up the Databricks Spark integration to create an Immuta-enabled cluster. See the [configure cluster policies](#configure-cluster-policies) section below for guidance.
* If **Databricks Unity Catalog is not enabled** in your Databricks workspace, you must disable Unity Catalog in your Immuta tenant before proceeding with your configuration of Databricks Spark:
  1. Navigate to the <i class="fa-gear">:gear:</i> **App Settings** page and click **Integration Settings**.
  2. Uncheck the **Enable Unity Catalog** checkbox.
  3. Click **Save**.

## Add the integration on the app settings page

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in Immuta.
2. Navigate to **HDFS** > **System API Key** and click **Generate Key**.
3. Click **Save** and then **Confirm**. If you do not save and confirm, the system API key will not be saved.
4. Scroll to the **Integration Settings** section.
5. Click **+ Add Native Integration** and select **Databricks Spark Integration** from the dropdown menu.
6. Complete the **Hostname** field.
7. Enter a **Unique ID** for the integration. The unique ID is used to name cluster policies clearly, which is important when managing several Databricks Spark integrations. As cluster policies are workspace-scoped, but multiple integrations might be made in one workspace, this ID lets you distinguish between different sets of cluster policies.
8. Select the identity manager that should be used when mapping the current Spark user to their corresponding identity in Immuta from the **Immuta IAM** dropdown menu. This should be set to reflect the identity manager you use in Immuta (such as Entra ID or Okta).
9. Choose an **Access Model**. The **Protected until made available by policy** option [disallows reading and writing tables not protected by Immuta](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables), whereas the **Available until protected by policy** option allows it.

{% hint style="warning" %}
**Behavior change in Immuta v2025.1 and newer**

If a table is registered in Immuta and does not have a subscription policy applied to it, that data will be visible to users in Databricks, even if the **Protected until made available by policy** setting is enabled.

If you have enabled this setting, author an "Allow individually selected users" [global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial) that applies to all data sources.
{% endhint %}

10. Select the **Storage Access Type** from the dropdown menu.
11. Opt to add any **Additional Hadoop Configuration Files**.
12. Click **Add Native Integration,** and then click **Save** and **Confirm**. This will restart the application and save your Databricks Spark integration. (It is normal for this restart to take some time.)

The Databricks Spark integration will not do anything until your cluster policies are configured, so even though your integration is saved, continue to the next section to configure your cluster policies so the Spark plugin can manage authorization on the Databricks cluster.

## Configure cluster policies

1. Click **Configure Cluster Policies**.
2. Select one or more cluster policies in the matrix. Clusters running Immuta with Databricks Runtime 14.3 can only use Python and SQL. You can make changes to the policy by clicking **Additional Policy Changes** and editing the environment variables in the text field or by downloading it. See the [Spark environment variables reference guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration) for information about each variable and its default value. Some common settings are linked below:
   1. [Audit all queries](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_audit_all_queries)
   2. [Scratch paths](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_scratch_paths)
   3. [User impersonation](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_allowed_impersonation_users) (you can also [prevent users from changing impersonation in a session](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_single_impersonation_user))
3. Select your Databricks Runtime.
4. Use one of the two installation types described below to apply the policies to your cluster:
   * **Automatically push cluster policies:** This option allows you to automatically push the cluster policies to the configured Databricks workspace. This will overwrite any cluster policy templates previously applied to this workspace.
     1. Select the **Automatically Push Cluster Policies** radio button.
     2. Enter your **Admin Token**. This token must be for a user who has the [required Databricks privilege](#permissions). This will give Immuta temporary permission to push the cluster policies to the configured Databricks workspace and overwrite any cluster policy templates previously applied to the workspace.
     3. Click **Apply Policies**.
   * **Manually push cluster policies:** Enabling this option allows you to manually push the cluster policies and the init script to the configured Databricks workspace.
     1. Select the **Manually Push Cluster Policies** radio button.
     2. Click **Download Init Script** and set the **Immuta plugin init script** as a cluster-scoped init script in Databricks by following the [Databricks documentation](https://docs.databricks.com/en/init-scripts/cluster-scoped.html).
     3. Click **Download Policies**, and then [manually add this cluster policy to your Databricks](https://docs.databricks.com/aws/en/admin/clusters/policies) workspace.
        1. Ensure that the `init_scripts.0.workspace.destination` in the policy matches the file path to the init script you configured above.
        2. The Immuta cluster policy references Databricks Secrets for several of the sensitive fields. These secrets must be manually created if the cluster policy is not automatically pushed. Use Databricks API or CLI to push the proper secrets.
5. Click **Close**, and then click **Save** and **Confirm**.
6. Apply the cluster policy generated by Immuta to the cluster with the Spark plugin installed by following the [Databricks documentation](https://docs.databricks.com/api/workspace/clusters/create).

## Map users and grant them access to the cluster

1. [Map external user IDs from Databricks to Immuta.](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping)
2. Give users the `Can Attach To` permission on the cluster.


# Manually Update Your Databricks Cluster

Manually update your Databricks cluster to reflect changes in cluster policies or the Immuta init script

If a Databricks cluster needs to be manually updated to reflect changes in the Immuta init script or cluster policies, you can remove and set up your integration again to get the updated policies and init script.

1. Log in to Immuta as an Application Admin.
2. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu and scroll to the **Integration Settings** section.
3. Your existing Databricks Spark integration should be listed here; expand it and note the configuration values. Now select **Remove** to remove your integration.
4. Click **Add Integration** and select **Databricks Integration** to add a new integration.
5. Enter your Databricks Spark integration settings again as configured previously.
6. Click **Add Integration** to add the integration, and then select **Configure Cluster Policies** to set up the updated cluster policies and init script.
7. Select the cluster policies you wish to use for your Immuta-enabled Databricks clusters.
8. Automatically push cluster policies and the init script (recommended) or manually update your cluster policies.
   * **Automatically push cluster policies**
     1. Select **Automatically Push Cluster Policies** and enter your privileged Databricks access token. This token must have privileges to write to cluster policies.
     2. Select **Apply Policies** to push the cluster policies and init script again.
     3. Click **Save** and **Confirm** to deploy your changes.
   * **Manually update cluster policies**
     1. Download the init script and the new cluster policies to your local computer.
     2. Click **Save** and **Confirm** to save your changes in Immuta.
     3. Log in to your Databricks workspace with your administrator account to set up cluster policies.
     4. Get the path you will upload the init script (`immuta_cluster_init_script_proxy.sh`) to by opening one of the cluster policy `.json` files and looking for the `defaultValue` of the field `init_scripts.0.dbfs.destination`. This should be a DBFS path in the form of `dbfs:/immuta-plugin/hostname/immuta_cluster_init_script_proxy.sh`.
     5. Click **Data** in the left pane to upload your init script to DBFS to the path you found above.
     6. To find your existing cluster policies you need to update, click **Compute** in the left pane and select the **Cluster policies** tab.
     7. Edit each of these cluster policies that were configured before and overwrite the contents of the JSON with the new cluster policy JSON you downloaded.
9. Restart any Databricks clusters using these updated policies for the changes to take effect.


# Install a Trusted Library

Install a third-party library as trusted to enable that library's code to bypass the Immuta security manager

{% hint style="warning" %}
**Databricks Libraries API**: Installing trusted libraries outside of the Databricks Libraries API (e.g., `ADD JAR ...`) is not supported.
{% endhint %}

1. In the Databricks Clusters UI, install your third-party library .jar or Maven artifact with **Library Source** `Upload`, `DBFS`, `DBFS/S3`, or `Maven`. Alternatively, use the Databricks libraries API.
2. In the Databricks Clusters UI, add the `IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS` property as a Spark environment variable and set it to your artifact's URI. To specify more than one trusted library, comma delimit the URIs:

   ```bash
   IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS=maven:/my.group.id:my-package-id:1.2.3
   ```

{% tabs %}
{% tab title="Maven artifacts" %}
For Maven artifacts, the URI is `maven:/<maven_coordinates>`, where `<maven_coordinates>` is the **Coordinates** field found when clicking on the installed artifact on the **Libraries** tab in the Databricks Clusters UI. Here's an example of an installed artifact:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/EXYZpd0xVCL0pRbAB6E7/maven-artifacts.png" alt=""><figcaption></figcaption></figure>

In this example, you would add the following Spark environment variable:

```bash
IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS=maven:/com.github.immuta.hadoop.immuta-spark-third-party-maven-lib-test:2020-11-17-144644
```

{% endtab %}

{% tab title=".jar artifacts" %}
For jar artifacts, the URI is the **Source** field found when clicking on the installed artifact on the **Libraries** tab in the Databricks Clusters UI. For artifacts installed from DBFS or S3, this ends up being the original URI to your artifact. For uploaded artifacts, Databricks will rename your .jar and put it in a directory in DBFS. Here's an example of an installed artifact:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/9wghILlUcipmTXG5sR5E/jar-artifact.png" alt=""><figcaption></figcaption></figure>

In this example, you would add the following Spark environment variable:

```bash
IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS=dbfs:/immuta/bstabile/jars/immuta-spark-third-party-lib-test.jar
```

{% endtab %}
{% endtabs %}

3. Once you've finished making your changes, restart the cluster.
4. Once the cluster is up, execute a command in a notebook. If the trusted library installation is successful, you should see driver log messages like this:

   ```bash
   TrustedLibraryUtils: Successfully found all configured Immuta configured trusted libraries in Databricks.
   TrustedLibraryUtils: Wrote trusted libs file to [/databricks/immuta/immutaTrustedLibs.json]: true.
   TrustedLibraryUtils: Added trusted libs file with 1 entries to spark context.
   TrustedLibraryUtils: Trusted library installation complete.
   ```


# Project UDFs Cache Settings

Lower the web service cache timeout settings of project UDFs

This page outlines the configuration for setting up project UDFs, which allow users to set their current project in Immuta through Spark. For details about the specific functions available and how to use them, see the [Use Project UDFs (Databricks) page](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/reference-guides/project-udfs).

{% hint style="info" %}
**Use project UDFs in Databricks Spark**

Currently, caches are not all invalidated outside of Databricks because Immuta caches information pertaining to a user's current project. Consequently, this feature should only be used in Databricks.
{% endhint %}

1. Lower the web service cache timeout in Immuta:
   1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon and scroll to the **HDFS Cache Settings** section.
   2. Lower the **Cache TTL of HDFS user names (ms)** to **0**.
   3. Click **Save**.
2. Raise the cache timeout on your Databricks cluster: In the Spark environment variables section, set the `IMMUTA_CURRENT_PROJECT_CACHE_TIMEOUT_SECONDS` and `IMMUTA_PROJECT_CACHE_TIMEOUT_SECONDS` to high values (like `10000`).

   *Note: These caches will be invalidated on cluster when a user calls `immuta.set_current_project`, so they can effectively be cached permanently on cluster to avoid periodically reaching out to the web service.*


# Run R and Scala spark-submit Jobs on Databricks

Complete prerequisites and create R and Scala spark-submit jobs

This guide illustrates how to run R and Scala `spark-submit` jobs on Databricks, including prerequisites and caveats.

## R `spark-submit`

### Prerequisites

Before you can run `spark-submit` jobs on Databricks, complete the following steps.

1. Initialize the Spark session:
   1. Enter these settings into the R submit script to allow the R script to access Immuta data sources, scratch paths, and workspace tables: `immuta.spark.acl.assume.not.privileged="true"` and `spark.hadoop.immuta.databricks.config.update.service.enabled="false"`.
   2. Once the script is written, upload the script to a location in `dbfs/S3/ABFS` to give the Databricks cluster access to it.
2. Because of how some user properties are populated in Databricks, load the SparkR library in a separate cell before attempting to use any SparkR functions.

### Create the R `spark submit` Job

To create the R `spark-submit` job,

1. Go to the Databricks jobs page.
2. Create a new job, and select **Configure spark-submit**.
3. Set up the parameters:

   ```
    [
    "--conf","spark.driver.extraJavaOptions=-Djava.security.manager=com.immuta.security.ImmutaSecurityManager -Dimmuta.security.manager.classes.config=file:///databricks/immuta/allowedCallingClasses.json -Dimmuta.spark.encryption.fpe.class=com.immuta.spark.encryption.ff1.ImmutaFF1Service",
    "--conf","spark.executor.extraJavaOptions=-Djava.security.manager=com.immuta.security.ImmutaSecurityManager -Dimmuta.security.manager.classes.config=file:///databricks/immuta/allowedCallingClasses.json -Dimmuta.spark.encryption.fpe.class=com.immuta.spark.encryption.ff1.ImmutaFF1Service",
    "--conf","spark.databricks.repl.allowedLanguages=python,sql,scala,r",
    "dbfs:/path/to/script.R",
    "arg1", "arg2", "..."
    ]
   ```

   *Note: The path `dbfs:/path/to/script.R` can be in S3 or ABFS (on Azure Databricks), assuming the cluster is configured with access to that path.*
4. Edit the cluster configuration, and change the Databricks Runtime to be a [supported version](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration#supported-databricks-runtime-versions).
5. Configure the [Spark environment variables](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration) section as you normally would for an Immuta cluster.

## Scala spark-submit

### Prerequisites

Before you can run `spark-submit` jobs on Databricks you must initialize the Spark session with the settings outlined below.

1. Configure the Spark session with `immuta.spark.acl.assume.not.privileged="true"` and `spark.hadoop.immuta.databricks.config.update.service.enabled="false"`.

   *Note: Stop your Spark session (`spark.stop()`) at the end of your job or the cluster will not terminate.*
2. The spark submit job needs to be launched using a different classloader which will point at the designated user JARs directory. The following Scala template can be used to handle launching your submit code using a separate classloader:

   ```scala
   package com.example.job

   import java.net.URLClassLoader
   import java.io.File

   import org.apache.spark.sql.SparkSession

   object ImmutaSparkSubmitExample {
   def main(args: Array[String]): Unit = {
       val jarDir = new File("/databricks/immuta/jars/")
       val urls = jarDir.listFiles.map(_.toURI.toURL)

       // Configure a new ClassLoader which will load jars from the additional jars directory
       val cl = new URLClassLoader(urls)
       val jobClass = cl.loadClass(classOf[ImmutaSparkSubmitExample].getName)
       val job = jobClass.newInstance
       jobClass.getMethod("runJob").invoke(job)
   }
   }

   class ImmutaSparkSubmitExample {

   def getSparkSession(): SparkSession = {
       SparkSession.builder()
       .appName("Example Spark Submit")
       .enableHiveSupport()
       .config("immuta.spark.acl.assume.not.privileged", "true")
       .config("spark.hadoop.immuta.databricks.config.update.service.enabled", "false")
       .getOrCreate()
   }

   def runJob(): Unit = {
       val spark = getSparkSession
       try {
       val df = spark.table("immuta.<YOUR DATASOURCE>")

       // Run Immuta Spark queries...

       } finally {
       spark.stop()
       }
   }
   }
   ```

### Create the Scala `spark-submit` Job

To create the Scala `spark-submit` job,

1. Build and upload your JAR to `dbfs/S3/ABFS` where the cluster has access to it.
2. Select **Configure spark-submit**, and configure the parameters:

   ```
    [
    "--conf","spark.driver.extraJavaOptions=-Djava.security.manager=com.immuta.security.ImmutaSecurityManager -Dimmuta.security.manager.classes.config=file:///databricks/immuta/allowedCallingClasses.json -Dimmuta.spark.encryption.fpe.class=com.immuta.spark.encryption.ff1.ImmutaFF1Service",
    "--conf","spark.executor.extraJavaOptions=-Djava.security.manager=com.immuta.security.ImmutaSecurityManager -Dimmuta.security.manager.classes.config=file:///databricks/immuta/allowedCallingClasses.json -Dimmuta.spark.encryption.fpe.class=com.immuta.spark.encryption.ff1.ImmutaFF1Service",
    "--conf","spark.databricks.repl.allowedLanguages=python,sql,scala,r",
    "--class","org.youorg.package.MainClass",
    "dbfs:/path/to/code.jar",
    "arg1", "arg2", "..."
    ]
   ```

   *Note: The fully-qualified class name of the class whose `main` function will be used as the entry point for your code in the `--class` parameter.*

   *Note: The path `dbfs:/path/to/code.jar` can be in S3 or ABFS (on Azure Databricks) assuming the cluster is configured with access to that path.*
3. Edit the cluster configuration, and change the Databricks Runtime to a [supported version](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration#supported-databricks-runtime-versions).
4. Include `IMMUTA_INIT_ADDITIONAL_JARS_URI=dbfs:/path/to/code.jar` in the "Environment Variables" (where `dbfs:/path/to/code.jar` is the path to your jar) so that the jar is uploaded to all the cluster nodes.

## Caveats

* The user mapping works differently from notebooks because `spark-submit` clusters are not configured with access to the Databricks SCIM API. The cluster tags are read to get the cluster creator and match that user to an Immuta user.
* Privileged users (Databricks admins and allowlisted users) must be tied to an Immuta user and given access through Immuta to access data through `spark-submit` jobs because the setting `immuta.spark.acl.assume.not.privileged="true"` is used.
* There is an option of using the `immuta.api.key` setting with an Immuta API key generated on the Immuta profile page.
* Currently when an API key is generated it invalidates the previous key. This can cause issues if a user is using multiple clusters in parallel, since each cluster will generate a new API key for that Immuta user. To avoid these issues, manually generate the API key in Immuta and set the `immuta.api.key` on all the clusters or use a specified job user for the submit job.


# DBFS Access

Enable DBFS access in Databricks for non-sensitive data

This page outlines how to enable access to DBFS in Databricks for non-sensitive data. Databricks administrators should place the desired configuration in the Spark environment variables.

## DBFS FUSE mount

This Databricks feature mounts DBFS to the local cluster filesystem at `/dbfs`. Although disabled when using process isolation, this feature can safely be enabled if raw, unfiltered data is not stored in DBFS and all users on the cluster are authorized to see each other’s files. When enabled, the entirety of DBFS essentially becomes a scratch path where users can read and write files in `/dfbs/path/to/my/file` as though they were local files.

{% hint style="info" %}
**DBFS FUSE mount limitation**: This feature cannot be used in environments with E2 Private Link enabled.
{% endhint %}

For example,

```bash
%sh echo "I'm creating a new file in DBFS" > /dbfs/my/newfile.txt
```

In Python,

```python
%python
with open("/dbfs/my/newfile.txt", "w") as f:
  f.write("I'm creating a new file in DBFS")
```

*Note: This solution also works in R and Scala.*

### Enable DBFS FUSE mount

To enable the DBFS FUSE mount, set this configuration in the Spark environment variables: IMMUTA`_SPARK_DATABRICKS_DBFS_MOUNT_ENABLED=true`.

{% hint style="info" %}
**Mounting a bucket**

* Users can [mount additional buckets to DBFS](https://docs.databricks.com/data/data-sources/aws/amazon-s3.html#mount-aws-s3) that can also be accessed using the FUSE mount.
* Mounting a bucket is a one-time action, and the mount will be available to all clusters in the workspace from that point on.
* Mounting must be performed from a non-Immuta cluster.
  {% endhint %}

## Scala DBUtils (and %fs magic) with scratch paths

Scratch paths will work when performing arbitrary remote filesystem operations with fs magic or Scala dbutils.fs functions. For example,

```bash
%fs put -f s3://my-bucket/my/scratch/path/mynewfile.txt "I'm creating a new file in S3"
%scala dbutils.fs.put("s3://my-bucket/my/scratch/path/mynewfile.txt", "I'm creating a new file in S3")
```

### Configure Scala DBUtils (and %fs magic) with scratch paths

To support %fs magic and Scala DBUtils with scratch paths, configure

```xml
       <property>
           <name>immuta.spark.databricks.scratch.paths</name>
           <value>s3://my-bucket/my/scratch/path</value>
       </property>
```

### Configure DBUtils in Python

To use `dbutils` in Python, set this configuration: `immuta.spark.databricks.py4j.strict.enabled=false`.

#### Example workflow

This section illustrates the workflow for getting a file from a remote scratch path, editing it locally with Python, and writing it back to a remote scratch path.

```python
%python
import os
import shutil

s3ScratchFile = "s3://some-bucket/path/to/scratch/file"
localScratchDir = os.environ.get("IMMUTA_LOCAL_SCRATCH_DIR")
localScratchFile = "{}/myfile.txt".format(localScratchDir)
localScratchFileCopy = "{}/myfile_copy.txt".format(localScratchDir)
```

1. Get the file from remote storage:

   ```python
   dbutils.fs.cp(s3ScratchFile, "file://{}".format(localScratchFile))
   ```
2. Make a copy if you want to explicitly edit `localScratchFile`, as it will be read-only and owned by root:

   ```python
   shutil.copy(localScratchFile, localScratchFileCopy)
   with open(localScratchFileCopy, "a") as f:
       f.write("Some appended file content")
   ```
3. Write the new file back to remote storage:

   ```python
   dbutils.fs.cp("file://{}".format(localScratchFileCopy), s3ScratchFile)
   ```


# Troubleshooting

Troubleshoot common errors with the Databricks Spark integration

This page provides guidelines for troubleshooting issues with the Databricks Spark integration and resolving Py4J security and Databricks trusted library errors.

## Debugging the integration

For easier debugging of the Databricks Spark integration, follow the recommendations below.

* **Enable cluster init script logging**:
  * In the cluster page in Databricks for the target cluster, navigate to **Advanced Options** -> **Logging**.
  * Change the **Destination** from `NONE` to `DBFS` and change the path to the desired output location. *Note: The unique cluster ID will be added onto the end of the provided path.*
* View the Spark UI on your target Databricks cluster: On the cluster page, click the **Spark UI** tab, which shows the Spark application UI for the cluster. If you encounter issues creating Databricks data sources in Immuta, you can also view the **JDBC/ODBC Server** portion of the Spark UI to see the result of queries that have been sent from Immuta to Databricks.

### Using the validation and debugging notebook

The validation and debugging notebook is designed to be used by or under the guidance of an Immuta support professional. Reach out to your Immuta representative for assistance.

1. Import the notebook into a Databricks workspace by navigating to **Home** in your Databricks instance.
2. Click the **arrow** next to your name and select **Import**.
3. Once you have executed commands in the notebook and populated it with debugging information, export the notebook and its contents by opening the **File** menu, selecting **Export**, and then selecting **DBC Archive**.

## Py4J security error

* **Error Message**: `py4j.security.Py4JSecurityException: Constructor <> is not allowlisted`
* **Explanation**: This error indicates you are being blocked by Py4J security rather than the Immuta Security Manager. Py4J security is strict and generally ends up blocking many ML libraries.
* **Solution**: Turn off Py4J security on the offending cluster by setting `IMMUTA_SPARK_DATABRICKS_PY4J_STRICT_ENABLED=false` in the environment variables section. Additionally, because there are limitations to the security mechanisms Immuta employs on-cluster when Py4J security is disabled, ensure that all users on the cluster have the same level of access to data, as users could theoretically see (policy-enforced) data that other users have queried.

## Databricks trusted library errors

Check the driver logs for details. Some possible causes of failure include

* One of the Immuta-configured trusted library URIs does not point to a Databricks library. Check that you have configured the correct URI for the Databricks library.
* For trusted Maven artifacts, the URI must follow this format: `maven:/group.id:artifact-id:version`.
* Databricks failed to install a library. Any Databricks library installation errors will appear in the Databricks UI under the **Libraries** tab.


# Reference Guides


# Databricks Spark Integration Configuration

Learn how the Databricks Spark integration works to govern data access

The [Databricks Spark integration is one of two integrations](#user-content-fn-1)[^1] Immuta offers for Databricks.

In this integration, Immuta installs an Immuta-maintained Spark plugin on your Databricks cluster. When a user queries data that has been registered in Immuta as a data source, the plugin injects policy logic into the plan Spark builds so that the results returned to the user only include data that specific user should see.

The reference guides in this section are written for Databricks administrators who are responsible for setting up the integration, securing Databricks clusters, and setting up users:

* [Installation and compliance](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance): This guide includes information about what Immuta creates in your Databricks environment and securing your Databricks clusters.
* [Customizing the integration](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration): Consult this guide for information about customizing the Databricks Spark integration settings.
* [Setting up users](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/setting-up-users): Consult this guide for information about connecting data users and setting up user impersonation.
* [Spark environment variables](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration): This guide provides a list of Spark environment variables used to configure the integration.
* [Ephemeral overrides](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/ephemeral-overrides): This guide describes [ephemeral overrides](#user-content-fn-2)[^2] and how to configure them to reduce the risk that a user has overrides set to a cluster (or multiple clusters) that aren't currently up.

[^1]: The Databricks Spark integration should be used if your data still exists in the Hive metastore. See the [Which integration should you use](/2026.2/configuration/integrations/databricks#which-integration-should-you-use) section for an overview of the two integrations and when to use each one.

[^2]: In the context of the Databricks Spark integration, Immuta uses the term *ephemeral* to describe data sources where the associated compute resources can vary over time. This means that the compute bound to these data sources is not fixed and can change. All Databricks data sources in Immuta are ephemeral.


# Installation and Compliance

Learn about what Immuta creates in your Databricks environment to enforce access controls

In the Databricks Spark integration, Immuta installs an Immuta-maintained Spark plugin on your Databricks cluster. When a user queries data that has been registered in Immuta as a data source, the plugin injects policy logic into the plan Spark builds so that the results returned to the user only include data that specific user should see.

The sequence diagram below breaks down this process of events when an Immuta user queries data in Databricks.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/Eu2EL99TCyostZ7V5e1q/databricks-spark-process-diagram.png" alt=""><figcaption><p>Immuta intercepts Spark calls to the Metastore. Immuta then modifies the logical plan so that policies are applied to the data for the querying user.</p></figcaption></figure>

## System requirements

* A Databricks workspace with the Premium tier, which includes cluster policies (required to configure the Spark integration)
* A cluster that uses one of these supported Databricks Runtimes:
  * 11.3 LTS
  * 14.3
* Supported languages
  * Python
  * R (not supported for Databricks Runtime 14.3)
  * Scala (not supported for Databricks Runtime 14.3)
  * SQL
* A Databricks cluster that is one of these supported compute types:
  * [All-purpose compute](https://docs.databricks.com/en/compute/index.html#types-of-compute)
  * [Job compute](https://docs.databricks.com/en/compute/index.html#types-of-compute)
* Custom access mode
* A Databricks workspace and cluster with the ability to directly make HTTP calls to the Immuta web service. The Immuta web service also must be able to connect to and perform queries on the Databricks cluster, and to call [Databricks workspace APIs](https://docs.databricks.com/api/workspace/introduction).
* The Databricks Spark integration only works with Spark 3.

## What does Immuta do in my Databricks environment?

When an administrator configures the Databricks Spark integration, Immuta generates a cluster policy that the administrator then applies to the Databricks cluster. When the cluster starts after the cluster policy has been applied, the Databricks cluster [init script](https://docs.databricks.com/en/init-scripts/index.html) that Immuta provides downloads Spark plugin artifacts onto the cluster that has the init script and puts the artifacts in the appropriate locations on local disk for use by Spark.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/FJChWfwQqglks216KeoO/Databricks%20Spark%20init%20script%20(1).png" alt=""><figcaption></figcaption></figure>

Once the init script runs, the Spark application running on the Databricks cluster will have the appropriate artifacts on its CLASSPATH to use Immuta for authorization and policy enforcement.

Immuta adds the following artifacts to your Databricks environment:

<details>

<summary>Immuta-maintained Spark plugin</summary>

The Databricks Spark integration injects this Immuta-maintained Spark plugin into the SparkSQL stack at cluster startup time. Policy determinations are obtained from the connected Immuta tenant and applied before returning results to the user. The plugin includes wrappers and Immuta analysis hook plan rewrites to enforce policies.

</details>

<details>

<summary>Immuta Security Manager</summary>

*Note: The Security Manager is disabled for*[ *Databricks Runtime 14.3*](#databricks-runtime-14.3)*.*

The Immuta Security Manager ensures users can't perform unauthorized actions when using Scala and R, since those languages have features that allow users to circumvent policies without the Security Manager enabled. The Immuta Security Manager blocks users from executing code that could allow them to gain access to sensitive data by only allowing select code paths to access sensitive files and methods. These select code paths provide Immuta's code access to sensitive resources while blocking end users from these sensitive resources directly.

**Performance**

The Security Manager must inspect the call stack every time a permission check is triggered, which adds overhead to queries. To improve Immuta's query performance on Databricks, Immuta disables the Security Manager when Scala and R are not being used.

The cluster init script checks the cluster’s configuration and automatically removes the Security Manager configuration when

* `spark.databricks.repl.allowedlanguages` is a subset of `{python, sql}`
* `IMMUTA_SPARK_DATABRICKS_PY4J_STRICT_ENABLED` is `true`

When the cluster is configured this way, Immuta can rely on Databricks' process isolation and Py4J security to prevent user code from performing unauthorized actions.

*Note: Immuta still expects the `spark.driver.extraJavaOptions` and `spark.executor.extraJavaOptions` to be set and pointing at the Security Manager.*

Beyond disabling the Security Manager, Immuta will skip several startup tasks that are required to secure the cluster when Scala and R are configured, and fewer permission checks will occur on the Driver and Executors in the Databricks cluster, reducing overhead and improving performance.

**Caveats**

* There are still cases that require the Security Manager; in those instances, Immuta creates a fallback Security Manager to check the code path, so the `IMMUTA_INIT_ALLOWED_CALLING_CLASSES_URI` environment variable must always point to a valid calling class file.
* Databricks’ dbutils is blocked by their Py4J security; therefore, it can’t be used to access scratch paths.

</details>

<details>

<summary><code>immuta</code> database</summary>

When a table is registered in Immuta as a data source, users can see that table in the native Databricks database and in the `immuta` database. This allows for an option to use a single database (`immuta`) for all tables.

The `immuta` database on Immuta-enabled clusters allows Immuta to track Immuta-managed data sources separately from remote Databricks tables so that policies and other security features can be applied. However, Immuta supports raw tables in Databricks, so table-backed queries do not need to reference this database.

When configuring a Databricks cluster, you can hide `immuta` from any calls to `SHOW DATABASES` so that users are not confused or misled by that database. Hiding the database does not disable access to it. Queries can still be performed against tables in the `immuta` database using the Immuta-qualified table name (e.g., `immuta.my_schema_my_table`) regardless of whether or not this database is hidden.

To hide the `immuta` database, use the following environment variable in the [Spark cluster configuration](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_show_immuta_database) when configuring your integration:

```conf
IMMUTA_SPARK_SHOW_IMMUTA_DATABASE=false
```

Then, Immuta will not show this database when a `SHOW DATABASES` query is performed.

</details>

Once the Immuta-enabled cluster is running, the following user actions spur various processes. The list below provides an overview of each process:

* [**Data source is registered**](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/registering-and-protecting-data#registering-data): When a data owner registers a Databricks securable as a data source, data source metadata (column type, securable name, column names, etc.) is retrieved from the Metastore and stored in the Immuta Metadata Database. If tags are then applied to the data source, Immuta stores this metadata in the Metadata Database as well.
* **Data source is deleted**: When a data source is deleted, the data source metadata is deleted from the Metadata Database. Depending on the settings configured for the integration, users will either be able to query that data now that it is no longer registered in Immuta, or access to the securable will be revoked for all users. See the [Protected and unprotected tables section](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables) for details about this setting.
* [**Policy is created or edited on a data source**](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/registering-and-protecting-data#protecting-data): Information about the policy and the columns or securables it applies to is stored in the Metadata Database. When a user queries the data in Databricks, the Spark plugin retrieves the policy information, the user metadata, and the data source metadata from the Metadata Database and injects this information as policy logic into the Spark logical plan. Immuta caches policy information and data source definitions in memory on the Spark application to reduce calls to the Metadata Database and boost performance.
* **A policy is deleted**: When a policy is deleted, the policy information is deleted from the Metadata Database. If users were granted access to the data source by that policy, their access is revoked.
* [**Databricks user is mapped to Immuta**](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/setting-up-users#mapping-databricks-users-to-immuta): When a Databricks user is mapped to Immuta, their metadata is stored in the Metadata Database.
* **Databricks user queries data**: When a user queries the data in Databricks, Immuta intercepts the call from Spark down to the Metastore. Then, the Immuta-maintained Spark plugin retrieves the policy information, the user metadata, and the data source metadata from the Metadata Database and injects this information as policy logic into the Spark logical plan. Once the physical plan is applied, Databricks returns policy-enforced data to the user.

The image below illustrates these processes and how they interact.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/xc91IHB1ZEAck33GIqJN/databricks-init-script.png" alt=""><figcaption></figcaption></figure>

### Supported policies

The Databricks Spark integration allows users to author subscription and data policies to enforce access controls. See the corresponding pages for details about specific types of policies supported:

* [Subscription policy access types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types)
* [Data policy types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#policy-support-matrix)

### Databricks Runtime 14.3

Immuta supports clusters on Databricks Runtime 14.3. The integration for this Databricks Runtime differs from the integration for other supported Runtimes in the following ways:

* [**Security Manager is disabled**](#immuta-security-manager): The Security Manager is disabled for Databricks Runtime 14.3. Because the Security Manager is used to prevent users from circumventing access controls when using R and Scala, those languages are unsupported. Only Python and SQL clusters are supported.
* **Py4J security and process isolation automatically enabled**: Immuta relies on Databricks process isolation and Py4J security to prevent user code from performing unauthorized actions. After selecting Runtime 14.3 during configuration, Immuta will automatically enable process isolation and Py4J security.
* **dbutils is unsupported**: Immuta relies on Databricks process isolation and Py4J security to prevent user code from performing unauthorized actions. This means that dbutils is not supported for Databricks Spark integrations using Databricks Runtime 14.3 LTS.
* [**Databricks Connect is unsupported**](https://docs.databricks.com/en/dev-tools/databricks-connect/index.html): Databricks Connect is unsupported because Py4J security must be enabled to use it.

The table below compares the features supported for clusters on Databricks Runtime 11.3 and Databricks Runtime 14.3.

| Feature                                                                                                                                                                              | Databricks Runtime 11.3 | Databricks Runtime 14.3 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ----------------------- |
| Subscription policies                                                                                                                                                                | :white\_check\_mark:    | :white\_check\_mark:    |
| Data policies                                                                                                                                                                        | :white\_check\_mark:    | :white\_check\_mark:    |
| [Scratch paths](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#scratch-paths)                                | :white\_check\_mark:    | :white\_check\_mark:    |
| [Project UDFs](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#restricting-users-access-with-immuta-projects) | :white\_check\_mark:    | :white\_check\_mark:    |
| [Non-Immuta reads and writes](#user-content-fn-1)[^1]                                                                                                                                | :white\_check\_mark:    | :white\_check\_mark:    |
| [Impersonation](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/setting-up-users#user-impersonation)                                      | :white\_check\_mark:    | :white\_check\_mark:    |
| [Metastore magic](/2026.2/configuration/integrations/databricks#metastore-magic)                                                                                                     | :white\_check\_mark:    | :white\_check\_mark:    |
| Python                                                                                                                                                                               | :white\_check\_mark:    | :white\_check\_mark:    |
| SQL                                                                                                                                                                                  | :white\_check\_mark:    | :white\_check\_mark:    |
| R                                                                                                                                                                                    | :white\_check\_mark:    | :x:                     |
| Scala                                                                                                                                                                                | :white\_check\_mark:    | :x:                     |
| Immuta project workspaces                                                                                                                                                            | :white\_check\_mark:    | :x:                     |
| Smart mask ordering                                                                                                                                                                  | :white\_check\_mark:    | :x:                     |
| Masking and tagging complex columns (STRUCT, ARRAY, MAP)                                                                                                                             | :white\_check\_mark:    | :x:                     |
| Photon support                                                                                                                                                                       | :white\_check\_mark:    | :x:                     |
| dbutils                                                                                                                                                                              | :white\_check\_mark:    | :x:                     |
| Databricks Connect                                                                                                                                                                   | :white\_check\_mark:    | :x:                     |
| Write policies                                                                                                                                                                       | :x:                     | :x:                     |
| Support for allowlisting networks or local filesystem paths                                                                                                                          | :x:                     | :white\_check\_mark:    |

## Cluster security and compliance

### Authentication methods

The Databricks Spark integration supports the following authentication methods to configure the integration:

* **OAuth machine-to-machine (M2M)**: Immuta uses the [Client Credentials Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) to integrate with [Databricks OAuth machine-to-machine authentication](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html), which allows Immuta to authenticate with Databricks using a client secret. Once Databricks verifies the Immuta service principal’s identity using the client secret, Immuta is granted a temporary OAuth token to perform token-based authentication in subsequent requests. When that token expires (after one hour), Immuta requests a new temporary token. See the [Databricks OAuth machine-to-machine (M2M) authentication page](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html) for more details.
* **Personal access token (PAT)**: This token gives Immuta temporary permission to push the cluster policies to the configured Databricks workspace and overwrite any cluster policy templates previously applied to the workspace when configuring the integration or to register securables as Immuta data sources.

### Audit

Immuta captures the code or query that triggers the Spark plan in Databricks, making audit records more useful in assessing what users are doing. To audit what triggers the Spark plan, Immuta hooks into Databricks where notebook cells and JDBC queries execute and saves the cell or query text. Then, Immuta pulls this information into the audits of the resulting Spark jobs.

Immuta supports auditing all queries run on a Databricks cluster, regardless of whether users touch Immuta-protected data or not. To configure Immuta to do so, set the [`IMMUTA_SPARK_AUDIT_ALL_QUERIES` environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_audit_all_queries) in the Spark cluster configuration when configuring your integration.

See the [Security and compliance guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/security-and-compliance#auditing-and-compliance) for more details about the audit capabilities in the Databricks Spark integration.

### Protecting the Immuta configuration

Non-administrator users on an Immuta-enabled Databricks cluster must not have access to view or modify Immuta configuration or the `immuta-spark-hive.jar` file, as this poses a security loophole around Immuta policy enforcement. [Databricks secrets](https://docs.databricks.com/security/secrets/index.html#spark-conf-env-var) allow you to securely apply environment variables to Immuta-enabled clusters.

Databricks secrets can be used in the environment variables configuration section for a cluster by referencing the secret path instead of the actual value of the environment variable. For example, if a user wanted to make the `MY_SECRET_ENV_VAR=abcd_1234` value secret, they could instead create a Databricks secret and reference it as the value of that variable by following these steps:

1. Create the secret scope `my_secrets` and add a secret with the key `my_secret_env_var` containing the sensitive environment variable.
2. Reference the secret in the environment variables section as `MY_SECRET_ENV_VAR={{secrets/my_secrets/my_secret_env_var}}`.

At runtime, `{{secrets/my_secrets/my_secret_env_var}}` would be replaced with the actual value of the secret if the owner of the cluster has access to that secret.

### Scala clusters

There are limitations to isolation among users in Scala jobs on a Databricks cluster, even when using Immuta’s Security Manager. When data is broadcast, cached (spilled to disk), or otherwise saved to `SPARK_LOCAL_DIR`, it's impossible to distinguish between which user’s data is composed in each file/block. If you are concerned about this vulnerability, Immuta suggests that you

* **limit Scala clusters to Scala jobs only** and
* **require equalized projects**, which will force all users to act under the same set of attributes, groups, and purposes with respect to their data access. To require that Scala clusters be used in equalized projects and avoid the risk described above, set the [`IMMUTA_SPARK_REQUIRE_EQUALIZATION` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_require_equalization) to `true`.\
  \
  Once this configuration is complete, users on the cluster will need to switch to an Immuta equalized project before running a job. Once the first job is run using that equalized project, all subsequent jobs, no matter the user, must also be run under that same equalized project. If you need to change a cluster's project, you must restart the cluster.

When data is read in Spark using an Immuta policy-enforced plan, the masking and redaction of rows is performed at the leaf level of the physical Spark plan, so a policy such as "Mask using hashing the column `social_security_number` for everyone" would be implemented as an expression on a project node right above the `FileSourceScanExec/LeafExec` node at the bottom of the plan. This process prevents raw data from being shuffled in a Spark application and, consequently, from ending up in `SPARK_LOCAL_DIR`.

This policy implementation coupled with an equalized project guarantees that data being dropped into `SPARK_LOCAL_DIR` will have policies enforced and that those policies will be homogeneous for all users on the cluster. Since each user will have access to the same data, if they attempt to manually access other users' cached data, they will only see what they have access to via equalized permissions on the cluster. If project equalization is not turned on, users could dig through that directory and find data from another user with heightened access, which would result in a data leak.

## Troubleshooting the installation

The [Troubleshooting page](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/troubleshooting) has guidance for resolving issues with your installation.

[^1]: When you set up a Databricks Spark integration, you can enable the setting **Available until protected by policy.** This setting means all tables are open until explicitly registered and protected by Immuta, which allows Databricks users to read and write to data objects that are not registered in Immuta.\
    \
    See the [Customizing the integration page](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables) for details.


# Customizing the Integration

Learn how to adjust settings for the Databricks Spark integration

You can customize the Databricks Spark integration settings using these components Immuta provides:

* [Cluster policies](#cluster-policies)
* [Spark environment variables](#spark-environment-variables)
* [Hadoop configuration file](#additional-hadoop-configuration-file-optional)

## Cluster policies

Immuta provides cluster policies that set the [Spark environment variables](#spark-environment-variables) and configuration on your Databricks cluster once you apply that policy to your cluster. These policies generated by Immuta must be applied to your cluster manually. The [Configure a Databricks Spark integration guide](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration#configure-cluster-policies) includes instructions for generating and applying these cluster policies. Each cluster policy is described below.

<details>

<summary>Python and SQL</summary>

*This is the most performant policy configuration.*

In this configuration, Immuta is able to rely on Databricks-native security controls, reducing overhead. The key security control here is the enablement of process isolation. This prevents users from obtaining unintentional access to the queries of other users. In other words, masked and filtered data is consistently made accessible to users in accordance with their assigned attributes. This Immuta cluster configuration relies on Py4J security being enabled. Consequently, the following Databricks features are unsupported:

* Many Python ML classes (such as `LogisticRegression`, `StringIndexer`, and `DecisionTreeClassifier`)
* dbutils.fs
* Databricks Connect client library

For full details on Databricks’ best practices in configuring clusters, read their [governance documentation](https://docs.databricks.com/security/data-governance.html).

</details>

<details>

<summary>Python, SQL, and R</summary>

***Additional overhead**: Compared to the Python and SQL cluster policy, this configuration trades some additional overhead for added support of the R language.*

In this configuration, you are able to rely on the Databricks-native security controls. The key security control here is the enablement of process isolation. This prevents users from obtaining unintentional access to the queries of other users. In other words, masked and filtered data is consistently made accessible to users in accordance with their assigned attributes.

Like the Python & SQL configuration, Py4j security is enabled for the Python & SQL & R configuration. However, because R has been added Immuta enables the Security Manager, in addition to Py4J security, to provide more security guarantees. For example, by default all actions in R execute as the root user; among other things, this permits access to the entire filesystem (including sensitive configuration data), and, without iptable restrictions, a user may freely access the cluster’s cloud storage credentials. To address these security issues, Immuta’s initialization script wraps the R and Rscript binaries to launch each command as a temporary, non-privileged user with limited filesystem and network access and installs the Immuta Security Manager, which prevents users from bypassing policies and protects against the above vulnerabilities from within the JVM.

Consequently, the cost of introducing R is that the Security Manager incurs a small increase in performance overhead; however, average latency will vary depending on whether the cluster is homogeneous or heterogeneous. (In homogeneous clusters, all users are at the same level of groups/authorizations; this is enforced externally, rather than directly by Immuta.)

When users install third-party Java/Scala libraries, they will be denied access to sensitive resources by default. However, cluster administrators can specify which of the installed Databricks libraries should be [trusted](#databricks-trusted-libraries) by Immuta.

The following Databricks features are unsupported when this cluster policy is applied:

* Many Python ML classes (such as `LogisticRegression`, `StringIndexer`, and `DecisionTreeClassifier`)
* dbutils.fs
* Databricks Connect client library

For full details on Databricks’ best practices in configuring clusters, read their [governance documentation](https://docs.databricks.com/security/data-governance.html).

</details>

<details>

<summary>Python, SQL, and R with library support</summary>

***Py4J security disabled**: In addition to support for Python, SQL, and R, this configuration adds support for additional Python libraries and utilities by disabling Databricks-native Py4J security.*

This configuration does not rely on Databricks-native Py4J security to secure the cluster, while process isolation is still enabled to secure filesystem and network access from within Python processes. On an Immuta-enabled cluster, once Py4J security is disabled the Immuta Security Manager is installed to prevent nefarious actions from Python in the JVM. Disabling Py4J security also allows for expanded Python library support, including many Python ML classes (such as `LogisticRegression`, `StringIndexer`, and `DecisionTreeClassifier`) and dbutils.fs.

By default, all actions in R will execute as the root user. Among other things, this permits access to the entire filesystem (including sensitive configuration data). And without iptable restrictions, a user may freely access the cluster’s cloud storage credentials. To properly support the use of the R language, Immuta’s initialization script wraps the R and Rscript binaries to launch each command as a temporary, non-privileged user. This user has limited filesystem and network access. The Immuta Security Manager is also installed to prevent users from bypassing policies and protects against the above vulnerabilities from within the JVM.

The Security Manager will incur a small increase in performance overhead; average latency will vary depending on whether the cluster is homogeneous or heterogeneous. (In homogeneous clusters, all users are at the same level of groups/authorizations; this is enforced externally, rather than directly by Immuta.)

When users install third-party Java/Scala libraries, they will be denied access to sensitive resources by default. However, cluster administrators can specify which of the installed Databricks libraries should be [trusted](#databricks-trusted-libraries) by Immuta.

A homogeneous cluster is recommended for configurations where Py4J security is disabled. If all users have the same level of authorization, there would not be any data leakage, even if a nefarious action was taken.

For full details on Databricks’ best practices in configuring clusters, read their [governance documentation](https://docs.databricks.com/security/data-governance.html).

</details>

<details>

<summary>Scala</summary>

***Scala clusters**: This configuration is for Scala-only clusters.*

Where Scala language support is needed, this configuration can be used in the Custom [access mode](https://docs.databricks.com/clusters/cluster-ui-preview.html).

According to Databricks’ cluster type support documentation, Scala clusters are intended for [single users only](https://docs.databricks.com/clusters/configure.html#standard-clusters). However, nothing inherently prevents a Scala cluster from being configured for multiple users. Even with the Immuta Security Manager enabled, there are limitations to user isolation within a Scala job.

For a secure configuration, it is recommended that clusters intended for Scala workloads are limited to Scala jobs only and are made homogeneous through the use of [project equalization](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/equalized-access/equalization) or externally via convention/cluster ACLs. (In homogeneous clusters, all users are at the same level of groups/authorizations; this is enforced externally, rather than directly by Immuta.)

For full details on Databricks’ best practices in configuring clusters, read their [governance documentation](https://docs.databricks.com/security/data-governance.html).

</details>

<details>

<summary>Sparklyr</summary>

***Single-user clusters recommended:** Like Databricks, Immuta recommends single-user clusters for sparklyr when user isolation is required. A single-user cluster can either be a job cluster or a cluster with credential passthrough enabled.* *Note: spark-submit jobs are not currently supported.*

Two cluster types can be configured with sparklyr: Single-User Clusters (recommended) and Multi-User Clusters (discouraged).

* [**Single-User Clusters**](#single-user-cluster-configuration): Credential Passthrough (required on Databricks) allows a single-user cluster to be created. This setting automatically configures the cluster to assume the role of the attached user when reading from storage. Because Immuta requires that raw data is readable by the cluster, the instance profile associated with the cluster should be used rather than a role assigned to the attached user.
* [**Multi-User Clusters**](#multi-user-cluster-configuration): Because Immuta cannot guarantee user isolation in a multi-user sparklyr cluster, it is not recommended to deploy a multi-user cluster. To force all users to act under the same set of attributes, groups, and purposes with respect to their data access and eliminate the risk of a data leak, all sparklyr multi-user clusters must be equalized either by convention (all users able to attach to the cluster have the same level of data access in Immuta) or by configuration (detailed below).

**Single-user cluster configuration**

**1 - Enable sparklyr**

In addition to the configuration for an Immuta cluster with R, add this environment variable to the **Environment Variables** section of the cluster:

```conf
IMMUTA_DATABRICKS_SPARKLYR_SUPPORT_ENABLED=true
```

This configuration makes changes to the iptables rules on the cluster to allow the sparklyr client to connect to the required ports on the JVM used by the sparklyr backend service.

**2 - Set up a sparklyr connection in Databricks**

1. Install and load libraries into a notebook. Databricks includes the stable version of sparklyr, so `library(sparklyr)` in an R notebook is sufficient, but you may opt to install the latest version of sparklyr from `CRAN`. Additionally, loading `library(DBI)` will allow you to execute SQL queries.
2. Set up a sparklyr connection:

   ```conf
   sc <- spark_connect(method = "databricks")
   ```
3. Pass the connection object to execute queries:

   ```conf
   dbGetQuery(sc, "show tables in immuta")
   ```

**3 - Configure a single-user cluster**

Add the following items to the Spark Config section of the cluster:

```conf
spark.databricks.passthrough.enabled true

spark.databricks.pyspark.trustedFilesystems com.databricks.s3a.S3AFileSystem,shaded.databricks.azurebfs.org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem,shaded.databricks.v20180920_b33d810.org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem,com.databricks.adl.AdlFileSystem,shaded.databricks.V2_1_4.com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem,shaded.databricks.org.apache.hadoop.fs.azure.NativeAzureFileSystem,shaded.databricks.org.apache.hadoop.fs.s3a.S3AFileSystem,org.apache.hadoop.fs.ImmutaSecureFileSystemWrapper

spark.hadoop.fs.s3a.aws.credentials.provider com.amazonaws.auth.InstanceProfileCredentialsProvider
```

The `trustedFileSystems` setting is required to allow Immuta’s wrapper FileSystem (used in conjunction with the Security Manager for data security purposes) to be used with credential passthrough. Additionally, the `InstanceProfileCredentialsProvider` must be configured to continue using the cluster’s instance profile for data access, rather than a role associated with the attached user.

**Multi-user cluster configuration**

**Avoid deploying multi-user clusters with sparklyr configuration**

It is possible, but not recommended, to deploy a multi-user cluster sparklyr configuration. Immuta cannot guarantee user isolation in a multi-user sparklyr configuration.

The configurations in this section enable sparklyr, require project equalization, map sparklyr sessions to the correct Immuta user, and prevent users from accessing Immuta native workspaces.

1. Add the following environment variables to the **Environment Variables** section of your cluster configuration:

   ```conf
   IMMUTA_DATABRICKS_SPARKLYR_SUPPORT_ENABLED=true

   IMMUTA_SPARK_REQUIRE_EQUALIZATION=true

   IMMUTA_SPARK_CURRENT_USER_SCIM_FALLBACK=false
   ```
2. Add the following items to the **Spark Config** section:

   ```conf
   immuta.spark.acl.assume.not.privileged true

   immuta.api.key=<user’s API key>
   ```

**Limitations**

Immuta’s integration with sparklyr does not currently support

* spark-submit jobs
* UDFs

</details>

## Spark environment variables

The [Spark environment variables reference guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration) lists the various possible settings controlled by these variables that you can set in your cluster policy before attaching it to your cluster.

## Additional Hadoop configuration file (optional)

In some cases it is necessary to add sensitive configuration to `SparkSession.sparkContext.hadoopConfiguration` to allow Spark to read data.

For example, when accessing external tables stored in Azure Data Lake Gen2, Spark must have credentials to access the target containers or filesystems in Azure Data Lake Gen2, but users must not have access to those credentials. In this case, an additional configuration file may be provided with a storage account key that the cluster may use to access Azure Data Lake Gen2.

To use an additional Hadoop configuration file, set the [`IMMUTA_INIT_ADDITIONAL_CONF_URI` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_init_additional_conf_uri) to be the full URI to this file.

## Configurable settings

### Data source settings

#### Protected and unprotected tables

Databricks non-privileged users will only see sources to which they are subscribed in Immuta, and this can present problems if organizations have a data lake full of non-sensitive data and Immuta removes access to all of it. Immuta addresses this challenge by allowing Immuta users to access any tables that are not protected by Immuta (i.e., not registered as a data source or a table in a native workspace). Although this is similar to how privileged users in Databricks operate, non-privileged users cannot bypass Immuta controls.

* **Protected until made available by policy:** This setting means that users can only see tables that Immuta has explicitly subscribed them to.

{% hint style="warning" %}
**Behavior change in Immuta v2025.1 and newer**

If a table is registered in Immuta and does not have a subscription policy applied to it, that data will be visible to users, even if the **Protected until made available by policy** setting is enabled.

If you have enabled this setting, author an "Allow individually selected users" [global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial) that applies to all data sources.
{% endhint %}

* **Available until protected by policy:** This setting means all tables are open until explicitly registered and protected by Immuta. This setting allows both non-Immuta reads and non-Immuta writes:
  * [`IMMUTA_SPARK_DATABRICKS_ALLOW_NON_IMMUTA_READS`](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_allow_non_immuta_reads): Immuta users with regular (non-privileged) Databricks roles may `SELECT` from tables that are not registered in Immuta. This setting does not allow reading data directly with commands like **spark.read.format("x")**. Users are still required to read data and query tables using Spark SQL. When non-Immuta reads are enabled through the cluster policy, Immuta users will see all databases and tables when they run **show databases** or **show tables**. However, this does not mean they will be able to query all of them.
  * [`IMMUTA_SPARK_DATABRICKS_ALLOW_NON_IMMUTA_WRITES`](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_allow_non_immuta_writes): Immuta users with regular (non-privileged) Databricks roles can run DDL commands and data-modifying commands against tables or spaces that are not registered in Immuta. With non-Immuta writes enabled through the cluster policy, users on the cluster can mix any policy-enforced data they may have access to via any registered data sources in Immuta with non-Immuta data and write the ensuing result to a non-Immuta write space where it would be visible to others. If this is not a desired possibility, the cluster should instead be configured to only use Immuta’s project workspaces.

The [Configure a Databricks Spark integration guide](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration#add-the-integration-on-the-app-settings-page) includes instructions for applying these settings to your cluster.

#### Ephemeral overrides

In Immuta, a Databricks data source is considered ephemeral, meaning that the compute resources associated with that data source will not always be available.

Ephemeral data sources allow the use of ephemeral overrides, user-specific connection parameter overrides that are applied to Immuta metadata operations.

When a user runs a Spark job in Databricks, the Immuta plugin automatically submits ephemeral overrides for that user to Immuta for all applicable data sources to use the current cluster as compute for all subsequent metadata operations for that user against the applicable data sources.

For more details about ephemeral overrides and how to configure or disable them, see the [Ephemeral overrides page](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/ephemeral-overrides).

### Restricting users' access with Immuta projects

Immuta projects combine users and data sources under a common purpose. Sometimes this purpose is for a single user to organize their data sources or to control an entire schema of data sources through a single projects screen; however, most often this is an Immuta purpose for which the data has been approved to be used and will restrict access to data and streamline team collaboration. Consequently, data owners can restrict access to data for a specified purpose through projects.

When a user is working within the context of a project, data users will only see the data in that project. This helps to prevent data leaks when users collaborate. Users can switch project contexts to access various data sources while acting under the appropriate purpose. Consider adjusting the following project settings to suit your organization's needs:

* **Project UDFs** (web service and on-cluster caches): Immuta caches a mapping of user accounts and users' current projects in the Immuta Web Service and on-cluster. When users change their project with UDFs instead of the Immuta UI, Immuta invalidates all the caches on-cluster (so that everything changes immediately) and the cluster submits a request to change the project context to a web worker. Immediately after that request, another call is made to a web worker to refresh the current project.\
  \
  To allow use of project UDFs in Spark jobs, [raise the caching on-cluster and lower the cache timeouts for the Immuta Web Service](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/project-udfs). Otherwise, caching could cause dissonance among the requests and calls to multiple web workers when users try to change their project contexts.
* **Preventing users from changing projects within a session**: If your compliance requirements restrict users from changing projects within a session, you can block the use of Immuta's project UDFs on a Databricks Spark cluster. To do so, [configure the `IMMUTA_SPARK_DATABRICKS_DISABLED_UDFS` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_disabled_udfs).

### Databricks features

This section describes how Immuta interacts with common Databricks features.

#### Change data feed

Databricks users can see the [Databricks change data feed (CDF)](#user-content-fn-1)[^1] on queried tables if they are allowed to read raw data and meet specific qualifications. Immuta does not support applying policies to the changed data, and the CDF cannot be read for data source tables if the user does not have access to the raw data in Databricks or for [streaming queries](https://docs.databricks.com/delta/delta-change-data-feed.html#read-changes-in-streaming-queries).

The CDF can be read if the querying user is allowed to read the raw data and ONE of the following statements is true:

* the table is in the current workspace
* the table is in a scratch path
* non-Immuta reads are enabled AND the table does not intersect with a workspace under which the current user is not acting
* non-Immuta reads are enabled AND the table is not part of an Immuta data source

#### Databricks trusted libraries

{% hint style="warning" %}
**Security vulnerability**

Using this feature could create a security vulnerability, depending on the third-party library. For example, if a library exposes a public method named `readProtectedFile` that displays the contents of a sensitive file, then trusting that library would allow end users access to that file. Work with your Immuta support professional to determine if the risk does not apply to your environment or use case.
{% endhint %}

The trusted libraries feature allows Databricks cluster administrators to avoid [Immuta Security Manager errors when using third-party libraries](#user-content-fn-2)[^2]. An administrator can specify an installed library as trusted, which will enable that library's code to bypass the Immuta security manager. This feature does not impact Immuta's ability to apply policies; trusting a library only allows code through that otherwise would have been blocked by the Security Manager.

The following types of libraries are supported when installing a third-party library using the Databricks UI or the Databricks Libraries API:

* `Library source` is `Upload`, `DBFS` or `DBFS/S3` and the `Library Type` is `Jar`.
* `Library source` is `Maven`.

When users install third-party libraries, those libraries will be denied access to sensitive resources by default. However, cluster administrators can specify which of the installed Databricks libraries should be trusted by Immuta. See the [Install a trusted library guide](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/installation) to add a trusted library to your configuration.

**Limitations**

* Installing trusted libraries outside of the Databricks Libraries API (e.g., `ADD JAR ...`) is not supported.
* Databricks installs libraries right after a cluster has started, but there is no guarantee that library installation will complete before a user's code is executed. If a user executes code before a trusted library installation has completed, Immuta will not be able to identify the library as trusted. This can be solved by either
  * waiting for library installation to complete before running any third-party library commands or
  * executing a Spark query. This will force Immuta to wait for any trusted Immuta libraries to complete installation before proceeding.
* When installing a library using Maven as a library source, Databricks will also install any transitive dependencies for the library. However, those transitive dependencies are installed behind the scenes and will not appear as installed libraries in either the Databricks UI or using the Databricks Libraries API. Only libraries specifically listed in the `IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS` environment variable will be trusted by Immuta, which does not include installed transitive dependencies. This effectively means that any code paths that include a class from a transitive dependency but do not include a class from a trusted third-party library can still be blocked by the Immuta security manager. For example, if a user installs a trusted third-party library that has a transitive dependency of a `file-util` library, the user will not be able to directly use the `file-util` library to read a sensitive file that is normally protected by the Immuta security manager.

  In many cases, it is not a problem if dependent libraries aren't trusted because code paths where the trusted library calls down into dependent libraries will still be trusted. However, if the dependent library needs to be trusted, there is a workaround:

  1. Add the transitive dependency jar paths to the [`IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_trusted_lib_uris). In the driver `log4j` logs, Databricks outputs the source jar locations when it installs transitive dependencies. In the cluster driver logs, look for a log message similar to the following:

     ```bash
     INFO LibraryDownloadManager: Downloaded library dbfs:/FileStore/jars/maven/org/slf4j/slf4j-api-1.7.25.jar as
     local file /local_disk0/tmp/addedFile8569165920223626894slf4j_api_1_7_25-784af.jar
     ```
  2. In the above example, where `slf4j` is the transitive dependency, you would add the path `dbfs:/FileStore/jars/maven/org/slf4j/slf4j-api-1.7.25.jar` to the `IMMUTA_SPARK_DATABRICKS_TRUSTED_LIB_URIS` environment variable and restart your cluster.

#### External catalogs

Connect any of these [supported external catalogs](/2026.2/configuration/manage-data-metadata/catalogs/reference-guides/pre-configuration#supported-external-catalogs) to work with your Databricks Spark integration so data owners can tag their data.

#### External metastores

Immuta supports the use of external metastores in [local or remote mode](https://docs.databricks.com/data/metastores/external-hive-metastore.html#hive-metastore-deployment-modes):

* **Local mode**: The metastore client running inside a cluster connects to the underlying metastore database directly via JDBC.
* **Remote mode**: Instead of connecting to the underlying database directly, the metastore client connects to a separate metastore service via the Thrift protocol. The metastore service connects to the underlying database. When running a metastore in remote mode, DBFS is not supported.

For more details about these deployment modes, see [how to set up Databricks clusters to connect to an existing external Apache Hive metastore](https://docs.databricks.com/en/archive/external-metastores/external-hive-metastore.html#hive-metastore-deployment-modes).

<details>

<summary>Configure external Hive metastore</summary>

Download the metastore jars and point to them as specified in [Databricks documentation](https://docs.databricks.com/data/metastores/external-hive-metastore.html#download-the-metastore-jars-and-point-to-them). Metastore jars must end up on the cluster's local disk at this explicit path: `/databricks/hive_metastore_jars`.

If using DBR 7.x with Hive 2.3.x, either

* Set `spark.sql.hive.metastore.version` to `2.3.7` and `spark.sql.hive.metastore.jars` to `builtin` or
* Download the metastore jars and set `spark.sql.hive.metastore.jars` to `/databricks/hive_metastore_jars/*` as before.

</details>

<details>

<summary>Configure AWS Glue Data Catalog</summary>

To use AWS Glue Data Catalog as the metastore for Databricks, see the [Databricks documentation](https://docs.databricks.com/data/metastores/aws-glue-metastore.html).

</details>

#### Notebook-scoped libraries on machine learning clusters

Users on Databricks Runtimes 8+ can manage notebook-scoped libraries with [`%pip` commands](https://docs.databricks.com/libraries/notebooks-python-libraries.html#install-notebook-scoped-libraries-with-pip).

However, this functionality differs from the [support for Databricks trusted libraries](#databricks-trusted-libraries), and Python libraries are not supported as trusted libraries. The Immuta Security Manager will deny the code of libraries installed with `%pip` access to sensitive resources.

#### Scratch paths

Scratch paths are cluster-specific remote file paths that Databricks users are allowed to directly read from and write to without restriction. The creator of a Databricks cluster specifies the set of remote file paths that are designated as scratch paths on that cluster when they configure a Databricks cluster. Scratch paths are useful for scenarios where non-sensitive data needs to be written out to a specific location using a Databricks cluster protected by Immuta.

To configure a scratch path, use the [`IMMUTA_SPARK_DATABRICKS_SCRATCH_PATHS` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_scratch_paths).

[^1]: Databricks change data feed (CDF) shows the row-level changes between versions of a Delta table. The changes displayed include row data and metadata that indicates whether the row was inserted, deleted, or updated.

[^2]: The Immuta Security Manager blocks users from executing code that could allow them to gain access to sensitive data by only allowing select code paths to access sensitive files and methods. These select code paths provide Immuta's code access to sensitive resources while blocking end users from these sensitive resources directly.


# Setting Up Users

Learn about user impersonation and how to map your Databricks users into Immuta

When the Databricks Spark plugin is running on a Databricks cluster, all Databricks users running jobs or queries are either a privileged user or a non-privileged user:

* **Privileged users:** Privileged users can effectively read from and write to any table or view in the cluster Metastore, or any file path accessible by the cluster, without restriction. Privileged users are either [Databricks workspace admins](https://docs.databricks.com/en/admin/index.html#workspace-admins) or users specified in [`IMMUTA_SPARK_ACL_ALLOWLIST`](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_acl_allowlist). Any user writing queries or jobs impersonating another user is a non-privileged user, even if they are impersonating a privileged user.

  Privileged users have effective authority to read from and write to any securable in the cluster metastore or file path, because in almost all cases Databricks clusters running with the Immuta Spark plug-in installed have disabled [Hive metastore table access control](https://docs.databricks.com/en/data-governance/table-acls/table-acl.html). However, if Hive metastore table access control is enabled on the cluster, privileged users will have the authority granted to them that is specified by table access control.
* **Non-privileged users**: Non-privileged users are any users who are not privileged users, and all authorization for non-privileged users is determined by Immuta policies.

Whether a user is a privileged user or a non-privileged user, for a given query or job, is cached once first determined, based on [`IMMUTA_SPARK_ACL_PRIVILEGED_TIMEOUT_SECONDS` environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_acl_privileged_timeout_seconds). This caching can be disabled entirely by setting the value of that environment variable to `0`.

## Mapping Databricks users to Immuta

Usernames in Databricks must match the usernames in the connected Immuta tenant. By default, the Immuta Spark plugin checks the Databricks username against the username within Immuta's internal IAM to determine access. However, you can integrate your existing IAM with Immuta and use that instead of the default internal IAM. Ideally, you should use the same identity manager for Immuta that you use for Databricks. See the [Immuta support matrix page](/2026.2/releases/support-matrix) for a list of supported identity providers and protocols.

It is possible within Immuta to have multiple users share the same username if they exist within different IAMs. In this case, the cluster can be configured to look up users from a specified IAM. To do this, the value of the[`IMMTUA_USER_MAPPING_IAMID` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_user_mapping_iamid) must be updated to be the targeted IAM ID configured within the Immuta tenant. The targeted IAM ID can be found on the [App settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#navigate-to-the-app-settings-page). Each Databricks cluster can only be mapped to one IAM.

## User impersonation

Databricks user impersonation allows a Databricks user to impersonate an Immuta user. With this feature,

* **the Immuta user who is being impersonated** does not have to have a Databricks account, but they must have an Immuta account.
* **the Databricks user who is impersonating an Immuta user** does not have to be associated with Immuta. For example, this could be a service account.

When acting under impersonation, the Databricks user loses their privileged access, so they can only access the tables the Immuta user has access to and only perform DDL commands when that user is acting under an allowed circumstance (such as workspaces, scratch paths, or non-Immuta reads/writes).

Use the [`IMMUTA_SPARK_DATABRICKS_ALLOWED_IMPERSONATION_USERS` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_databricks_allowed_impersonation_users) to enable user impersonation.

{% hint style="warning" %}
**Scala clusters**

Immuta discourages use of this feature with Scala clusters, as the proper security mechanisms were not built to account for [user isolation limitations in Scala clusters](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance#scala-clusters). Instead, this feature was developed for the BI tool use case in which service accounts connecting to the Databricks cluster need to impersonate Immuta users so that policies can be enforced.
{% endhint %}

{% hint style="info" %}
**Prevent users from changing impersonation user in a given session**

If your BI tool or other service allows users to submit arbitrary SQL or issue SET commands, set `IMMUTA_SPARK_DATABRICKS_SINGLE_IMPERSONATION_USER` to `true` to prevent users from changing their impersonation user once it has been set for a given Spark session.
{% endhint %}

### Audited queries

Audited queries include an `impersonationUser` field, which identifies the Databricks user impersonating the Immuta user:

```json
{
  "id": "query-a20e-493e-id-c1ada0a23a26",
  "dateTime": "1639684812845",
  "month": 1463,
  "profileId": 4,
  "userId": "smwilliams@example.com",
  "dataSourceId": 1,
  "dataSourceName": "Hr Data",
  "count": 1,
  "recordType": "spark",
  "success": true,
  "component": "dataSource",
  "accessType": "query",
  "query": "Relation[id#2644,first_name#2645,last_name#2646,email#2647,gender#2648,race#2649,ssn#2650,dept#2651,job#2652,skills#2653,salary#2654,type#2655] parquet\n",
  "extra": {
    "databricksWorkspaceID": "0",
    "maskedColumns": {},
    "metastoreTables": [
      "demo.hr_data"
    ],
    "clusterName": "your-cluster-name",
    "pathUris": [
      "dbfs:/user/hive/warehouse/demo.db/hr_data"
    ],
    "queryText": "select * from demo.hr_data limit 10;",
    "queryLanguage": "sql",
    "clusterID": "your-171358-cluster-id",
    "impersonationUser": "edixon@example.com"
  },
  "dataSourceTableName": "demo_hr_data",
  "createdAt": "2021-12-16T20:00:12.850Z",
  "updatedAt": "2021-12-16T20:00:12.850Z"
}
```


# Spark Environment Variables

Learn about the available Spark environment variables so that you can customize your Databricks Spark integration

This page outlines configuration details for Immuta-enabled Databricks clusters. Databricks administrators should place the desired configuration in the Spark environment variables.

## IMMUTA\_INIT\_ADDITIONAL\_CONF\_URI

If you add additional Hadoop configuration during the integration setup, this variable sets the path to that file.

The additional Hadoop configuration is where sensitive configuration goes for remote filesystems (if you are using a secret key pair to access S3, for example).

## IMMUTA\_EPHEMERAL\_HOST\_OVERRIDE

**Default value**: `true`

Set this to `false` if ephemeral overrides should not be enabled for Spark. When `true`, this will automatically override ephemeral data source httpPaths with the httpPath of the Databricks cluster running the user's Spark application.

## IMMUTA\_EPHEMERAL\_HOST\_OVERRIDE\_HTTPPATH

This configuration item can be used if automatic detection of the Databricks httpPath should be disabled in favor of a static path to use for ephemeral overrides.

## IMMUTA\_EPHEMERAL\_TABLE\_PATH\_CHECK\_ENABLED

**Default value**: `true`

When querying Immuta data sources in Spark, the metadata from the Metastore is compared to the metadata for the target source in Immuta to validate that the source being queried exists and is queryable on the current cluster. This check typically validates that the target (database, table) pair exists in the Metastore and that the table’s underlying location matches what is in Immuta. This configuration can be used to disable location checking if that location is dynamic or changes over time. *Note: This may lead to undefined behavior if the same table names exist in multiple workspaces but do not correspond to the same underlying data.*

## IMMUTA\_INIT\_ALLOWED\_CALLING\_CLASSES\_URI

A URI that points to a valid calling class file, which is an Immuta artifact you download during the [Databricks Spark configuration](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/configuration) process.

## IMMUTA\_SPARK\_ACL\_ALLOWLIST

This is a comma-separated list of Databricks users who can access any table or view in the cluster metastore without restriction.

## IMMUTA\_SPARK\_ACL\_PRIVILEGED\_TIMEOUT\_SECONDS

**Default value**: `3600`

The number of seconds to cache privileged user status for the Immuta ACL. A privileged Databricks user is an admin or is allowlisted in `IMMUTA_SPARK_ACL_ALLOWLIST`.

## IMMUTA\_SPARK\_AUDIT\_ALL\_QUERIES

**Default value**: `false`

Enables auditing all queries run on a Databricks cluster, regardless of whether users touch Immuta-protected data or not.

## IMMUTA\_SPARK\_DATABRICKS\_ALLOW\_NON\_IMMUTA\_READS

**Default value**: `false`

Allows non-privileged users to `SELECT` from tables that are not protected by Immuta. See the [Customizing the integration guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables) for details about this feature.

## IMMUTA\_SPARK\_DATABRICKS\_ALLOW\_NON\_IMMUTA\_WRITES

**Default value**: `false`

Allows non-privileged users to run DDL commands and data-modifying commands against tables or spaces that are not protected by Immuta. See the [Customizing the integration guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables) for details about this feature.

## IMMUTA\_SPARK\_DATABRICKS\_ALLOWED\_IMPERSONATION\_USERS

This is a comma-separated list of Databricks users who are allowed to impersonate Immuta users:

```json
"spark_env_vars.IMMUTA_SPARK_DATABRICKS_ALLOWED_IMPERSONATION_USERS": {
  "type": "fixed",
  "value": "edixon@example.com,dakota@example.com"
}
```

## IMMUTA\_SPARK\_DATABRICKS\_DBFS\_MOUNT\_ENABLED

**Default value**: `false`

Exposes the DBFS FUSE mount located at `/dbfs`. Granular permissions are not possible, so all users will have read/write access to all objects therein. *Note: Raw, unfiltered source data should never be stored in DBFS.*

## IMMUTA\_SPARK\_DATABRICKS\_DISABLED\_UDFS

Block one or more Immuta [user-defined functions (UDFs)](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/project-udfs) from being used on an Immuta cluster. This should be a Java regular expression that matches the set of UDFs to block by name (excluding the `immuta` database). For example to block all project UDFs, you may configure this to be `^.*_projects?$`. For a list of functions, see the [project UDFs page](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/reference-guides/project-udfs#available-functions).

## IMMUTA\_SPARK\_DATABRICKS\_JAR\_URI

**Default value**: `file:///databricks/jars/immuta-spark-hive.jar`

The location of `immuta-spark-hive.jar` on the filesystem for Databricks. This should not need to change unless a custom initialization script that places immuta-spark-hive in a non-standard location is necessary.

## IMMUTA\_SPARK\_DATABRICKS\_LOCAL\_SCRATCH\_DIR\_ENABLED

**Default value**: `true`

Creates a world-readable or writable scratch directory on local disk to facilitate the use of `dbutils` and 3rd party libraries that may write to local disk. Its location is non-configurable and is stored in the environment variable `IMMUTA_LOCAL_SCRATCH_DIR`. Note: Sensitive data should not be stored at this location.

## IMMUTA\_SPARK\_DATABRICKS\_LOG\_LEVEL

**Default value**: `INFO`

The SLF4J log level to apply to Immuta's Spark plugins.

## IMMUTA\_SPARK\_DATABRICKS\_LOG\_STDOUT\_ENABLED

**Default value**: `false`

If true, writes logging output to stdout/the console as well as the `log4j-active.txt` file (default in Databricks).

## IMMUTA\_SPARK\_DATABRICKS\_SCRATCH\_DATABASE

This configuration is a comma-separated list of additional databases that will appear as scratch databases when running a `SHOW DATABASE` query. This configuration increases performance by circumventing the Metastore to get the metadata for all the databases to determine what to display for a `SHOW DATABASE` query; it won't affect access to the scratch databases. Instead, use [`IMMUTA_SPARK_DATABRICKS_SCRATCH_PATHS`](#immuta_spark_databricks_scratch_paths) to control read and write access to the underlying database paths.

Additionally, this configuration will only display the scratch databases that are configured and will not validate that the configured databases exist in the Metastore. Therefore, it is up to the Databricks administrator to properly set this value and keep it current.

## IMMUTA\_SPARK\_DATABRICKS\_SCRATCH\_PATHS

Comma-separated list of remote paths that Databricks users are allowed to directly read/write. These paths amount to unprotected "scratch spaces." You can create a scratch database by configuring its specified location (or configure `dbfs:/user/hive/warehouse/<db_name>.db` for the default location).

To create a scratch path to a location or a database stored at that location, configure

```bash
IMMUTA_SPARK_DATABRICKS_SCRATCH_PATHS=s3://path/to/the/dir
```

To create a scratch path to a database created using the default location,

```bash
IMMUTA_SPARK_DATABRICKS_SCRATCH_PATHS=s3://path/to/the/dir,dbfs:/user/hive/warehouse/any_db_name.db</value>
```

## IMMUTA\_SPARK\_DATABRICKS\_SCRATCH\_PATHS\_CREATE\_DB\_ENABLED

**Default value**: `false`

Enables non-privileged users to create or drop scratch databases.

## IMMUTA\_SPARK\_DATABRICKS\_SINGLE\_IMPERSONATION\_USER

**Default value**: `false`

When `true`, this configuration prevents users from changing their impersonation user once it has been set for a given Spark session. This configuration should be set when the BI tool or other service allows users to submit arbitrary SQL or issue SET commands.

## IMMUTA\_SPARK\_DATABRICKS\_SUBMIT\_TAG\_JOB

**Default value**: `true`

Denotes whether the Spark job will be run that "tags" a Databricks cluster as being associated with Immuta.

## IMMUTA\_SPARK\_DATABRICKS\_TRUSTED\_LIB\_URIS

A comma-separated list of [Databricks trusted library](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/installation) URIs.

## IMMUTA\_SPARK\_NON\_IMMUTA\_TABLE\_CACHE\_SECONDS

**Default value**: `3600`

The number of seconds Immuta caches whether a table has been exposed as a data source in Immuta. This setting only applies when `IMMUTA_SPARK_DATABRICKS_ALLOW_NON_IMMUTA_WRITES` or `IMMUTA_SPARK_DATABRICKS_ALLOW_NON_IMMUTA_READS` is enabled.

## IMMUTA\_SPARK\_REQUIRE\_EQUALIZATION

**Default value**: `false`

Requires that users act through a single, equalized project. A cluster should be equalized if users need to run Scala jobs on it, and it should be limited to Scala jobs only via `spark.databricks.repl.allowedLanguages`.

## IMMUTA\_SPARK\_RESOLVE\_RAW\_TABLES\_ENABLED

**Default value**: `true`

Enables use of the underlying database and table name in queries against a table-backed Immuta data source. Administrators or allowlisted users can set `IMMUTA_SPARK_RESOLVE_RAW_TABLES_ENABLED` to `false` to bypass resolving raw databases or tables as Immuta data sources. This is useful if an admin wants to read raw data but is also an Immuta user. By default, data policies will be applied to a table even for an administrative user if that admin is also an Immuta user.

## IMMUTA\_SPARK\_SESSION\_RESOLVE\_RAW\_TABLES\_ENABLED

**Default value**: `true`

Same as the [IMMUTA\_SPARK\_RESOLVE\_RAW\_TABLES\_ENABLED](#immuta_spark_resolve_raw_tables_enabled) variable, but this is a session property that allows users to toggle this functionality. If users run `set immuta.spark.session.resolve.raw.tables.enabled=false`, they will see raw data only (not Immuta data policy-enforced data). *Note: This property is not set in `immuta_conf.xml`.*

## IMMUTA\_SPARK\_SHOW\_IMMUTA\_DATABASE

**Default value**: `true`

This shows the `immuta` database in the configured Databricks cluster. When set to `false` Immuta will no longer show this database when a `SHOW DATABASES` query is performed. However, queries can still be performed against tables in the `immuta` database using the Immuta-qualified table name (e.g., `immuta.my_schema_my_table`) regardless of whether or not this feature is enabled.

## IMMUTA\_SPARK\_VERSION\_VALIDATE\_ENABLED

**Default value**: `true`

Immuta checks the versions of its artifacts to verify that they are compatible with each other. When set to `true`, if versions are incompatible, that information will be logged to the Databricks driver logs and the cluster will not be usable. If a configuration file or the jar artifacts have been patched with a new version (and the artifacts are known to be compatible), this check can be set to `false` so that the versions don't get logged as incompatible and make the cluster unusable.

## IMMUTA\_USER\_MAPPING\_IAMID

**Default value**: `bim`

Denotes which IAM in Immuta should be used when mapping the current Spark user's username to a userid in Immuta. This defaults to Immuta's internal IAM (`bim`) but should be updated to reflect an actual production IAM.


# Ephemeral Overrides

Learn about how Immuta uses ephemeral overrides to determine which cluster compute to use when connecting to Databricks for maintenance operations

In the context of the Databricks Spark integration, Immuta uses the term *ephemeral* to describe data sources where the associated compute resources can vary over time. This means that the compute bound to these data sources is not fixed and can change. All Databricks data sources in Immuta are ephemeral.

Ephemeral overrides are specific to each data source and user. They effectively bind cluster compute resources to a data source for a given user. Immuta uses these overrides to determine which cluster compute to use when connecting to Databricks for various maintenance operations.

The operations that use the ephemeral overrides include

* **Visibility checks on the data source for a particular user**. These checks assess how to apply row-level policies for specific users.
* **Stats collection triggered by a specific user**.
* **Validating a custom WHERE clause policy against a data source**. When owners or governors create custom WHERE clause policies, Immuta uses compute resources to validate the SQL in the policy. In this case, the ephemeral overrides for the user writing the policy are used to contact a cluster for SQL validation.
* **High cardinality column detection**. Certain advanced policy types (e.g., minimization) in Immuta require a high cardinality column, and that column is computed on data source creation. It can be recomputed on demand and, if so, will use the ephemeral overrides for the user requesting computation.

### Triggering an ephemeral override request

An ephemeral override request can be triggered when a user queries the securable corresponding to a data source in a Databricks cluster with the Spark plug-in configured. The actual triggering of this request depends on the [configuration settings](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_ephemeral_host_override).

Ephemeral overrides can also be set for a data source in the Immuta UI by navigating to a data source page, clicking on the data source actions button, and selecting **Ephemeral overrides** from the dropdown menu.

Ephemeral override requests made from a cluster for data sources and users where ephemeral overrides were set in the UI will not be successful.

If ephemeral overrides are never set (either through the user interface or the cluster configuration), the system will continue to use the connection details directly associated with the data source, which are set during [data source registration](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/registering-and-protecting-data#registering-data).

## Configuring overrides in Immuta-enabled clusters

Ephemeral overrides can be problematic in environments that have a dedicated cluster to handle maintenance activities, since ephemeral overrides can cause these operations to execute on a different cluster than the dedicated one.

To reduce the risk that a user has overrides set to a cluster (or multiple clusters) that aren't currently up, complete one of the following actions:

* Direct all clusters' HTTP paths for overrides to a cluster dedicated for metadata queries using the [`IMMUTA_EPHEMERAL_HOST_OVERRIDE_HTTPPATH` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_ephemeral_host_override_httppath).
* Disable ephemeral overrides completely by setting the [`IMMTUA_EPHEMERAL_HOST_OVERRIDE` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_ephemeral_host_override) to `false`.

{% hint style="info" %}
**Ephemeral overrides best practices**

1. Disable ephemeral overrides for clusters when using multiple workspaces and dedicate a single cluster to serve queries from Immuta in a single workspace.
2. If you use multiple E2 workspaces without disabling ephemeral overrides, avoid applying the **where user** row-level policy to data sources.
   {% endhint %}


# Security and Compliance

Understand the authentication methods, cluster security, and audit features supported by the Databricks Spark integration to ensure you are meeting your organization's security and compliance needs

Immuta offers several features to provide security for your users and Databricks clusters and to prove compliance and monitor for anomalies.

## Authentication

### Configuring the integration and registering data

Immuta supports the following authentication methods to configure the Databricks Spark integration and register data sources:

* **OAuth machine-to-machine (M2M)**: Immuta uses the [Client Credentials Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) to integrate with [Databricks OAuth machine-to-machine authentication](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html), which allows Immuta to authenticate with Databricks using a client secret. Once Databricks verifies the Immuta service principal’s identity using the client secret, Immuta is granted a temporary OAuth token to perform token-based authentication in subsequent requests. When that token expires (after one hour), Immuta requests a new temporary token.\
  \
  See the [Databricks OAuth machine-to-machine (M2M) authentication page](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html) for more details.
* **Personal access token (PAT)**: This token gives Immuta temporary permission to push the cluster policies to the configured Databricks workspace and overwrite any cluster policy templates previously applied to the workspace when configuring the integration or to register securables as Immuta data sources.

### User authentication

The built-in Immuta IAM can be used as a complete solution for authentication and fine-grained user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and fine-grained user entitlement instead.

Each of the supported identity providers includes a specific set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

See the [Identity managers guide](/2026.2/configuration/people/section-contents/reference-guides/identity-managers) for a list of supported providers and details.

See the [Setting up users guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/setting-up-users) for details and instructions on mapping Databricks user accounts to Immuta.

## Cluster security

### Data processing and encryption

See the [Data processing, encryption, and masking practices guide](/2026.2/configuration/application-settings/reference-guides/data-processing) for more information about transmission of policy decision data, encryption of data in transit and at rest, and encryption key management.

### Protecting the Immuta configuration

Non-administrator users on an Immuta-enabled Databricks cluster must not have access to view or modify Immuta configuration, as this poses a security loophole around Immuta policy enforcement. [Databricks secrets](https://docs.databricks.com/security/secrets/index.html#spark-conf-env-var) allow you to securely apply environment variables to Immuta-enabled clusters.

Databricks secrets can be used in the environment variables configuration section for a cluster by referencing the secret path instead of the actual value of the environment variable.

See the [Installation and compliance guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance#protecting-the-immuta-configuration) for details and instructions on using Databricks secrets.

### Scala cluster security

There are limitations to isolation among users in Scala jobs on a Databricks cluster. When data is broadcast, cached (spilled to disk), or otherwise saved to `SPARK_LOCAL_DIR`, it's impossible to distinguish between which user’s data is composed in each file/block. To address this vulnerability, Immuta suggests that you

* limit Scala clusters to Scala jobs only and
* require equalized projects, which will force all users to act under the same set of attributes, groups, and purposes with respect to their data access. This requirement guarantees that data being dropped into `SPARK_LOCAL_DIR` will have policies enforced and that those policies will be homogeneous for all users on the cluster. Since each user will have access to the same data, if they attempt to manually access other users' cached/spilled data, they will only see what they have access to via equalized permissions on the cluster. If project equalization is not turned on, users could dig through that directory and find data from another user with heightened access, which would result in a data leak.

See the [Installation and compliance guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance#scala-clusters) for more details and configuration instructions.

## Auditing and compliance

Immuta provides auditing features and governance reports so that data owners and governors can monitor users' access to data and detect anomalies in behavior.

You can view the information in these audit logs on [dashboards](/2026.2/governance/detect-your-activity/detection/detect-concept) or [configure your Immuta deployment with audit](/2026.2/configuration/self-managed-deployment/configure/audit-best-practices) for long-term backup and processing with log data processors and tools. This capability fosters convenient integrations with log monitoring services and data pipelines.

See the [Audit documentation](/2026.2/governance/detect-your-activity/audit/reference-guides/query-audit-logs/databricks-uc) for details about these capabilities and how they work with the Databricks Spark integration.

### Databricks query audit

Immuta captures the code or query that triggers the Spark plan in Databricks, making audit records more useful in assessing what users are doing.

To audit what triggers the Spark plan, Immuta hooks into Databricks where notebook cells and JDBC queries execute and saves the cell or query text. Then, Immuta pulls this information into the audits of the resulting Spark jobs.

Immuta will audit queries that come from interactive notebooks, notebook jobs, and JDBC connections, but will not audit [Scala or R submit jobs](/2026.2/configuration/integrations/databricks/databricks-spark/how-to-guides/spark-submit). Furthermore, Immuta only audits Spark jobs that are associated with Immuta tables. Consequently, Immuta will not audit a query in a notebook cell that does not trigger a Spark job, *unless* [*`IMMUTA_SPARK_AUDI_ALL_QUERIES` is set to `true`.*](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_audit_all_queries)

See the [Databricks Spark query audit logs](/2026.2/governance/detect-your-activity/audit/reference-guides/query-audit-logs/databricks) page for examples of saved queries and the resulting audit records. To exclude query text from audit events, see the [App settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#exclude-query-text-from-audit-records).

### Auditing all queries

Immuta supports auditing all queries run on a Databricks cluster, regardless of whether users touch Immuta-protected data or not.

See the [Installation and compliance guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance#audit) for details and instructions.

### Auditing queries run while impersonating another user

When a query is run by a user impersonating another user, the `extra.impersonationUser` field in the audit log payload is populated with the Databricks username of the user impersonating another user. The `userId` field will return the Immuta username of the user being impersonated:

```json
{
  "id": "query-a20e-493e-id-c1ada0a23a26",
  [...]
  "userId": "<immuta_username>",
  [...]
  "extra": {
    [...]
    "impersonationUser": "<databricks_username>"
  }
  [...]
}
```

See the [Setting up users guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/setting-up-users#user-impersonation) for details about user impersonation.

### Governance reports

Immuta governance reports allow users with the `GOVERNANCE` Immuta permission to use a natural language builder to instantly create reports that delineate user activity across Immuta. These reports can be based on various entity types, including users, groups, projects, data sources, purposes, policy types, or connection types.

See the [Governance report types page](/2026.2/governance/detect-your-activity/audit/reference-guides/reports) for a list of report types and guidance.


# Registering and Protecting Data

Learn how Immuta enforces policies on data in your Databricks Spark environment

In the Databricks Spark integration, Immuta installs an Immuta-maintained Spark plugin on your Databricks cluster. When a user queries data that has been registered in Immuta as a data source, the plugin injects policy logic into the plan Spark builds so that the results returned to the user only include data that specific user should see.

The sequence diagram below breaks down this process of events when an Immuta user queries data in Databricks.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/Eu2EL99TCyostZ7V5e1q/databricks-spark-process-diagram.png" alt=""><figcaption><p>Immuta intercepts Spark calls to the Metastore. Immuta then modifies the logical plan so that policies are applied to the data for the querying user.</p></figcaption></figure>

## Registering data

When data owners register Databricks securables in Immuta, the securable metadata is registered and Immuta creates a corresponding [data source](#user-content-fn-1)[^1] for those securables. The data source metadata is stored in the Immuta Metadata Database so that it can be referenced in policy definitions.

The image below illustrates what happens when a data owner registers the `Accounts`, `Claims`, and `Customers` securables in Immuta.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/EPLiFNgUC1mjEvrIm2py/Databricks%20Spark%20metadata%20ingestion.png" alt=""><figcaption></figcaption></figure>

Users who are subscribed to the data source in Immuta can then query the corresponding securable directly in their Databricks notebook or workspace.

### Authentication methods

See the [Installation and compliance page](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/installation-and-compliance#authentication-methods) for details about the authentication methods supported for registering data.

### Schema monitoring

When schema monitoring is enabled, Immuta monitors your servers to detect when new tables or columns are created or deleted, and automatically registers (or disables) those tables in Immuta. These newly updated data sources will then have any global policies and tags that are set in Immuta applied to them. The Immuta data source columns will be updated with any column changes, and the Immuta environment will be in sync with your data environment.

For Databricks Spark, the automatic [schema monitoring job](/2026.2/configuration/integrations/registering-metadata/data-sources/schema-monitoring/reference-guides/schema-monitoring) is disabled because of the [ephemeral nature of Databricks clusters](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/ephemeral-overrides). In this case, Immuta requires you to download a schema detection job template (a Python script) and import that into your Databricks workspace.

See the [Register a Databricks data source guide](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/databricks-tutorial#enable-or-disable-schema-monitoring) for instructions on enabling schema monitoring.

### Ephemeral overrides

In Immuta, a Databricks data source is considered ephemeral, meaning that the compute resources associated with that data source will not always be available.

Ephemeral data sources allow the use of ephemeral overrides, user-specific connection parameter overrides that are applied to Immuta metadata operations.

When a user runs a Spark job in Databricks, the Immuta plugin automatically submits ephemeral overrides for that user to Immuta. Consequently, [subsequent metadata operations for that user will use the current cluster as compute](#user-content-fn-2)[^2].

See the [Ephemeral overrides page](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/ephemeral-overrides) for more details about ephemeral overrides and how to configure or disable them.

#### Ephemeral override requests

The Spark plugin has the capability to send ephemeral override requests to Immuta. These requests are distinct from ephemeral overrides themselves. Ephemeral overrides cannot be turned off, but the Spark plugin can be configured to not send ephemeral override requests.

### Tag ingestion

Tags can be used in Immuta in a variety of ways:

* Use tags for global subscription or data policies that will apply to all data sources in the organization. In doing this, company-wide data security restrictions can be controlled by the administrators and governors, while the users and data owners need only to worry about tagging the data correctly.
* Generate Immuta reports from tags for insider threat surveillance or data access monitoring.
* Filter search results with tags in the Immuta UI.

The Databricks Spark integration cannot ingest tags from Databricks, but you can connect any of these [supported external catalogs](/2026.2/configuration/manage-data-metadata/catalogs/reference-guides/pre-configuration#supported-external-catalogs) to work with your integration.

You can also manage tags in Immuta by [manually adding tags](/2026.2/configuration/manage-data-metadata/tags) to your data sources and columns. Alternatively, you can use [identification](/2026.2/configuration/manage-data-metadata/data-discovery) to automatically tag your sensitive data.

## Protecting data

Immuta allows you to author subscription and data policies to automate access controls on your Databricks data.

* **Subscription policies:** After registering data sources in Immuta, you can control who has access to specific securables in Databricks through Immuta subscription policies or by [manually adding users to the data source](/2026.2/configuration/integrations/registering-metadata/data-sources/data-source-settings/how-to-guides/manage-members). Data users will only see the `immuta` database with no tables until they are granted access to those tables as Immuta data sources. See the [Subscription policy access types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types) for a list of policy types supported.
* **Data policies**: You can create data policies to apply fine-grained access controls (such as restricting rows or masking columns) to manage what users can see in each table after they are subscribed to a data source. See the [Data policy types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#policy-support-matrix) for details about specific types of data policies supported.

The image below illustrates how Immuta enforces a subscription policy that only allows users in the `Analysts` group to access the `yellow-table`.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/PRFeGrSbbAxho6iYLYIU/databricks-policy-enforcement.png" alt=""><figcaption></figcaption></figure>

See the [Automate data access control decisions page](/2026.2/governance/getting-started-with-secure/automate-data-access-control-decisions) for details about the benefits of using Immuta subscription and data policies.

### Policy enforcement in Databricks

Once a Databricks user who is subscribed to the data source in Immuta [queries the corresponding securable](/2026.2/governance/data-consumers/query-data/databricks) directly in their workspace, Spark Analysis initiates and the following events take place:

1. Spark calls down to the Metastore to get table metadata.
2. Immuta intercepts the call to retrieve table metadata from the Metastore.
3. Immuta modifies the Logical Plan to enforce policies that apply to that user.
4. Immuta wraps the Physical Plan with specific Java classes to signal to the Security Manager that it is a trusted node and is allowed to scan raw data.
5. The Physical Plan is applied and filters out and transforms raw data coming back to the user.
6. The user sees policy-enforced data.

The image below illustrates what happens when an Immuta user who is subscribed to the `Customers` data source queries the securable in Databricks.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/h2Poq1m7o0zpD8ClB3lH/Spark%20analysis.png" alt=""><figcaption></figcaption></figure>

#### **Users who can read raw tables on-cluster**

Regardless of the policies on the data source, the users will be able to read raw data on the cluster if they meet one of the criteria listed below:

* Databricks administrator is tied to an Immuta account
* A Databricks user is listed as an ignored user (Users can be specified in the [`IMMUTA_SPARK_ACL_ALLOWLIST` Spark environment variable](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_spark_acl_allowlist) to become ignored users.)

### Protected and unprotected tables

Generally, Immuta prevents users from seeing data unless they are explicitly given access, which blocks access to raw sources in the underlying databases.

Databricks non-admin users will only see sources to which they are subscribed in Immuta, and this can present problems if organizations have a data lake full of non-sensitive data and Immuta removes access to all of it. To address this challenge, Immuta allows administrators to change this default setting when configuring the integration so that Immuta users can access securables that are not registered as a data source. Although this is similar to how privileged users in Databricks operate, non-privileged users cannot bypass Immuta controls.

See the [Customizing the integration guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#protected-and-unprotected-tables) for details about this setting.

### Restricting users' access to data with Immuta projects

Immuta projects combine users and data sources under a common purpose. Sometimes this purpose is for a single user to organize their data sources or to control an entire schema of data sources through a single projects screen; however, most often this is an Immuta purpose for which the data has been approved to be used and will restrict access to data and streamline team collaboration. Consequently, data owners can restrict access to data for a specified purpose through projects.

When a user is working within the context of a project, they will only see the data in that project. This helps to prevent data leaks when users collaborate. Users can switch project contexts to access various data sources while acting under the appropriate purpose.

When users change project contexts (either through the Immuta UI or with [project UDFs](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/reference-guides/project-udfs)), queries reflect users as acting under the purposes of that project, which may allow additional access to data if there are purpose restrictions on the data source(s). This process also allows organizations to track not just *whether* a specific data source is being used, but *why*.

See the [Customizing the integration page](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/customizing-the-integration#restricting-users-access-with-immuta-projects) for details about how to prevent users from switching project contexts in a session.

#### Project workspaces

Users can have additional write access in their integration using project workspaces. Users can integrate a single or multiple workspaces with a single Immuta tenant.

See the [Project workspaces page](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/reference-guides/project-workspaces#databricks-spark-project-workspaces) for more details.

[^1]: A data source is a virtual representation of the Databricks securable.

[^2]: The actual triggering of this request depends on the [configuration settings](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks/configuration#immuta_ephemeral_host_override). If ephemeral overrides are never set, the system will continue to use the connection details directly associated with the data source, which are set during data source registration.


# Accessing Data

Learn how end users can access policy-enforced data in Databricks Spark

Once a Databricks securable is registered in Immuta as a data source and you are subscribed to that data source, you must access that data through SQL:

{% tabs %}
{% tab title="Python" %}

```python
df = spark.sql("select * from immuta.table")
```

{% endtab %}

{% tab title="Scala" %}

```scala
import org.apache.spark.sql.SparkSession

val spark = SparkSession
  .builder()
  .appName("Spark SQL basic example")
  .config("spark.some.config.option", "some-value")
  .getOrCreate()
val sqlDF = spark.sql("SELECT * FROM immuta.table")
```

{% endtab %}

{% tab title="SQL" %}

```sql
%sql
select * from immuta.table
```

{% endtab %}

{% tab title="R" %}

```r
library(SparkR)
df <- SparkR::sql("SELECT * from immuta.table")
```

*With R, you must load the SparkR library in a cell before accessing the data.*
{% endtab %}
{% endtabs %}

See the sections below for more guidance on accessing data using [Delta Lake](#delta-lake), [direct file reads in Spark for file paths](#spark-direct-file-reads), and [user impersonation](#user-impersonation).

## Delta Lake

When using Delta Lake, the API does not go through the normal Spark execution path. This means that Immuta's Spark extensions do not provide protection for the API. To solve this issue and ensure that Immuta has control over what a user can access, the Delta Lake API is blocked.

Spark SQL can be used instead to give the same functionality with all of Immuta's data protections. See the [Delta API reference guide](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/accessing-data/delta-lake-api) for a list of corresponding Spark SQL calls to use.

## Spark direct file reads

In addition to supporting direct file reads through workspace and scratch paths, Immuta allows direct file reads in Spark for file paths. As a result, users who prefer to interact with their data using file paths or who have existing workflows revolving around file paths can continue to use these workflows without rewriting those queries for Immuta.

When reading from a path in Spark, the Immuta Databricks Spark plugin queries the Immuta Web Service to find Databricks data sources for the current user that are backed by data from the specified path. If found, the query plan maps to the Immuta data source and follows existing code paths for policy enforcement.

Users can read data from individual parquet files in a sub-directory and partitioned data from a sub-directory (or by using a `where` predicate). Expand the blocks below to view examples of reading data using these methods.

<details>

<summary>Read data from an individual parquet file</summary>

To read from an individual file, load a partition file from a sub-directory:

```bash
spark.read.format("parquet").load("s3:/my_bucket/path/to/my_parquet_table/partition_column=01/my_file.parquet")
```

</details>

<details>

<summary>Read partitioned data from a sub-directory</summary>

To read partitioned data from a sub-directory, load a parquet partition from a sub-directory:

```bash
spark.read.format("parquet").load("s3:/my_bucket/path/to/my_parquet_table/partition_column=01")
```

Alternatively, load a parquet partition using a `where` predicate:

```bash
spark.read.format("parquet").load("s3:/my_bucket/path/to/my_parquet_table").where("partition_column=01")Read partitioned data from a sub-directory
```

</details>

### Limitations

* Direct file reads for Immuta data sources only apply to data sources created from tables, not data sources created from views or queries.
* If more than one data source has been created for a path, Immuta will use the first valid data source it finds. It is therefore not recommended to use this integration when more than one data source has been created for a path.
* In Databricks, multiple input paths are supported as long as they belong to the same data source.
* CSV-backed tables are not currently supported.
* Loading a `delta` partition from a sub-directory is not recommended by Spark and is not supported in Immuta. Instead, use a `where` predicate:

  ```bash
  # Not recommended by Spark and not supported in Immuta
  spark.read.format("delta").load("s3:/my_bucket/path/to/my_delta_table/partition_column=01")

  # Recommended by Spark and supported in Immuta.
  spark.read.format("delta").load("s3:/my_bucket/path/to/my_delta_table").where("partition_column=01")

  ```

## User impersonation

User impersonation allows Databricks users to query data as another Immuta user. To impersonate another user, see the [Impersonate a user page](/2026.2/governance/data-consumers/user-impersonation#databricks-spark).


# Delta Lake API

Learn how to use Spark SQL to achieve the same functionality as the Delta Lake API

When using Delta Lake, the API does not go through the normal Spark execution path. This means that Immuta's Spark extensions do not provide protection for the API. To solve this issue and ensure that Immuta has control over what a user can access, the Delta Lake API is blocked.

Spark SQL can be used instead to give the same functionality with all of Immuta's data protections.

## Requests

Below is a table of the Delta Lake API with the Spark SQL that may be used instead.

| Delta Lake API            | Spark SQL                                                                                |
| ------------------------- | ---------------------------------------------------------------------------------------- |
| DeltaTable.convertToDelta | CONVERT TO DELTA parquet.`/path/to/parquet/`                                             |
| DeltaTable.delete         | DELETE FROM \[table\_identifier delta.`/path/to/delta/`] WHERE condition                 |
| DeltaTable.generate       | GENERATE symlink\_format\_manifest FOR TABLE \[table\_identifier delta.`/path/to/delta`] |
| DeltaTable.history        | DESCRIBE HISTORY \[table\_identifier delta.`/path/to/delta`] (LIMIT x)                   |
| DeltaTable.merge          | MERGE INTO                                                                               |
| DeltaTable.update         | UPDATE \[table\_identifier delta.`/path/to/delta/`] SET column = valueWHERE (condition)  |
| DeltaTable.vacuum         | VACUUM \[table\_identifier delta.`/path/to/delta`]                                       |

See here for a complete list of the [Delta SQL Commands](https://docs.databricks.com/delta/index.html).

## Merging tables in workspaces

When a table is created in a project workspace, you can merge a different Immuta data source from that workspace into that table you created.

1. [Create a table in the project workspace](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/writing-to-projects/how-to-guides/write-data-back).
2. Create a temporary view of the Immuta data source you want to merge into that table.
3. Use that temporary view as the data source you add to the project workspace.
4. Run the following command:

   ```bash
   MERGE INTO delta_native.target_native as target
   USING immuta_temp_view_data_source as source
   ON target.dr_number = source.dr_number
   WHEN MATCHED THEN
   UPDATE SET target.date_reported = source.date_reported
   ```


# Databricks Unity Catalog

Learn how Databricks can enforce Immuta policies automatically across data in your Unity Catalog metastore

The how-to guides linked on this page illustrate how to integrate Databricks Unity Catalog with Immuta. See the [reference guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide) for information about the Databricks Unity Catalog integration.

**Requirements**:

* Unity Catalog [metastore created](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html) and attached to a Databricks workspace. Immuta supports configuring a single metastore for each configured integration, and that metastore may be attached to multiple Databricks workspaces.
* Unity Catalog enabled on your Databricks cluster or SQL warehouse. All SQL warehouses have Unity Catalog enabled if your workspace is attached to a Unity Catalog metastore.

{% stepper %}
{% step %}
**Connect your technology**

These guides provide instructions on getting your data set up in Immuta.

1. [Register your Databricks Unity Catalog connection](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection): Using a single setup process, connect Databricks Unity Catalog to Immuta. This will register your data objects into Immuta and allow you to start dictating access through global policies.
2. [Organize your data sources into domains and assign domain permissions to accountable teams](/2026.2/configuration/domains): Use domains to segment your data and assign responsibilities to the appropriate team members. These domains will then be used to manage permissions for publishing data products, authoring policies, viewing audit and managing identification.
   {% endstep %}

{% step %}
**Register your users**

These guides provide instructions on getting your users set up in Immuta.

1. [Connect an IAM](/2026.2/configuration/people/section-contents#how-to-guides): Bring the IAM your organization already uses and allow Immuta to register your users for you.
2. [Map external user IDs from Databricks to Immuta](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping): Ensure the user IDs in Immuta, Databricks, and your IAM are aligned so that the right policies impact the right users.
   {% endstep %}

{% step %}
**Add data metadata**

These guides provide instructions on getting your data metadata set up in Immuta.

1. [Connect an external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure): Bring the external catalog your organization already uses and allow Immuta to continually sync your tags with your data sources for you.
2. [Run identification](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/manage-sdd-tags): Identification allows you to automate data tagging using identifiers that detect certain data patterns.
   {% endstep %}

{% step %}
**Start using policy and audit**

These guides provide instructions on using policy and audit for the first time.

1. [Author a global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial): Once you add your data metadata to Immuta, you can immediately create policies that utilize your tags and apply to your tables. Subscription policies can be created to dictate access to data sources.
2. [Author a global data policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial): Data metadata can also be used to create data policies that apply to data sources as they are registered in Immuta. Data policies dictate what data a user can see once they are granted access to a data source. Using catalog and identification tags you can create proactive policies, knowing that they will apply to data sources as they are added to Immuta with the automated tagging.
3. [Configure audit](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam): Once you have your data sources and users, and policies granting them access, you can set up audit export. This will export the audit logs from user queries, policy changes, and tagging updates.
   {% endstep %}
   {% endstepper %}


# How-to Guides


# Register a Databricks Unity Catalog Connection

Register your Databricks Unity Catalog data

## **Requirements**

* **Immuta user** with the `APPLICATION_ADMIN` Immuta permission
* [**Databricks service principal**](#user-content-fn-1)[^1] with the following privileges. For instructions on setting up this user, see the [Creating the Databricks service principal section](#setting-up-the-required-databricks-service-principal):
  * `USE CATALOG` and `MANAGE` on all catalogs containing securables you want registered as Immuta data sources.
  * `USE SCHEMA` on all schemas containing securables you want registered as Immuta data sources.
  * [`MODIFY`](#user-content-fn-2)[^2] and `SELECT` on all securables you want registered as Immuta data sources.
  * Workspace admin on the workspace configured as the host for the integration.
  * Additional privileges are required for query audit:
    * `USE CATALOG` on the `system` catalog
    * `USE SCHEMA` on the `system.access` and `system.query` schemas
    * `SELECT` on the following system tables:
      * `system.access.table_lineage`
      * `system.access.column_lineage`
      * `system.access.audit`
      * `system.query.history`
    * Add the Databricks service principal to the `databricks_pii_access` group
* **Databricks user to run the script to register the connection** with the following privileges:
  * [Metastore admin and account admin](#user-content-fn-3)[^3]
  * `CREATE CATALOG` privilege on the Unity Catalog metastore to create an Immuta-owned catalog and tables

See the [Databricks documentation](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/privileges.html) for more details about Unity Catalog privileges and securable objects.

#### Prerequisites

* Unity Catalog [metastore created](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html) and attached to a Databricks workspace.
* Unity Catalog enabled on your Databricks cluster or SQL warehouse. All SQL warehouses have Unity Catalog enabled if your workspace is attached to a Unity Catalog metastore. Immuta recommends linking a SQL warehouse to your Immuta tenant rather than a cluster for both performance and availability reasons.

## Register a connection

{% hint style="warning" %}
**Create a separate Immuta catalog for each Immuta tenant**

If multiple Immuta tenants are connected to your Databricks environment, create a separate **Immuta catalog** for each of those tenants. Having multiple Immuta tenants use the same Immuta catalog causes failures in policy enforcement.
{% endhint %}

1. Click <i class="fa-database">:database:</i> **Data** and select the **Connections** tab in the navigation menu.
2. Click the **+ Add Connection** button.
3. Select the **Databricks** data platform tile.
4. Enter the connection information:
   * **Display Name**: The display name represents the unique name of your connection and will be used as prefix in the name for all data objects associated with this connection. It will also appear as the display name in the UI and will be used in all API calls made to update or delete the connection. Avoid the use of periods (`.`) or restricted words in your connection name.
   * **Host**: The hostname of your Databricks workspace.
   * **Port**: Your Databricks port.
   * **HTTP Path**: The HTTP path of your Databricks cluster or SQL warehouse.
   * **Immuta Catalog**: The name of the catalog Immuta will create to store internal entitlements and other user data specific to Immuta. This catalog will only be readable for the Immuta service principal and should not be granted to other users. The catalog name may only contain letters, numbers, and underscores and cannot start with a number.
   * Opt to configure an HTTP proxy for this connection by selecting **Enable** and entering the required details:
     * **Proxy Host**: Enter the full proxy URL.
     * **Proxy Port**: Enter the proxy port.
     * Select if the proxy requires authentication:
       * **Disabled**
       * **Enabled**:
         * **Proxy Username**: Enter the username for the proxy connection.
         * **Proxy Password**: Enter the password for the proxy connection.
5. Select your authentication method from the dropdown menu and enter the authentication information for the [Immuta service principal that you created](#creating-the-databricks-service-principal).

<details>

<summary>Personal Access Token</summary>

Enter the **Token**. This is the access token for the Immuta service principal, which can be [an on-behalf token created in Databricks](https://docs.databricks.com/api/workspace/tokenmanagement/createobotoken). This service principal must have the metastore [privileges listed](#requirements) for the metastore associated with the Databricks workspace. If this token is configured to expire, [update this field regularly](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection/manage-databricks-unity-catalog-connection-settings#edit-the-connection-details) for the connection to continue to function. This authentication information will be included in the script populated to complete the connection setup.

</details>

<details>

<summary>OAuth M2M (Client Secret)</summary>

**AWS Databricks**:

1. Follow [Databricks documentation to create a client secret](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html) for the Immuta service principal and assign this service principal the [privileges listed](#requirements) for the metastore associated with the Databricks workspace.
2. Fill out the **Client ID**. This is a combination of letters, numbers, or symbols, used as a public identifier and is the [client ID displayed in Databricks when creating the client secret for the service principal](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html#step-3-create-an-oauth-secret-for-a-service-principal).
3. Fill out the **Authority URL** with the full URL of the identity provider. This is where the generated token is sent. The default value is `https://<your workspace name>.cloud.databricks.com/oidc/v1/token`.
4. Enter the **Scope** (string). The scope limits the operations and roles allowed in Databricks by the access token. See the [OAuth 2.0 documentation](https://oauth.net/2/scope/) for details about scopes.
5. Enter the **Client Secret**. Immuta uses this secret to authenticate with the authorization server when it requests a token.

**Azure Databricks:**

1. Follow [Databricks documentation](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-m2m) to create a service principal within Azure and then populate to your Databricks account and workspace.
2. Assign this service principal the [privileges listed](#requirements) for the metastore associated with the Databricks workspace.
3. Within Databricks, [create an OAuth client secret for the service principal](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-m2m#step-5-create-an-azure-databricks-oauth-secret-for-the-service-principal). This completes your Databricks-based service principal setup.
4. Fill out the **Client ID**. This is a combination of letters, numbers, or symbols, used as a public identifier and is the [client ID displayed in Databricks when creating the client secret for the service principal](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html#step-3-create-an-oauth-secret-for-a-service-principal) (note that Azure Databricks uses the Azure SP Client ID; it will be identical).
5. Within Immuta, fill out the **Authority URL** with the full URL of the identity provider. This is where the generated token is sent. The default value is `https://<your workspace name>.azuredatabricks.net/oidc/v1/token`.
6. Enter the **Scope** (string). The scope limits the operations and roles allowed in Databricks by the access token. See the [OAuth 2.0 documentation](https://oauth.net/2/scope/) for details about scopes.
7. Enter the **Client Secret** you created above. Immuta uses this secret to authenticate with the authorization server when it requests a token.

</details>

<details>

<summary>OAuth M2M (Certificate)</summary>

1. Fill out the **Client ID**, which is the subject of the generated token. It is also known as `sub` (subject).
2. Fill out the **Authority URL**, which is the authority URL of your identity provider.
3. Fill out the **Scope**, which is the scope of operations and roles allowed by the secret.
4. Enter the **Certificate Thumbprint**. This identifies the corresponding key to the token and is often abbreviated as `x5t` or is called `kid` (key identifier).
5. Opt to fill out the **Resource** field with a URI of the resource where the requested token will be used.
6. Upload the **Private Key**, which is the client certificate that is used to sign the authorization request.

</details>

1. Click **Next**.
2. Configure the **Policy** setting:
   1. Opt to [exclude specific users from policy](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide#policy-exemption-group) by adding them to the **Exclude Group Pattern**. This field cannot be changed after the connection is created.
3. Click **Next**.
4. Configure the Audit settings:
   1. Opt to **Enable Audit**.
   2. If audit is enabled, opt to enter **Workspace IDs** to filter the audit ingest to just specific workspaces.
5. Click **Next**.
6. Opt to **Enable Object Sync**, which will keep your connection objects up to date with your Databricks Unity Catalog environment.
   1. Select the **Start Time** for when the first object sync job will run each day.
   2. Select the **Run Frequency** to determine how frequently object sync will run each day.
   3. Opt to **Run Object Sync on Create** to create all the data objects for your connection. If you do not select this option, you must run object sync manually or wait for the scheduled object sync for your connection's data objects.
7. Click **Save connection**.
8. Copy the provided script and run it in Databricks Unity Catalog as a user with the privileges [listed in the requirements section](#requirements).
9. Click **Validate Connection**.
10. If the connection is successful, click **Finish**. If there are any errors, check the connection details and credentials to ensure they are correct and try again.

## Opt to enable Databricks Unity Catalog tag ingestion

{% hint style="info" %}
**Private preview**: This feature is only available to select accounts. Contact your Immuta representative to enable this feature.
{% endhint %}

**Requirements**:

* A configured Databricks Unity Catalog connection
* Fewer than 10,000 Databricks Unity Catalog data sources registered in Immuta
* The following permissions must be added to your Immuta service principal:
  * `USE CATALOG` on the `system` catalog
  * `USE SCHEMA` on the `system.access` schema
  * `SELECT` on the following system table:
    * `system.access.audit`
  * If ingesting and applying tags to **foreign** **catalogs (created via Lakehouse Federation)**, the following additional permissions are required:
    * `USE SCHEMA` on the `system.information_schema` schema
    * `SELECT` on the following system tables:
      * `system.information_schema.column_tags`
      * `system.information_schema.table_tags`
      * `system.information_schema.tables`
      * `system.information_schema.columns`

To allow Immuta to automatically import table and column tags from Databricks Unity Catalog, enable Databricks Unity Catalog tag ingestion in the external catalog section of the Immuta app settings page.

1. Navigate to the <i class="fa-gear">:gear:</i> **App Settings** page.
2. Scroll to **2 External Catalogs**, and click **Add Catalog**.
3. Enter a **Display Name** and select **Databricks Unity Catalog** from the dropdown menu.
4. Click **Save** and confirm your changes.

## Setting up the required Databricks service principal

If you need instruction for setting up your Databricks service principal **before registering your connection**, see the steps below.

### Creating the Databricks service principal

In Databricks, [create a service principal](https://docs.databricks.com/en/admin/users-groups/service-principals.html#manage-service-principals-in-your-account) with the privileges listed below. Immuta uses this service principal continuously to orchestrate Unity Catalog policies and maintain state between Immuta and Databricks.

* `USE CATALOG` and `MANAGE` on all catalogs containing securables you want registered as Immuta data sources.
* `USE SCHEMA` on all schemas containing securables you want registered as Immuta data sources.
* `MODIFY` and `SELECT` on all securables you want registered as Immuta data sources. *The* `MODIFY` *privilege is not required for materialized views registered as Immuta data sources, since* `MODIFY` *is not a supported privilege on that object type in* [*Databricks*](https://docs.databricks.com/aws/en/data-governance/unity-catalog/manage-privileges/privileges#privilege-types-by-securable-object-in-unity-catalog)*.*
* [Workspace admin permissions](https://docs.databricks.com/aws/en/admin/users-groups/manage-service-principals#assign-the-workspace-admin-role-to-a-service-principal) (If your service principal is a regular user in Databricks and not an actual service principal in Databricks, follow the guidance for [managing users in Databricks documentation](https://docs.databricks.com/aws/en/admin/users-groups/users#assign-the-workspace-admin-role-to-a-user) to grant this user the workspace admin permission.)

{% hint style="info" %}
`MANAGE` and `MODIFY` are required so that the service principal can apply row filters and column masks on the securable; to do so, the service principal must also have `SELECT` on the securable as well as `USE CATALOG` on its parent catalog and `USE SCHEMA` on its parent schema. Since privileges are inherited, you can grant the service principal the `MODIFY` and `SELECT` privilege on all catalogs or schemas containing Immuta data sources, which automatically grants the service principal the `MODIFY` and `SELECT` privilege on all current and future securables in the catalog or schema. The service principal also inherits `MANAGE` from the parent catalog for the purpose of applying row filters and column masks, but that privilege must be set directly on the parent catalog in order for grants to be fully applied.
{% endhint %}

See the [Databricks documentation](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/privileges.html) for more details about Unity Catalog privileges and securable objects.

### Configuring query audit privileges

[Grant the service principal access to the Databricks Unity Catalog system tables](https://docs.databricks.com/en/administration-guide/system-tables/index.html#grant-access-to-system-tables). For Databricks Unity Catalog audit to work, Immuta must have, at minimum, the following access.

* `USE CATALOG` on the `system` catalog
* `USE SCHEMA` on the `system.access` and `system.query` schemas
* `SELECT` on the following system tables:

  * `system.access.table_lineage`
  * `system.access.column_lineage`
  * `system.access.audit`
  * `system.query.history`

  Access to system tables is governed by Unity Catalog. No user has access to these system schemas by default. To grant access, a user that is both a metastore admin and an account admin must grant `USE_SCHEMA` and `SELECT` privileges on the system schemas to the service principal. See [Manage privileges in Unity Catalog](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/index.html).

[^1]: A Databricks user authorized to create a Databricks service principal must create one for Immuta. This service principal is used continuously by Immuta to orchestrate Unity Catalog policies and maintain state between Immuta and Databricks.

[^2]: *The* `MODIFY` *privilege is not required for materialized views registered as Immuta data sources, since* `MODIFY` *is not a supported privilege on that object type in* [*Databricks*](https://docs.databricks.com/aws/en/data-governance/unity-catalog/manage-privileges/privileges#privilege-types-by-securable-object-in-unity-catalog)*.*

[^3]: These privileges are required to enable query audit. See [Manage privileges in Unity Catalog](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/index.html) for details.


# Remove a Databricks Unity Catalog Connection

Delete your Databricks Unity Catalog connection

{% hint style="info" %}
**Cleanup script**

You must run the cleanup script to completely remove Immuta-managed items from your environment. Until you manually run the cleanup script in your Databricks Unity Catalog environment, Immuta-managed groups and Immuta policies will still exist in Databricks Unity Catalog.
{% endhint %}

To delete the host,

1. Click **Data** in the navigation menu and select **Connections**.
2. Click the **overflow menu** in the Actions column and select **Delete Connection**.
3. Download the **cleanup script** from the modal.
4. Click **Delete Connection** again to confirm.
5. Navigate to Databricks Unity Catalog and run the cleanup script in your environment to remove the Immuta-managed groups and policies.


# Manage Databricks Unity Catalog Connection Settings

Manage Databricks Unity Catalog integration and connection settings

## Run object sync <a href="#run-object-sync" id="run-object-sync"></a>

1. Navigate to the connection or connection-backed object.
2. Click **Run Object Sync**.

## Edit the connection details <a href="#edit-the-connection-details" id="edit-the-connection-details"></a>

1. Click the **Edit** button in the Connection details box.
2. Edit the field you want:
   1. **Host**
   2. **Port**
   3. **HTTP Path**
   4. **Immuta System Catalog**
   5. **HTTP Proxy settings**
   6. **Authentication Method**: If you are editing the authentication method to be a different service principal, grant the new service account the [required permissions](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection#requirements).
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the audit settings <a href="#edit-the-audit-settings" id="edit-the-audit-settings"></a>

1. Click the **Edit** button in the Audit settings box.
2. Opt to enable or disable **Query Audit**: If you enable audit, ensure the system account has the [required permissions for audit](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection#requirements).
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the object sync <a href="#edit-the-policy-settings" id="edit-the-policy-settings"></a>

1. Click the **Edit** button in the Object Sync settings box.
2. Use the dropdown to select a new **Start Time** or **Run Frequency**.
3. Select **Save**.

## Edit the data object settings <a href="#edit-the-object-settings" id="edit-the-object-settings"></a>

1. Click the **Edit** button in the Data object settings box.
2. Opt to enable or disable **Policy Sync**: When policy sync is enabled, all child objects will be represented by Immuta data sources and policies will be applied to the data sources.
3. Opt to **Add Users and Groups** as data owners:
   1. Start typing in the text box and select the user or group from the dropdown.
   2. Click **Add Owners**.
4. Click **Save**.


# Migrate to Unity Catalog

Move your data to Unity Catalog and re-register those securables in Immuta so Immuta can administer Unity Catalog access controls

When you enable Unity Catalog, Immuta automatically migrates your existing Databricks data sources in Immuta to reference the legacy `hive_metastore` catalog to account for Unity Catalog's three-level hierarchy. New data sources will reference the Unity Catalog metastore you create and attach to your Databricks workspace.

Because the `hive_metastore` catalog is not managed by Unity Catalog, existing data sources in the `hive_metastore` cannot have Unity Catalog access controls applied to them. Data sources in the Hive Metastore must be managed by the [Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark).

To allow Immuta to administer Unity Catalog access controls on that data, move the data to Unity Catalog and re-register those tables in Immuta by completing the steps below. If you don't move all data before configuring the integration, [metastore magic](/2026.2/configuration/integrations/databricks#metastore-magic) will protect your existing data sources throughout the migration process.

1. Ensure that all Databricks clusters that have Immuta installed are stopped and the Immuta configuration is removed from the cluster. Immuta-specific cluster configuration is no longer needed with the Databricks Unity Catalog integration.
2. Move all data into Unity Catalog before configuring Immuta with Unity Catalog. *Existing data sources will need to be re-created after they are moved to Unity Catalog and the Unity Catalog integration is configured.*
3. [Register a Databricks Unity Catalog connection](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection).


# Databricks Unity Catalog Integration Reference Guide

Learn about how the Databricks Unity Catalog integration works and what Immuta creates in your environment to administer access controls directly on objects in Databricks Unity Catalog

Using the Databricks Unity Catalog connection, you can register a Databricks Unity Catalog integration to register data sources, apply policies to securables, audit user queries, and use other supported Immuta features.

The sequence diagram below outlines the events that occur when an Immuta user wants to query a Databricks Unity Catalog table that has been registered as an Immuta data source.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FPrvbo5q4nK0OYCZZh6vm%2Fimage.png?alt=media&amp;token=3a3fd46e-14a8-47fa-9864-4c6803815501" alt=""><figcaption></figcaption></figure>

Immuta’s integration with Unity Catalog allows you to enforce fine-grained access controls on Unity Catalog securable objects with Immuta policies. Instead of manually creating UDFs or granting access to each table in Databricks, you can author your policies in Immuta and have Immuta manage and orchestrate Unity Catalog access-control policies on your data in Databricks clusters or SQL warehouses.

## What does Immuta do in my Databricks environment?

### Registering a connection

Immuta utilizes [connections](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) to register and manage data from your entire Databricks Unity Catalog environment all at once. This approach simplifies data registration and allows Immuta to automatically monitor your Databricks Unity Catalog platform for changes. Data sources are then added or removed to reflect the current state of your data platform.When a [connection is first registered](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection), Immuta will ask your application admin to provide the following:

* The name of an **Immuta system catalog** in Databricks Unity Catalog that Immuta will control and create schemas in to contain policy definitions and user entitlements.
* A **set of Databricks credentials to a** **service principal** with the [required privileges](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection#requirements) to manage all data protected by Immuta. These credentials will be used to initially register all your [Databricks objects](#supported-object-types) as data objects. Immuta will also continue to use those credentials for scheduled [object syncs](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide#object-sync), [identification](/2026.2/configuration/manage-data-metadata/data-discovery), and to orchestrate policies in Databricks Unity Catalog.

The application admin will then run the setup script in Databricks Unity Catalog, which will create the following:

* The **new Immuta system catalog** to contain the `immuta_system` schema with internal Immuta data and the `immuta_policies_n` schema with the Immuta policy UDFs

After the setup and registration is complete, Immuta ingests and stores connection metadata in the Immuta metadata database. In the example below, the Immuta application administrator connects the database that contains `marketing-data`, `research-data`, and `cs-data` tables. Immuta registers these tables as data objects and stores the view metadata in the Immuta metadata database. Creating the connection does not impact any user's existing access in Databricks Unity Catalog until policy sync is enabled for those tables.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2F7D6SMrY1ZdNyr4qBroPG%2Fimage.png?alt=media&amp;token=7b0c354f-7cf5-4de7-a893-43e80c708c03" alt=""><figcaption></figcaption></figure>

Beyond making the registration of your data more intuitive, connections provide more control. Instead of performing operations on individual schemas or tables, you can perform operations (such as object sync) at the connection level.

See the [Connections reference guide](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) for details about connections and how to manage them. To configure your Databricks Unity Catalog integration and register data, see the [Register a Databricks Unity Catalog connection guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection).

#### Applying policies <a href="#applying-policies" id="applying-policies"></a>

When policies require changes to be pushed to Unity Catalog, Immuta updates the internal tables in the `immuta_system` schema with the updated policy information. If necessary, new UDFs are pushed to replace any out-of-date policies in the `immuta_policies_n` schemas and any row filters or column masks are updated to point at the new policies. Many of these operations require compute on the configured Databricks cluster or SQL warehouse, so compute must be available for these policies to succeed.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FefK3lQwgRcl11SBGGKxB%2Fimage.png?alt=media&amp;token=614e52a1-7336-41a1-86cd-057f75a6b35c" alt=""><figcaption></figcaption></figure>

#### Subscription policies

Immuta enforces read and write [subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents) on Databricks Unity Catalog data sources by granting access to the appropriate securables in Databricks.

Once the connection is registered, this is what happens when a user applies a subscription policy to a Databricks Unity Catalog data source:

1. Immuta determines which users should have access based on the subscription policy.
2. If an appropriate Immuta-managed Databricks group does not already exist, Immuta creates one at the Databricks account level.
3. Immuta grants the required Unity Catalog privileges on the catalog, schema, or table to that Immuta-managed group using the Unity Catalog API.
4. Immuta adds the entitled users to the group.
5. Users who are no longer entitled to access the data source are removed from the group, causing them to lose access to the securable object.

Immuta-managed groups are created at the account level and not assigned to any particular workspace.

#### Group naming convention

When Immuta creates Databricks Unity Catalog groups to enforce access controls, the group naming convention differs slightly based on whether access was granted by an automatic subscription policy or the [group was manually subscribed](#user-content-fn-1)[^1] to the data source.

* **Automatic subscription of a user or Immuta group**: The group name comprises the Immuta external ID, the `connectionKey`, and the policy hash.
  * Naming convention: `IMMUTA_<Immuta external ID>_<connectionKey>_<policy hash>`
  * Example: `IMMUTA_123456789_UnityCatalogConnection_ce86d2f5f86471f66fcd08741d0eb0f4447a6e73a005094c9da07753a8d630f7`
* **Manual subscription of an Immuta group**: The group name comprises the Immuta external ID, the `connectionkey`, and the Immuta group name.
  * Naming convention: `IMMUTA_<Immuta external ID>_<connectionKey>_MANUAL_<group name>`
  * Example: `IMMUTA_123456789_UnityCatalogConnection_MANUAL_Research`

#### Data policies

You can author [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies) in Immuta to enforce fine-grained access controls on Databricks Unity Catalog data sources. For more details abour how enforcement works, see the [Protecting data page](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide/protecting-data).

When a data policy is applied to a Databricks Unity Catalog data source in Immuta,

1. A data owner, data governor, or administrator [creates or changes a policy](/2026.2/governance/author-policies-for-data-access-control), or a [user's attributes change](/2026.2/configuration/people/immuta-users/how-to-guides/managing-attribute-and-group) in Immuta.
2. Immuta generates and applies SQL user-defined functions (UDFs) in Databricks to enforce the configured policy.
   * **Row-level security** is enforced by applying SQL UDFs that filter rows returned to the querying user.
   * **Column-level security** is enforced by applying column-mask SQL UDFs to protected columns.
3. A Databricks user who is subscribed to the data source in Immuta queries the corresponding table directly in Databricks and the SQL UDFs are evaluated during query execution, ensuring that only authorized rows and unmasked column values are returned.

See the integration support matrix on the [Data policies reference guide](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) for a list of supported data policy types for Databricks Unity Catalog.

#### Databricks Unity Catalog privileges granted by Immuta

See the [Subscription policy access types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-databricks-unity-catalog-privileges) for details about the Databricks Unity Catalog privileges granted to users when they are subscribed to a data source protected by a subscription policy.

### Required Databricks Unity Catalog privileges

The privileges the Databricks Unity Catalog integration requires align to the least privilege security principle. The table below describes each privilege required in Databricks Unity Catalog for the [setup user](#user-content-fn-2)[^2] and the [Immuta service principal](#user-content-fn-3)[^3].

| Databricks Unity Catalog privilege                                                                                                                                                                                                                                                                                                                                                                                                                        | User requiring the privilege | Explanation                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Account admin                                                                                                                                                                                                                                                                                                                                                                                                                                             | Setup user                   | This privilege allows the setup user to grant the Immuta service principal the necessary permissions to orchestrate Unity Catalog access controls and maintain state between Immuta and Databricks Unity Catalog.                                                                                                                                                                                                                                                     |
| `CREATE CATALOG` on the Unity Catalog metastore                                                                                                                                                                                                                                                                                                                                                                                                           | Setup user                   | This privilege allows the setup user to create an Immuta-owned catalog and tables.                                                                                                                                                                                                                                                                                                                                                                                    |
| Metastore admin                                                                                                                                                                                                                                                                                                                                                                                                                                           | Setup user                   | This privilege is required only if enabling query audit, which requires granting access to system tables to the Immuta service principal. To grant access, a user that is both a metastore admin and an account admin must grant `USE` and `SELECT` permissions on the system schemas to the service principal. See [Manage privileges in Unity Catalog](https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/index.html) for more details. |
| Workspace admin                                                                                                                                                                                                                                                                                                                                                                                                                                           | Immuta service principal     | This privilege allows Immuta to create and manage Databricks groups to enforce access controls. Immuta-managed groups are created at the account level and not assigned to any particular workspace.                                                                                                                                                                                                                                                                  |
| <ul><li><code>USE CATALOG</code> and <code>MANAGE</code> on all catalogs containing securables registered as Immuta data sources</li><li><code>USE SCHEMA</code> on all schemas containing securables registered as Immuta data sources</li></ul>                                                                                                                                                                                                         | Immuta service principal     | These privileges allow the service principal to ingest catalogs and determine if they have specific workspace-catalog binding behavior defined. These privileges also allow the service principal to apply row filters and column masks on the securable.                                                                                                                                                                                                             |
| `MODIFY` and `SELECT` on all securables registered as Immuta data sources                                                                                                                                                                                                                                                                                                                                                                                 | Immuta service principal     | These privileges allow the service principal to apply row filters and column masks on the securable. Additionally, they are required for [identification](/2026.2/configuration/manage-data-metadata/data-discovery) to run on the securable.                                                                                                                                                                                                                         |
| `OWNER` on the Immuta catalog                                                                                                                                                                                                                                                                                                                                                                                                                             | Immuta service principal     | The Immuta service principal must own the catalog Immuta creates during setup that stores the Immuta policy information. The Immuta setup script grants ownership of this catalog to the Immuta service principal when you configure the integration.                                                                                                                                                                                                                 |
| <ul><li><code>USE CATALOG</code> on the <code>system</code> catalog</li><li><code>USE SCHEMA</code> on the <code>system.access</code> and <code>system.query</code> schemas</li><li><p><code>SELECT</code> on the following system tables:</p><ul><li><code>system.access.table\_lineage</code></li><li><code>system.access.column\_lineage</code></li><li><code>system.access.audit</code></li><li><code>system.query.history</code></li></ul></li></ul> | Immuta service principal     | These privileges allow Immuta to audit user queries in Databricks Unity Catalog.                                                                                                                                                                                                                                                                                                                                                                                      |
| `databricks_pii_access` group                                                                                                                                                                                                                                                                                                                                                                                                                             | Immuta service principal     | This membership allows Immuta to see the query text for Databricks Unity Catalog query audit.                                                                                                                                                                                                                                                                                                                                                                         |
| <ul><li><code>USE CATALOG</code> on the <code>system</code> catalog</li><li><code>USE SCHEMA</code> on the <code>system.access</code> schema</li><li><p><code>SELECT</code> on the following system table:</p><ul><li><code>system.access.audit</code></li></ul></li></ul>                                                                                                                                                                                | Immuta service principal     | These privileges allow Immuta to ingest and apply Databricks Unity Catalog tags to Immuta data sources.                                                                                                                                                                                                                                                                                                                                                               |

### Maintaining state with Databricks Unity Catalog

The following user actions spur various processes in the Databricks Unity Catalog integration so that Immuta data remains synchronous with data in Databricks Unity Catalog:

* **Data source created**: Immuta registers data source metadata and stores that metadata in the Immuta metadata database.
* **Data source deleted**: Immuta deletes the data source metadata from the metadata database and removes subscription policies from that table.
* **User account is mapped to Immuta**: When a user account is mapped to Immuta, their metadata is stored in the metadata database.
* **Subscription policy created, updated, or deleted:** Immuta provisions access in these scenarios by creating and managing Databricks groups and granting or revoking users from those groups.
  * **User subscribed to a data source by an automatic subscription policy**: Immuta creates a group for the affected users (if a group for them does not already exist) and grants Databricks privileges on the data object to that group.
  * **Automatic subscription policy applied to or updated on a data source**: Immuta calculates the users and data sources affected by the policy change and grants or revokes privileges on the Databricks Unity Catalog object by adding or removing users from the Immuta-created group in Databricks.
  * **Subscription policy deleted**: Immuta calculates the users and Databricks groups affected by the policy and revokes privileges on the Databricks Unity Catalog object by removing users from the Immuta-created group in Databricks. If there are no longer any members of an Immuta-created group in Databricks, that group is deleted by Immuta.
* **User manually added to or removed from a data source:** Immuta provisions access in these scenarios by granting or revoking Databricks access to the securable object directly from the user.
  * **User added to a data source by a data owner**: Immuta grants Databricks privileges on the data object directly to that user.
  * **User removed from a data source**: If the user was previously subscribed to the data source through an automatic subscription policy, Immuta removes the user from the Immuta-created group in Databricks. If the user was previously manually added to the data source by a data owner, Immuta revokes the Databricks privileges from the user.

### Supported object types

| Object type                    | Subscription policy support | Data policy support                              |
| ------------------------------ | --------------------------- | ------------------------------------------------ |
| Table                          | :white\_check\_mark:        | :white\_check\_mark:                             |
| View                           | :white\_check\_mark:        | :x:                                              |
| Materialized view              | :white\_check\_mark:        | :white\_check\_mark:                             |
| Metric views                   | :white\_check\_mark:        | :x:                                              |
| Streaming table                | :white\_check\_mark:        | :white\_check\_mark:                             |
| External table                 | :white\_check\_mark:        | :white\_check\_mark:                             |
| Foreign table                  | :white\_check\_mark:        | :white\_check\_mark:                             |
| Volumes (external and managed) | :white\_check\_mark:        | :x:                                              |
| Models                         | :white\_check\_mark:        | :x:                                              |
| Functions                      | :white\_check\_mark:        | :x:                                              |
| Delta Shares                   | :white\_check\_mark:        | [Supported with caveats](#user-content-fn-4)[^4] |

#### Workspace-restricted catalogs

If you have [a binding set to restrict workspace access to certain catalogs in Databricks Unity Catalog](https://docs.databricks.com/aws/en/data-governance/unity-catalog/access-control/workspace-catalog-binding), the ingestion of these catalogs (and their securables) into Immuta may get skipped. Ingestion for catalogs where the workspace associated with the Immuta service principal has read-only access are skipped because Immuta will be blocked from enforcing policies on such catalogs, even if the Immuta service principal were given explicit privilege grants (e.g., `MANAGE`) on the catalog.

See the following table to determine whether Immuta ingests catalogs with each binding:

| Catalog binding                | Ingested into Immuta |
| ------------------------------ | -------------------- |
| Open access with no bindings   | :white\_check\_mark: |
| Read-only isolated access      | :x:                  |
| Read and write isolated access | :white\_check\_mark: |

#### Policy support with `hive_metastore`

When enabling Unity Catalog support in Immuta, the catalog for all Databricks data sources will be updated to point at the default `hive_metastore` catalog. Internally, Databricks exposes this catalog as a proxy to the workspace-level Hive metastore that schemas and tables were kept in before Unity Catalog. Since this catalog is not a real Unity Catalog catalog, it does not support any Unity Catalog policies. Therefore, Immuta will ignore any data sources in the `hive_metastore` in any Databricks Unity Catalog integration, and policies will not be applied to tables there.

However, with [Databricks metastore magic](/2026.2/configuration/integrations/databricks#databricks-metastore-magic-solution) you can use `hive_metastore` and enforce subscription and data policies with the [Databricks Spark integration](/2026.2/configuration/integrations/databricks/databricks-spark/reference-guides/databricks).

## Supported policies

The Unity Catalog integration supports the following policy types:

* [Subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies)
* [Select masking policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies)
  * Conditional masking
  * Constant
  * Custom masking
  * Hashing
  * Null (including on ARRAY, MAP, and STRUCT type columns)
  * Regex: You must use the global regex flag (`g`) when creating a regex masking policy in this integration. You cannot use the case insensitive regex flag (`i`) when creating a regex masking policy in this integration. See the [limitations section](#limitations-and-known-issues) for examples.
  * Rounding (date and numeric rounding)
* [Row-level policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/row-redaction-explained)
  * Matching (only show rows where)
    * Custom WHERE
    * Never
    * Where user
    * Where value in column
  * Minimization
  * Time-based restrictions

## Security and compliance

### Authentication methods

The Databricks Unity Catalog integration supports the following authentication methods to configure the integration and create data sources:

* **Personal access token (PAT)**: This is the access token for the Immuta service principal. This service principal must have the metastore privileges listed in the [requirements](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection#requirements) section for the metastore associated with the Databricks workspace. If this token is configured to expire, update this field regularly for the integration to continue to function.
* **OAuth machine-to-machine (M2M)**: Immuta uses the [Client Credentials Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) to integrate with [Databricks OAuth machine-to-machine authentication](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html), which allows Immuta to authenticate with Databricks using a client secret. Once Databricks verifies the Immuta service principal’s identity using the client secret, Immuta is granted a temporary OAuth token to perform token-based authentication in subsequent requests. When that token expires (after one hour), Immuta requests a new temporary token. See the [Databricks OAuth machine-to-machine (M2M) authentication page](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html) for more details.

#### User registration and ID mapping <a href="#user-registration-and-id-mapping" id="user-registration-and-id-mapping"></a>

The built-in Immuta IAM can be used as a complete solution for authentication and user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and user entitlement instead. Each of the [supported IAM protocols](/2026.2/releases/support-matrix#iam-protocols) includes a set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

For policies to impact the right users, the user account in Immuta must be mapped to the user account in Databricks Unity Catalog. You can ensure these accounts are mapped correctly in the following ways:

* [Automatically](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#configure-external-user-id-mapping-on-app-settings-page): If usernames in Databricks Unity Catalog align with usernames in the external IAM and those accounts align with an IAM attribute, you can enter that IAM attribute on the app settings page to automatically map user IDs in Immuta to Databricks Unity Catalog.
* [Manually](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#manually-configure-external-user-id-mapping-on-a-users-page): You can manually map user IDs for individual users.

For guidance on connecting your IAM to Immuta, see the [how-to guide for your protocol](/2026.2/configuration/people/section-contents).

### Policy exemption group

The Databricks group configured as the policy exemption group in Immuta will be exempt from Immuta data policy enforcement. This account-level group is created and managed in Databricks, not in Immuta. This group does not need to be assigned to a Databricks workspace.

If you have service or system accounts that need to be exempt from masking and row-level policy enforcement, add them to an account-level group in Databricks and include this group name in the Databricks Unity Catalog configuration in Immuta. Then, group members will be excluded from having data policies applied to them when they query Immuta-protected tables in Databricks.

Typically, service or system accounts that perform the following actions are added to an exemption group in Databricks:

* Automated queries
* ETL
* Report generation

If you have multiple groups that must be exempt from data policies, add each group to a single group in Databricks that you then set as the policy exemption group in Immuta.

The service principal used to register data sources in Immuta will be automatically added to the exemption group for the Databricks securables it registers. Consequently, accounts added to the exemption group and used to register data sources in Immuta should be limited to service accounts.

### Tag ingestion

{% hint style="info" %}
**Private preview**: This feature is only available to select accounts. Contact your Immuta representative to enable this feature.
{% endhint %}

You can enable tag ingestion to allow Immuta to ingest Databricks Unity Catalog table and column tags so that you can use them in Immuta policies to enforce access controls. When you enable this feature, Immuta uses the credentials and connection information from the Databricks Unity Catalog integration to pull tags from Databricks and apply them to data sources as they are registered in Immuta. If Databricks data sources preexist the Databricks Unity Catalog tag ingestion enablement, those data sources will automatically sync to the catalog and tags will apply.

Immuta checks for changes to tags in Databricks and syncs Immuta data sources to those changes every hour by default. Immuta's tag ingestion process has a delta logic in order to establish all resources that have had a tag or description change inside Databricks Unity Catalog within a given timeframe to reduce excessive processing time and reduce compute cost.

{% hint style="info" %}
**Access requirements for Databricks Unity Catalog tag ingestion (delta logic)**

Since the delta logic leverages the `system.access.audit` table in Databricks, Immuta must have, at minimum, the following access:

* `USE CATALOG` on the `system` catalog
* `USE SCHEMA` on the `system.access` schema
* `SELECT` on the following system table:
  * `system.access.audit`

Note that without these permissions, Immuta will not be able to process any tag changes post the initial onboarding of data sources.
{% endhint %}

Once external tags are applied to Databricks data sources, those tags can be used to create [subscription](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) and [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies).

To enable Databricks Unity Catalog tag ingestion, see the [Register a Databricks Unity Catalog connection page](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection).

#### Syncing tag changes

After making changes to tags in Databricks, you can [manually sync the catalog](/2026.2/configuration/manage-data-metadata/tags/managing-tags#import-tags-from-an-external-catalog) so that the changes immediately apply to the data sources in Immuta. Otherwise, tag changes will automatically sync within a one hour timeframe. Please note that you may see this timeframe being exceeded in cases where Immuta has to process a lot of tag changes.

When syncing data sources to Databricks Unity Catalog tags, Immuta pulls the following information:

* **Table tags**: These tags apply to the table and appear on the data source details tab. Databricks tags' key and value pairs are reflected in Immuta as a hierarchy with each level separated by a `.` delimiter. For example, the Databricks Unity Catalog tag `Location: US` would be represented as `Location.US` in Immuta.
* **Column tags**: These tags are applied to data source columns and appear on the columns listed for the data source. Databricks tags' key and value pairs are reflected in Immuta as a hierarchy with each level separated by a `.` delimiter. For example, the Databricks Unity Catalog tag `Location: US` would be represented as `Location.US` in Immuta.
* **Table comments field**: This content appears as the data source description on the data source details tab.
* **Column comments field**: This content appears as column descriptions on the columns tab.

#### Limitations

* Only tags that apply to Databricks data sources in Immuta are available to build policies in Immuta. Immuta will not pull tags in from Databricks Unity Catalog unless those tags apply to registered data sources.
* Cost implications: Tag ingestion in Databricks Unity Catalog requires compute resources. Therefore, having many Databricks data sources or frequently manually syncing data sources to Databricks Unity Catalog may incur additional costs.
* Databricks Unity Catalog tag ingestion only supports tenants with fewer than 10,000 data sources registered.

## Limitations and known issues

* Direct group memberships: A principal can be a member of up to 1,500 groups.
* Unity Catalog privileges per object: Databricks limits privileges to 4,000 privileges for parent objects and 1,000 privileges for non-parent objects.
* Groups per account: Databricks has a limit of 250,000 groups for Databricks customers using Account SCIM 2.1. All other Databricks environments are subject to a 5,000 group limit.
* Row access policies with more than 1023 columns are unsupported. This is an underlying limitation of UDFs in Databricks. Immuta will only create row access policies with the minimum number of referenced columns. This limit will therefore apply to the number of columns referenced in the policy and not the total number in the table.
* If you disable table grants, Immuta revokes the grants. Therefore, if users had access to a table before enabling Immuta, they’ll lose access.
* If multiple Immuta tenants are connected to your Databricks environment, you must create a separate Immuta catalog for each of those tenants during configuration. Having multiple Immuta tenants use the same Immuta catalog causes failures in policy enforcement.
* You must use the global regex flag (`g`) when creating a regex masking policy in this integration, and you cannot use the case insensitive regex flag (`i`) when creating a regex masking policy in this integration. See the examples below for guidance:
  * regex with a global flag (supported): `/^ssn|social ?security$/g`
  * regex without a global flag (unsupported): `/^ssn|social ?security$/`
  * regex with a case insensitive flag (unsupported): `/^ssn|social ?security$/gi`
  * regex without a case insensitive flag (supported): `/^ssn|social ?security$/g`

### Azure Databricks Unity Catalog limitation <a href="#azure-databricks-unity-catalog-limitation" id="azure-databricks-unity-catalog-limitation"></a>

If a registered data source is owned by a Databricks group at the table level, then the Unity Catalog integration cannot apply data masking policies to that table in Unity Catalog.Therefore, set all table-level ownership on your Unity Catalog data sources to an individual user or service principal instead of a Databricks group. Catalogs and schemas can still be owned by a Databricks group, as ownership at that level doesn't interfere with the integration.

#### Feature limitations <a href="#feature-limitations" id="feature-limitations"></a>

The following features are currently unsupported:

* Immuta project workspaces
* Multiple IAMs on a single cluster
* Row filters and column masking policies on the following object types:
  * Functions
  * Models
  * Views
  * Volumes
* Mixing masking policies on the same column
* R and Scala cluster support
* Scratch paths
* User impersonation
* Policy enforcement on raw Spark reads
* Python UDFs for advanced masking functions
* Direct file-to-SQL reads
* Data policies (except for masking with NULL) on ARRAY, MAP, or STRUCT type columns
* Shallow clones

[^1]: If a user is manually subscribed to a data source instead of a group, Immuta grants Databricks privileges on the data object directly to that user instead of creating a group.

[^2]: The user configuring the Databricks Unity Catalog integration.

[^3]: This service principal is used by Immuta to manage the Databricks Unity Catalog integration once it has been set up.

[^4]: Immuta supports data policies for shares that contain external, managed, and foreign tables. Data policies are not supported for shares that contain streaming tables or materialized views, which is a Unity Catalog limitation. See the [Databricks documentation](https://docs.databricks.com/aws/en/delta-sharing/create-share) for more details.


# Security and Compliance

Understand the authentication methods and audit features supported by the Databricks Unity Catalog integration to ensure you are meeting your organization's security and compliance needs

## Authentication methods

### Registering the connection

The Databricks Unity Catalog integration supports the following authentication methods to register a connection. The credentials provided must be for an account with the permissions listed in the [Register a Databricks Unity Catalog connection guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection).

* **Personal access token (PAT)**
* **OAuth machine-to-machine (M2M)**

### Identity providers for user authentication

The built-in Immuta IAM can be used as a complete solution for authentication and user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and user entitlement instead.

Each of the supported identity providers includes a specific set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

See the [Identity managers guide](/2026.2/configuration/people/section-contents/reference-guides/identity-managers) for a list of supported providers and details.

See the [Databricks Unity Catalog integration reference guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide#user-registration-and-id-mapping) for details about user provisioning and mapping user accounts to Immuta.

## Auditing and compliance <a href="#auditing-and-compliance" id="auditing-and-compliance"></a>

Immuta provides auditing features and governance reports so that data owners and governors can monitor users' access to data and detect anomalies in behavior.

You can view the information in these audit logs on [dashboards](/2026.2/governance/detect-your-activity/detection/detect-concept).

See the [Audit documentation](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam) for details about these capabilities and how they work with the Databricks Unity Catalog integration.

### Databricks Unity Catalog query audit <a href="#databricks-unity-catalog-query-audit" id="databricks-unity-catalog-query-audit"></a>

Immuta uses Databricks tables from the `system` catalog to understand the queries users make and present them in the query audit logs.

The audit ingest is set when [registering the connection](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/how-to-guides/register-a-databricks-unity-catalog-connection) and can be scoped to only ingest specific workspaces if needed. The default ingest frequency is every 24 hours, but this can be configured to a different frequency on the [Immuta app settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#integration-settings). Additionally, audit ingestion can be manually requested at any time from the Immuta audit page. When manually requested, it will only search for new queries that were created since the last query that had been audited. The job is run in the background, so the new queries will not be immediately available.

See the [Databricks Unity Catalog audit page](/2026.2/governance/detect-your-activity/audit/reference-guides/query-audit-logs/databricks-uc) for details about the contents of the logs and an example of the resulting audit record.

#### Governance reports <a href="#governance-reports" id="governance-reports"></a>

Immuta governance reports allow users with the `GOVERNANCE` Immuta permission to use a natural language builder to instantly create reports that delineate user activity across Immuta. These reports can be based on various entity types, including users, groups, projects, data sources, purposes, policy types, or connection types.

See the [Governance report types](/2026.2/governance/detect-your-activity/audit/reference-guides/reports) page for a list of report types and guidance.


# Protecting Data

Learn how Immuta enforces policies on data in your Databricks Unity Catalog environment

In the Databricks Unity Catalog integration, Immuta administers Databricks Unity Catalog privileges on data registered in Immuta. Then, Immuta users who have been granted access to the data sources can query them.

The sequence diagram below outlines the events that occur when an Immuta user who is subscribed to a data source queries it in Databricks Unity Catalog.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FPrvbo5q4nK0OYCZZh6vm%2Fimage.png?alt=media&amp;token=3a3fd46e-14a8-47fa-9864-4c6803815501" alt=""><figcaption></figcaption></figure>

## Registering a connection

The Databricks Unity Catalog integration is configured and data is registered through [connections](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide), an Immuta feature that allows administrators to register data objects in a technology through a single connection to make data registration more scalable for your organization.

Once the Databricks Unity Catalog connection is registered, you can author subscription and data policies in Immuta to enforce access controls.

See the [Databricks Unity Catalog integration reference guide](/2026.2/configuration/integrations/databricks/databricks-unity-catalog/databricks-unity-catalog-integration-reference-guide) for more details about registering a connection.

## Protecting data

### Subscription policies

When a subscription policy is applied to a data source, users who meet the conditions of the policy will be [automatically subscribed to the data source](#user-content-fn-1)[^1]. Immuta creates and manages Databricks Unity Catalog groups for those users (if an appropriate group does not already exist), grants the required Unity Catalog privileges to the group, and adds the entitled users to that group.

Consider the following example that illustrates how Immuta enforces a subscription policy that only allows users in the `analysts` group to access the `yellow-table`. When this policy is authored and applied to the data source, Immuta creates an Immuta-managed Databricks group (if needed), grants the `SELECT` privilege on `yellow-table` to that group, and adds users who are members of the `analysts` group to it.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FVXdMrmTwuKXEBRg5MXGp%2Fimage.png?alt=media&amp;token=9f9dadfb-e7f5-4067-bcdf-2d0afaead50b" alt=""><figcaption></figcaption></figure>

In the image above, the user in the `analysts` group accesses `yellow-table`, while the user who is a part of the `research` group is denied access.

### User permissions Immuta revokes

**On securable objects**

If you enable a Databricks Unity Catalog object in Immuta, Immuta will only manage users' access to that data object after a subscription policy grants them access to the data source. Immuta preserves all preexisting grants in Databricks and only revokes user access when explicitly dictated by an Immuta policy.

Expand the collapsible blocks below to see how Immuta-managed grants and Databricks-managed grants are affected in various scenarios.

<details>

<summary>Subscription policy applied</summary>

Immuta only manages grants for Immuta users once a subscription policy applies to them. Any grants performed on Databricks objects outside Immuta will not be revoked.

The table below illustrates how the following policy enforces access controls for 4 different users, some of whom have Databricks-managed grants:

> Allow users to subscribe to the data source if they are a member of group `HR`

|                                                                    | Immuta-managed grant | Databricks-managed grant | Access result        |
| ------------------------------------------------------------------ | -------------------- | ------------------------ | -------------------- |
| <p><strong>User A</strong><br>- <code>HR</code> group</p>          | `SELECT`             | None                     | :white\_check\_mark: |
| <p><strong>User B</strong><br>- <code>Engineering</code> group</p> | None                 | `SELECT`                 | :white\_check\_mark: |
| **User C**                                                         | None                 | None                     | :x:                  |
| <p><strong>User D</strong><br>- <code>HR</code> group</p>          | `SELECT`             | `SELECT`                 | :white\_check\_mark: |

In this example,

* **User A is granted access** to the table by **Immuta**.
* **User B is granted access** to the table by **Databricks**.
* **User C cannot access** the table because they do not meet the conditions of the Immuta policy and they have been not granted access to the table in Databricks outside of Immuta.
* **User D is granted access** to the table by **Immuta** and **Databricks**. The Immuta-managed `SELECT` grant coexists with their Databricks-managed `SELECT` grant.

</details>

<details>

<summary>Subscription policy edited</summary>

If a subscription policy is edited, Immuta only affects the Immuta-managed grants on the data object.

The table below illustrates how editing the following policy enforces access controls for 4 different users, some of whom have Databricks-managed grants:

**Previous policy**

> Allow users to subscribe to the data source if they are a member of group `HR`

**Updated policy**

> Allow users to subscribe if they are a member of group `Engineers`

|                                                                    | Immuta-managed grant | Databricks-managed grant | Access result        |
| ------------------------------------------------------------------ | -------------------- | ------------------------ | -------------------- |
| <p><strong>User A</strong><br>- <code>HR</code> group</p>          | Revoked              | None                     | :x:                  |
| <p><strong>User B</strong><br>- <code>Engineering</code> group</p> | `SELECT`             | `SELECT`                 | :white\_check\_mark: |
| **User C**                                                         | None                 | None                     | :x:                  |
| <p><strong>User D</strong><br>- <code>HR</code> group</p>          | Revoked              | Revoked                  | :x:                  |

In this example,

* **User A is revoked access** to the table by **Immuta**. Because this user was previously granted access to the data source by Immuta, that Immuta-managed grant is revoked.
* **User B is granted access** to the table by **Databricks** and **Immuta**. The Immuta-managed `SELECT` grant coexists with their Databricks-managed `SELECT` grant.
* **User C cannot access** the table because they do not meet the conditions of the Immuta policy and they have been not granted access to the table in Databricks outside of Immuta.
* **User D is revoked access** to the table by the change to the Immuta policy. The Immuta-managed `SELECT` grant (from the previous policy) and the pre-existing Databricks-managed `SELECT` grant have been revoked because the Immuta policy explicitly dictated that their access should be removed.

</details>

<details>

<summary>Subscription policy deleted</summary>

If a subscription policy is deleted, users' Immuta grants are revoked for that policy. Users will retain access to the data source if they have Immuta-granted access through another subscription policy that overlaps or if they have a Databricks-managed grant for that data source.

The table below illustrates how **deleting the following Immuta policy** affects access for 4 different users, some of whom have Databricks-managed grants:

> Allow users to subscribe to the data source if they are a member of group `HR`

|                                                                    | Immuta-managed grant | Databricks-managed grant | Access result        |
| ------------------------------------------------------------------ | -------------------- | ------------------------ | -------------------- |
| <p><strong>User A</strong><br>- <code>HR</code> group</p>          | None                 | None                     | :x:                  |
| <p><strong>User B</strong><br>- <code>Engineering</code> group</p> | None                 | `SELECT`                 | :white\_check\_mark: |
| **User C**                                                         | None                 | None                     | :x:                  |
| <p><strong>User D</strong><br>- <code>HR</code> group</p>          | None                 | None                     | :x:                  |

In this example,

* **User A is revoked access** to the table by **Immuta**. Because this user was [previously granted access](#subscription-policy-applied) to the data source by Immuta, that Immuta-managed grant is revoked when the subscription policy is deleted.
* **User B is granted access** to the table by **Databricks**.
* **User C cannot access** the table because they have not been granted access by an Immuta policy and they have been not granted access to the table in Databricks.
* **User D is revoked access** to the table by **Immuta**. Because this user was [previously granted access](#subscription-policy-applied) to the data source by Immuta, Immuta took over managing this user's grants on the table, and that Immuta-managed grant is revoked when the subscription policy is deleted.

</details>

<details>

<summary>Data source disabled</summary>

If a data source is disabled, users' access reverts to what the Databricks-managed access was previously, before the data object was registered in Immuta.

The table below illustrates how **disabling** the data source in Immuta affects access for 4 different users, some of whom have Databricks-managed grants.

|                                                                    | Immuta-managed grant | Databricks-managed grant | Access result        |
| ------------------------------------------------------------------ | -------------------- | ------------------------ | -------------------- |
| <p><strong>User A</strong><br>- <code>HR</code> group</p>          | None                 | None                     | :x:                  |
| <p><strong>User B</strong><br>- <code>Engineering</code> group</p> | None                 | `SELECT`                 | :white\_check\_mark: |
| **User C**                                                         | None                 | None                     | :x:                  |
| <p><strong>User D</strong><br>- <code>HR</code> group</p>          | None                 | `SELECT`                 | :white\_check\_mark: |

In this example,

* **User A is revoked access** to the table by **Immuta**. The Immuta-managed grant is revoked when the data source is disabled because the state of the grants on this data object reverts to what it was before the data object was registered in Immuta.
* **User B is granted access** to the table by **Databricks**. The Databricks-managed grant remains because the state of the grants on this data object reverts to what it was before the data object was registered in Immuta.
* **User C cannot access** the table because they had not been granted access to the table in Databricks.
* **User D is granted access** to the table by **Databricks**. The Immuta-managed grant is revoked and the Databricks grant remains when the data source is disabled because the state of the grants on this data object reverts to what it was before the data object was registered in Immuta.

</details>

If a user is not registered in Immuta, Immuta will have no effect on that user's access to data in Unity Catalog.

**On schemas and catalogs**

By default, Immuta will revoke Immuta users' `USE CATALOG` and `USE SCHEMA` privileges in Unity Catalog for users that do not have access to any of the underlying securables within that catalog/schema. If users have any Immuta-managed or Databricks-managed grants to a securable, Immuta will not revoke that catalog/schema access.

If you disable this setting, Immuta will only revoke the permissions granted on the securable objects themselves, and users' `USE CATALOG` and `USE SCHEMA` permissions will remain even if the user does not have access to any resource in that catalog/schema.

See the [App settings page for instructions](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#databricks-unity-catalog-configuration) on changing this setting.

### Data policies

After Databricks Unity Catalog objects are registered in Immuta, you can author data policies in Immuta to enforce fine-grained access controls.

When a data policy is applied to a Databricks Unity Catalog data source, Immuta enforces that policy natively in Databricks. Depending on the policy type, Immuta applies SQL user-defined functions (UDFs) to enforce row-level security and column masking on registered tables so that queries return policy-enforced results.

As data policies are created, updated, or removed in Immuta, Immuta updates the corresponding SQL UDFs in Databricks to keep enforcement in sync. Users continue querying the Databricks Unity Catalog object directly and see policy-enforced data in Databricks.

See the [Data policies page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial) for guidance on authoring data policies in Immuta and the [supported data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#data-policy-support-matrix) for the Databricks Unity Catalog integration.

[^1]: If the **require manual subscription** option is selected for the policy, these users will have to manually subscribe to the data.


# Accessing Data

Learn how end users can access policy-enforced data in Databricks Unity Catalog

Once data is registered through the Databricks Unity Catalog connection, you will access your data through your Databricks queries as you normally would. If you are subscribed to the data source, Immuta grants you access to the data in Databricks.

When you submit a query, the Databricks Unity Catalog client submits the SQL query to Databricks, which then processes the query and determines what data your group is allowed to see. Then, Databricks queries the database and returns the query results to the Databricks Unity Catalog client, which then returns policy-enforced data to you.

The diagram below illustrates how Immuta, Databricks, and Databricks Untiy Catalog client interact to access data.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FPrvbo5q4nK0OYCZZh6vm%2Fimage.png?alt=media&amp;token=3a3fd46e-14a8-47fa-9864-4c6803815501" alt=""><figcaption></figcaption></figure>

## Querying data

Query Databricks Unity Catalog securables exactly how you normally would in Databricks. Because grants are managed through groups and data policies are managed through UDFs, there is no additional setup required from the data consumers.


# Google BigQuery

The Google BigQuery integration allows users to query policy protected data directly in BigQuery as secure views within an Immuta-created dataset. Immuta controls who can see what within the views, allowing data governors to create complex ABAC policies and data users to query the right data within the BigQuery console.

### Configuration

Google BigQuery is configured through the Immuta console and a script provided by Immuta. While you can complete some steps within the BigQuery console, it is easiest to install using gcloud and the Immuta script.

1. [Create a custom role and assign that role to a custom user to use as the Immuta system account.](#configure-the-google-bigquery-integration)
2. [Enable the integration in the Immuta console.](#enable-the-google-bigquery-integration)

### Protect your data

Once Google BigQuery has been configured, BigQuery admins can start creating subscription and data policies to meet compliance requirements and users can start querying policy protected data directly in BigQuery.

1. Create a global [subscription](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) or [supported data policy](#supported-policies).
2. [Register your BigQuery tables and views in Immuta as data sources.](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/bigquery-tutorial)
3. [Recommended: Organize your data sources into domains and assign domain permissions to accountable teams.](/2026.2/configuration/domains/configure-domains)
4. Revoke user access to the original datasets and grant users access to the Immuta created datasets in BigQuery.
5. Users query data from the Immuta created datasets directly in BigQuery.

### FAQs

1. What permissions will Immuta have in my BigQuery environment?
   * You can find a list of the permissions the custom Immuta role has [here](#configure-the-google-bigquery-integration).
2. What integration features will Immuta support for BigQuery?
   * For private preview, Immuta supports a basic version of the BigQuery integration where Immuta can enforce specific policies on data in a single BigQuery project. At this time, workspaces, tag ingestion, user impersonation, query audit, and multiple integrations are not supported.

## Google BigQuery integration conceptual overview

In this policy push integration, Immuta creates views that contain all policy logic. Each view has a 1-to-1 relationship with the original table. Access controls are applied in the view, allowing organizations to leverage Immuta’s powerful set of attribute-based policies and query data directly in BigQuery.

BigQuery is organized by projects (which can be thought of as databases), datasets (which can be compared to schemas), tables, and views. When you enable the integration, an Immuta dataset is created in BigQuery that contains the Immuta-required user entitlements information. These objects within the Immuta dataset are intended to only be used and altered by the Immuta application.

After data sources are registered, Immuta uses the custom user and role, created before the integration is enabled, to push the Immuta data sources as views into a mirrored dataset of the original table. Immuta manages grants on the created view to ensure only users subscribed to the Immuta data source will see the data.

### Secure views

The Immuta integration uses a mirrored dataset approach. That is, if the source dataset is named `mydataset`, Immuta will create a dataset named `mydataset_secure`, assuming that `_secure` is the specified Immuta dataset suffix. This mirrored dataset is an [authorized dataset](https://cloud.google.com/bigquery/docs/authorized-datasets#console), allowing it to access the data of the original dataset. It will contain the Immuta-managed views, which have identical names to the original tables they’re based on.

### Managing access

Following the principle of least privilege, Immuta does not have permission to manage Google Cloud Platform users, specifically in granting or denying access to a project and its datasets. This means that data governors should limit user access to original datasets to ensure data users are accessing the data through the Immuta created views and not the backing tables. The only users who need to have access to the backing tables are the credentials used to register the tables in Immuta.

Additionally, a data governor must grant users access to the mirrored datasets that Immuta will create and populate with views. Immuta and BigQuery’s best practice recommendation is to grant access via groups in Google Cloud Platform. Because users still must be registered in Immuta and subscribed to an Immuta data source to be able to query Immuta views, all Immuta users can be granted access to the mirrored datasets that Immuta creates.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/e9NlckhWlofUCGDlzICB/bigquery.png" alt=""><figcaption></figcaption></figure>

### Integration health status

The status of the integration is visible on the integrations tab of the Immuta application settings page. If errors occur in the integration, a banner will appear in the Immuta UI with guidance for remediating the error.

The definitions for each status and the state of configured data platform integrations is available in the [response schema of the integrations API](/2026.2/developer-guides/api-intro/integrations-api/reference-guides/response-schema#integration-statuses). However, the UI consolidates these error statuses and provides detail in the error messages.

### Limitations

* This integration can only be enabled through a manual bootstrap using the Immuta API.
* This integration can only be enabled to work in a single region.
* BigQuery does not allow views partitioned by pseudo-columns. If you would like to partition a table by a pseudo-column and have Immuta govern it, take the following steps:
  * Create a view in BigQuery of the partitioned table, with the pseudo-column aliased. For example,

    ```
    create view `sales`.`emea`.`sales_view` as SELECT *, _PARTITIONTIME as __partitiontime from `sales`.`emea`.`sales`
    ```
  * [Register this view as a BigQuery data source](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/bigquery-tutorial#register-data-sources-in-immuta) in Immuta.
  * Immuta will then be able to create Immuta-managed views off of this view with the pseudo-column aliased.

### Supported policies

This integration supports the following policy types:

* Column masking
  * Mask using hashing (SHA256())
  * Mask by making NULL
  * Mask using constant
  * Mask using a regular expression
  * Mask by date rounding
  * Mask by numeric rounding
  * Mask using custom functions
* Row filtering based on user attributes and/or object attributes
* Filter rows using custom WHERE clause

### Additional resources

See the resources below to start implementing and using the BigQuery integration:

* [Configuring the Google BigQuery integration](#configure-the-google-bigquery-integration)
* [Creating BigQuery data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/bigquery-tutorial)
* Building global [subscription](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) and [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) to govern data
* [Creating projects](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/projects-and-purpose-controls/reference-guides/projects) to collaborate

## Configure the Google BigQuery integration

Follow this guide to connect your Google BigQuery data warehouse to Immuta.

### Prerequisites

* Google BigQuery integration (PrPr) enabled.
* Immuta role with SYSTEM\_ADMIN permissions and an [API key](/2026.2/developer-guides/api-intro/immuta-v2-api#authentication).
* [Install the gcloud CLI](https://cloud.google.com/sdk/docs/install).

### Google Cloud service account and role used by Immuta to connect to Google BigQuery

The Google BigQuery integration requires you to create a Google Cloud service account and role that will be used by Immuta to

* create a Google BigQuery dataset that will be used to store a table of user entitlements, UDFs for policy enforcement, etc.
* manage the table of user entitlements via updates when entitlements change in Immuta.
* create datasets and secure views with access control policies enforced, which mirror tables inside of datasets you ingest as Immuta data sources.

You have two options to create the required Google Cloud service account and role:

* [Run the script provided by Immuta](#create-a-service-account-and-role-by-running-the-script-provided-by-immuta)
* [Use the Google Cloud Console](#create-a-service-account-and-role-by-using-google-cloud-console)

#### The Immuta script

The `bootstrap.sh` script is a shell script provided by Immuta that creates prerequisite Google Cloud IAM objects for the integration to connect. When you run this script from your command line, it will create the following items, scoped at the project-level[^1]:

* A new Google Cloud IAM role
* A new Google Cloud service account, which will be granted the newly-created role
* A JSON keyfile for the newly-created service account

You will need to use the objects created in these steps to [enable the Google BigQuery integration](#enable-the-google-bigquery-integration).

**Google Cloud IAM roles required to run the script**

To execute `bootstrap.sh` from your command line, you must be authenticated to the gcloud CLI utility as a user with **all** of the following roles:

* `roles/iam.roleAdmin`
* `roles/iam.serviceAccountAdmin`
* `roles/serviceusage.serviceUsageAdmin`

Having these three roles is the least-privilege set of Google Cloud IAM roles required to successfully run the `bootstrap.sh` script from your command line. However, having **either** of the following Google Cloud IAM roles will also allow you to run the script successfully:

* `roles/editor`
* `roles/owner`

#### Create a service account and role by running the script provided by Immuta

1. Install [gcloud](https://cloud.google.com/sdk/docs/install).
2. Set the account property in the core section for Google Cloud CLI to the account gcloud should use for authentication. (You can run gcloud auth list to see your currently available accounts):

   ```bash
   gcloud config set account ACCOUNT
   ```
3. In Immuta, navigate to the <i class="fa-gear">:gear:</i> **App Settings** page and click the **Integrations** tab.
4. Click **Add Integration** and select **Google BigQuery** from the dropdown menu.
5. Click **Select Authentication Method** and select **Key File**.
6. Click **Download Script(s)**.
7. Before you run the script, update your permissions to execute it:

   ```bash
   chmod 755 <path to downloaded script>
   ```
8. Run the script, where

   * **PROJECT\_ID** is the Google Cloud Platform project to operate on.
   * **ROLE\_ID** is the name of the custom role to create.
   * **NAME** will create a service account with the provided name.
   * **OUTPUT\_FILE** is the path where the resulting private key should be written. File system write permission will be checked on the specified path prior to the key creation.
   * **undelete-role** (optional) will undelete the custom role from the project. Roles that have been deleted for a long time can't be undeleted. This option can fail for the following reasons:
     * The role specified does not exist.
     * The active user does not have permission to access the given role.
   * **enable-api** (optional) provided you’ve been granted access to enable the Google BigQuery API, will enable the service.

   ```bash
   $ bootstrap.sh \
       --project PROJECT_ID \
       --role ROLE_ID \
       --service_account NAME \
       --keyfile OUTPUT_FILE \
       [--undelete-role] \
       [--enable-api]
   ```

#### Create a service account and role by using Google Cloud console

Alternatively, you may use the Google Cloud Console to create the prerequisite role, service account, and private key file for the integration to connect to Google BigQuery.

1. [Create a custom role using the console](https://cloud.google.com/iam/docs/creating-custom-roles#creating_a_custom_role) with the following privileges:
   * `bigquery.datasets.create`
   * `bigquery.datasets.delete`
   * `bigquery.datasets.get`
   * `bigquery.datasets.update`
   * `bigquery.jobs.create`
   * `bigquery.jobs.get`
   * `bigquery.jobs.list`
   * `bigquery.jobs.listAll`
   * `bigquery.routines.create`
   * `bigquery.routines.delete`
   * `bigquery.routines.get`
   * `bigquery.routines.list`
   * `bigquery.routines.update`
   * `bigquery.tables.create`
   * `bigquery.tables.delete`
   * `bigquery.tables.export`
   * `bigquery.tables.get`
   * `bigquery.tables.getData`
   * `bigquery.tables.list`
   * `bigquery.tables.setCategory`
   * `bigquery.tables.update`
   * `bigquery.tables.updateData`
   * `bigquery.tables.updateTag`
2. [Create a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) and grant it the custom role you just created.
3. [Enable the Google BigQuery API](https://cloud.google.com/endpoints/docs/openapi/enable-api#enabling_an_api).

### Enable the Google BigQuery integration

Once the Google Cloud IAM custom role and service account are created, you can enable the Google BigQuery integration. This section illustrates how to enable the integration on the Immuta app settings page. To configure this integration via the Immuta API, see the [Configure a Google BigQuery integration API guide](/2026.2/developer-guides/api-intro/integrations-api/how-to-guides/bigquery-api).

1. In Immuta, navigate to the <i class="fa-gear">:gear:</i> **App Settings** page and click the **Integrations** tab.
2. Click **Add Integration** and select **Google BigQuery** from the dropdown menu.
3. Click **Select Authentication Method** and select **Key File**.
4. Upload your **GCP Service Account Key File**. This is the private key file generated in [create a Google Cloud service account and role for Immuta to use to connect to Google BigQuery](#google-cloud-service-account-and-role-used-by-immuta-to-connect-to-google-bigquery). Uploading this file will auto-populate the following fields:
   * **Project Id**: The Google Cloud Platform project to operate on, where your Google BigQuery data warehouse is located. A new dataset will be provisioned in this Google BigQuery project to store the integration configuration.
   * **Service Account**: The service account you created in [create a Google Cloud service account and role for Immuta to use to connect to Google BigQuery](#google-cloud-service-account-and-role-used-by-immuta-to-connect-to-google-bigquery).
5. Complete the following fields:
   * **Immuta Dataset**: The name of the Google BigQuery dataset to provision inside of the project. Important: if you are using multiple environments in the same Google BigQuery project, this dataset to provision **must** be unique across environments.
   * **Immuta Role**: The custom role you created in [create a Google Cloud service account and role for Immuta to use to connect to Google BigQuery](#google-cloud-service-account-and-role-used-by-immuta-to-connect-to-google-bigquery).
   * **Dataset Suffix**: The suffix that will be postfixed to the name of each dataset created to store secure views, one per dataset that you ingest a table for as a data source in Immuta. Important: if you are using multiple environments in the same Google BigQuery project, this suffix **must** be unique across environments.
   * **GCP Location**: The dataset’s location. After a dataset is created, the location can't be changed. Note that
     * If you choose EU for the dataset location, your Core BigQuery Customer Data resides in the EU.
6. Click **Test Google BigQuery Integration**.
7. Click **Save**.

{% hint style="warning" %}
**GCP location must match dataset region**

The region set for the GCP location must match the region of your datasets. Set GCP location to a general region (for example, `US`) to include child regions.
{% endhint %}

### Disable the Google BigQuery integration

You can disable the Google BigQuery integration automatically or manually.

#### Automatically disable integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon, and then click the **Integrations** tab.
2. Select the Google BigQuery integration you would like to disable, and select the **Disable Integration** checkbox.
3. Click **Save**.

#### Manually disable integration

*The privileges required to run the cleanup script are the same as the Google Cloud IAM roles required to run the `bootstrap.sh` script.*

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon, and then click the **Integrations** tab.
2. Select the Google BigQuery integration you would like to disable, and click **Download Scripts**.
3. Click **Save**. *Wait until Immuta has finished saving your configuration changes before proceeding.*
4. Before you run the script, update your permissions to execute it:

   ```bash
   chmod 755 <path to downloaded script>
   ```
5. Run the cleanup script.

## Next steps

* [Create Google BigQuery data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/bigquery-tutorial)
* Build [global subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) and [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies)
* [Create projects](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/projects-and-purpose-controls/reference-guides/projects) to securely collaborate on analytical workloads

[^1]: As opposed to scoped at the organization-level, to adhere to the principle of least privilege.


# Redshift

Learn about Immuta's integration for Amazon Redshift

In this integration, Immuta generates policy-enforced views in your configured Redshift schema for tables registered as Immuta data sources.

## [Getting started](/2026.2/configuration/integrations/redshift/redshift)

This guide outlines how to integrate Redshift with Immuta.

## How-to guides

* [Redshift integration configuration](/2026.2/configuration/integrations/redshift/how-to-guides/redshift): Configure the integration in Immuta.
* [Redshift Spectrum configuration](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum): Configure Redshift Spectrum in Immuta.

## Reference guides

* [Redshift integration reference guide](/2026.2/configuration/integrations/redshift/reference-guides/redshift): This guide describes the design and components of the integration.
* [Redshift pre-configuration details](/2026.2/configuration/integrations/redshift/reference-guides/pre-configuration): This guide describes the prerequisites, supported features, and limitations of the integration.


# Getting Started with Redshift

The how-to guides linked on this page illustrate how to integrate Redshift with Immuta. See the [reference guide](/2026.2/configuration/integrations/redshift/reference-guides/redshift) for information about the Redshift integration.

**Requirement**: Redshift cluster with an RA3 node is required for the multi-database integration. For other instance types, you may configure a single-database integration using one of the [Redshift Spectrum options](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum).

{% stepper %}
{% step %}
**Connect your technology**

These guides provide instructions on getting your data set up in Immuta.

1. [Configure your Redshift integration](/2026.2/configuration/integrations/redshift/how-to-guides/redshift): Configure a Redshift integration with Immuta so that Immuta can create policy protected views for your users to query.
2. [Register Redshift data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/redshift-tutorial): This will register your data objects into Immuta and allow you to start dictating access through global policies.
3. [Organize your data sources into domains and assign domain permissions to accountable team](/2026.2/configuration/domains/configure-domains)s: Use domains to segment your data and assign responsibilities to the appropriate team members. These domains will then be used in policies and identification.
   {% endstep %}

{% step %}
**Register your users**

These guides provide instructions on getting your users set up in Immuta.

1. [Connect an IAM](/2026.2/configuration/people/getting-started): Bring the IAM your organization already uses and allow Immuta to register your users for you.
2. [Map external user IDs from Redshift to Immuta](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping): Ensure the user IDs in Immuta, Redshift, and your IAM are aligned so that the right policies impact the right users.
   {% endstep %}

{% step %}
**Add data metadata**

These guides provide instructions on getting your data metadata set up in Immuta.

1. [Connect an external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure): Bring the external catalog your organization already uses and allow Immuta to continually sync your tags with your data sources for you.
2. [Run identification](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/enable-sdd): Identification allows you to automate data tagging using identifiers that detect certain data patterns.
   {% endstep %}

{% step %}
**Start using policies**

These guides provide instructions on using policies and audit for the first time.

1. [Author a global subscription policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial): Once you add your data metadata to Immuta, you can immediately create policies that utilize your tags and apply to your tables. Subscription policies can be created to dictate access to data sources.
2. [Author a global data policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial): Data metadata can also be used to create data policies that apply to data sources as they are registered in Immuta. Data policies dictate what data a user can see once they are granted access to a data source. Using catalog and identification applied tags you can create proactive policies, knowing that they will apply to data sources as they are added to Immuta with the automated tagging.
3. [Configure audit](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam): Once you have your data sources and users, and policies granting them access, you can set up audit export. This will export the audit logs from policy changes and tagging updates.
   {% endstep %}
   {% endstepper %}


# How-to Guides


# Configure Redshift Integration

This page illustrates how to configure the [Redshift integration](/2026.2/configuration/integrations/redshift/reference-guides/redshift) on the Immuta app settings page. To configure this integration via the Immuta API, see the [Integrations API getting started guide](/2026.2/developer-guides/api-intro/integrations-api/getting-started).

For instructions on configuring Redshift Spectrum, see the [Redshift Spectrum](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum) guide.

## Requirements

* A Redshift cluster with an RA3 node is required for the multi-database integration. You must use a Redshift RA3 instance type because Immuta requires cross-database views, which are only supported in Redshift RA3 instance types. For other instance types, you may configure a single-database integration using one of the [Redshift Spectrum options](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum).
* For automated installations, the credentials provided must be a Superuser or have the ability to create databases and users and modify grants.
* The [`enable_case_sensitive_identifier` parameter](https://docs.aws.amazon.com/redshift/latest/dg/r_enable_case_sensitive_identifier.html) must be set to `false` (default setting) for your Redshift cluster.

## Add a Redshift integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Click the **Integrations** tab.
3. Click the **+Add Integration** button and select **Redshift** from the dropdown menu.
4. Complete the **Host** and **Port** fields.
5. Enter an **Immuta Database**. This is a new database where all secure schemas and Immuta created views will be stored.
6. Opt to check the **Enable Impersonation** box and customize the **Impersonation Role** name as needed. This will allow users to natively impersonate another user. Once you finish configuring the integration, you can grant the `IMPERSONATE_USER` permission to Immuta users. See the [Managing users and permissions guide](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#add-permission-to-user) for instructions.

### Select your configuration method

You have two options for configuring your Redshift environment:

* [Automatic setup](#automatic-setup): Grant Immuta one-time use of credentials to automatically configure your Redshift environment and the integration.
* [Manual setup](#manual-setup): Run the Immuta script in your Redshift environment yourself to configure your environment and the integration.

#### Automatic setup

{% hint style="info" %}
**Immuta requires temporary, one-time use of credentials with specific privileges**

When performing an automated installation, Immuta requires temporary, one-time use of credentials with the following privileges:

* `CREATE DATABASE`
* `CREATE USER`
* `REVOKE ALL PRIVILEGES ON DATABASE`
* `GRANT TEMP ON DATABASE`
* `MANAGE GRANTS ON ACCOUNT`

These privileges will be used to create and configure a new IMMUTA database within the specified Redshift instance. The credentials are not stored or saved by Immuta, and Immuta doesn’t retain access to them after initial setup is complete.

You can create a new account for Immuta to use that has these privileges, or you can grant temporary use of a pre-existing account. By default, the pre-existing account with appropriate privileges is a Superuser. If you create a new account, it can be deleted after initial setup is complete.

Alternatively, you can create the IMMUTA database within the specified Redshift instance without giving Immuta user credentials for a Superuser using the manual setup option.
{% endhint %}

1. Select **Automatic**.
2. Enter an **Initial Database** from your Redshift integration for Immuta to use to connect.
3. Use the dropdown menu to select your **Authentication Method**.
   1. **Username and Password**: Enter the **Username** and **Password** of the privileged user.
   2. **AWS Access Key**: Enter the **Database User**, **Access Key ID**, and **Secret Key**. Opt to enter in the **Session Token**.

#### Manual setup

{% hint style="info" %}
**Required privileges**

The specified role used to run the bootstrap needs to have the following privileges:

* `CREATE DATABASE`
* `CREATE USER`
* `REVOKE ALL PRIVILEGES ON DATABASE`
* `GRANT TEMP ON DATABASE`
* `MANAGE GRANTS ON ACCOUNT`
  {% endhint %}

1. Select **Manual** and download both of the bootstrap scripts from the **Setup** section.
2. Run the **bootstrap script (initial database)** in the Redshift initial database.
3. Run the **bootstrap script (Immuta database)** in the new **Immuta Database** in Redshift.
4. Choose your **authentication method**, and enter the information of the newly created account.

### Save the configuration

Click **Save**.

### Register data

[Register Redshift data in Immuta](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/redshift-tutorial).

## Edit a Redshift integration

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Navigate to the Integrations tab and click the **down arrow** next to the Redshift Integration.
3. Edit the field you want to change. *Note any field shadowed is not editable, and the integration must be disabled and re-installed to change it.*
4. Enter **Username** and **Password**.
5. Click **Save**.

{% hint style="info" %}
**Required privileges**

When performing edits to an integration, Immuta requires temporary, one-time use of credentials of a Superuser or a user with the following permissions:

* Create Databases
* Create users
* Modify grants

Alternatively, you can download the **Edit Script** from your Redshift configuration on the Immuta app settings page and run it in Redshift.
{% endhint %}

## Remove a Redshift integration

{% hint style="warning" %}
**Disabling Redshift Spectrum**

Disabling the Redshift integration is not supported when you set the fields `nativeWorkspaceName`, `nativeViewName`, and `nativeSchemaName` to [create Redshift Spectrum data sources.](/2026.2/developer-guides/api-intro/immuta-v2-api/data-source) Disabling the integration when these fields are used in metadata ingestion causes undefined behavior.
{% endhint %}

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Navigate to the Integrations tab and click the **down arrow** next to the Redshift Integration.
3. Click the **checkbox** to disable the integration.
4. Enter the username and password that were used to initially configure the integration.
5. Click **Save**.


# Configure Redshift Spectrum

Allow Immuta to create secure views of your external tables through one of these methods:

* [Configure the integration with an existing database](#use-an-existing-database) that contains the external tables: Instead of creating an `immuta` database that manages all schemas and views created when Redshift data is registered in Immuta, the integration adds the Immuta-managed schemas and views to an existing database in Redshift
* [Configure the integration by creating a new `immuta` database](#create-a-new-immuta-database) and re-create all of your external tables in that database.

For an overview of the integration, see the [Redshift overview](/2026.2/configuration/integrations/redshift/reference-guides/redshift#redshift-spectrum) documentation.

## Requirements

* A Redshift cluster with an AWS row-level security patch applied. [Contact Immuta](https://support.immuta.com/) for guidance.
* [An AWS IAM role for Redshift](https://docs.aws.amazon.com/redshift/latest/dg/c-getting-started-using-spectrum-create-role.html) that is [associated with your Redshift cluster](https://docs.aws.amazon.com/redshift/latest/dg/c-getting-started-using-spectrum-add-role.html).
* The [`enable_case_sensitive_identifier` parameter](https://docs.aws.amazon.com/redshift/latest/dg/r_enable_case_sensitive_identifier.html) must be set to `false` (default setting) for your Redshift cluster.
* The Redshift role used to run the Immuta bootstrap script must have the following privileges when configuring the integration to
  * Use an existing database:
    * `ALL PRIVILEGES ON DATABASE` for the database you configure the integration with, as you must manage grants on that database.
    * `CREATE USER`
    * `GRANT TEMP ON DATABASE`
  * Create a new database:
    * `CREATE DATABASE`
    * `CREATE USER`
    * `GRANT TEMP ON DATABASE`
    * `REVOKE ALL PRIVILEGES ON DATABASE`
* [A Redshift database that contains an external schema and external tables](https://docs.aws.amazon.com/redshift/latest/dg/c-getting-started-using-spectrum-create-external-table.html).

## Use an existing database

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Click the **Integrations** tab.
3. Click the **+Add Integration** button and select **Redshift** from the dropdown menu.
4. Complete the **Host** and **Port** fields.
5. Enter the name of the database you created the external schema in as the **Immuta Database**. This database will store all secure schemas and Immuta-created views.
6. Opt to check the **Enable Impersonation** box and customize the **Impersonation Role** name as needed. This will allow users to natively impersonate another user. Once you finish configuring the integration, you can grant the `IMPERSONATE_USER` permission to Immuta users. See the [Managing users and permissions guide](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#add-permission-to-user) for instructions.
7. Select **Manual** and download both of the bootstrap scripts from the **Setup** section. The specified role used to run the bootstrap needs to have the following privileges:
   * `ALL PRIVILEGES ON DATABASE` for the database you configure the integration with, as you must manage grants on that database.
   * `CREATE USER`
   * `GRANT TEMP ON DATABASE`
8. Run the **bootstrap script (Immuta database)** in the Redshift database that contains the external schema.
9. Choose your **authentication method**, and enter the credentials from the bootstrap script for the `Immuta_System_Account`.
10. Click **Save**.

### Register data

[Register Redshift data in Immuta](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/redshift-tutorial).

## Create a new Immuta database

1. Click the <i class="fa-gear">:gear:</i> **App Settings** icon in the navigation menu.
2. Click the **Integrations** tab.
3. Click the **+Add Integration** button and select **Redshift** from the dropdown menu.
4. Complete the **Host** and **Port** fields.
5. Enter an **Immuta Database**. This is a new database where all secure schemas and Immuta created views will be stored.
6. Opt to check the **Enable Impersonation** box and customize the **Impersonation Role** name as needed. This will allow users to natively impersonate another user. Once you finish configuring the integration, you can grant the `IMPERSONATE_USER` permission to Immuta users. See the [Managing users and permissions guide](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#add-permission-to-user) for instructions.
7. Select **Manual** and download both of the bootstrap scripts from the **Setup** section. The specified role used to run the bootstrap needs to have the following privileges:
   * `ALL PRIVILEGES ON DATABASE` for the database you configure the integration with, as you must manage grants on that database.
   * `CREATE DATABASE`
   * `CREATE USER`
   * `GRANT TEMP ON DATABASE`
8. Run the **bootstrap script (initial database)** in the Redshift initial database.
9. Run the **bootstrap script (Immuta database)** in the new **Immuta Database** in Redshift.
10. Choose your **authentication method**, and enter the credentials from the bootstrap script for the `Immuta_System_Account`.
11. Click **Save**.

Then, add your external tables to the Immuta database.

### Register data

[Register Redshift data in Immuta](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/redshift-tutorial).


# Reference Guides


# Redshift Integration

This page provides an overview of the Redshift integration in Immuta. For a tutorial detailing how to enable this integration, see the [installation guide](/2026.2/configuration/integrations/redshift/how-to-guides/redshift).

## Overview

Redshift is a policy push integration that allows Immuta to apply policies directly in Redshift. This allows data analysts to query Redshift views directly instead of going through a proxy and have per-user policies dynamically applied at query time.

## Architecture

The Redshift integration will create views from the tables within the database specified when configured. Then, the user can choose the name for the schema where all the Immuta generated views will reside. Immuta will also create the schemas `immuta_system`, `immuta_functions`, and `immuta_procedures` to contain the tables, views, UDFs, and stored procedures that support the integration. Immuta then creates a system role and gives that system account the following privileges:

* `ALL PRIVILEGES ON DATABASE IMMUTA_DB`
* `ALL PRIVILEGES ON ALL SCHEMAS IN DATABASE IMMUTA_DB`
* `USAGE ON FUTURE PROCEDURES IN SCHEMA IMMUTA_DB.IMMUTA_PROCEDURES`
* `USAGE ON LANGUAGE PLPYTHONU`

Additionally the `PUBLIC` role will be granted the following privileges:

* `USAGE ON DATABASE IMMUTA_DB`
* `TEMP ON DATABASE IMMUTA_DB`
* `USAGE ON SCHEMA IMMUTA_DB.IMMUTA_PROCEDURES`
* `USAGE ON SCHEMA IMMUTA_DB.IMMUTA_FUNCTIONS`
* `USAGE ON FUTURE FUNCTIONS IN SCHEMA IMMUTA_DB.IMMUTA_FUNCTIONS`
* `USAGE ON SCHEMA IMMUTA_DB.IMMUTA_SYSTEM`
* `SELECT ON TABLES TO public`

### Integration type

Immuta supports the Redshift integration as both multi-database and single-database integrations. In either integration type, Immuta supports a single integration with secure views in a single database per cluster.

#### Multi-database integration

If using a multi-database integration, you must use a Redshift cluster with an RA3 node because Immuta requires cross-database views.

#### Single-database integration

If using a single-database integration, all Redshift cluster types are supported. However, because cross-database queries are not supported in any types other than RA3, Immuta's views must exist in the same database as the raw tables. Consequently, the steps for configuring the integration for Redshift clusters with external tables differ slightly from those that don't have external tables. Allow Immuta to create secure views of your external tables through one of these methods:

* [configure the integration with an existing database that contains the external tables](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum#use-an-existing-database): Instead of creating an `immuta` database that manages all schemas and views created when Redshift data is registered in Immuta, the integration adds the Immuta-managed schemas and views to an existing database in Redshift.
* [configure the integration by creating a new `immuta` database](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum#create-a-new-immuta-database) and re-create all of your external tables in that database.

## Policy enforcement

SQL statements are used to create all views, including a join to the secure view: `immuta_system.user_profile`. This secure view is a select from the `immuta_system.profile` table (which contains all Immuta users and their current groups, attributes, projects, and a list of valid tables they have access to) with a constraint `immuta__userid = current_user()` to ensure it only contains the profile row for the current user. The `immuta_system.user_profile` view is readable by all users, but will only display the data that corresponds to the user executing the query.

The Redshift integration uses webhooks to keep views up-to-date with Immuta data sources. When a data source or policy is created, updated, or disabled, a webhook will be called that will create, modify, or delete the dynamic view. The `immuta_system.profile` table is updated through webhooks when a user's groups or attributes change, they switch projects, they acknowledge a purpose, or when their data source access is approved or revoked. The profile table can only be read and updated by the Immuta system account.

## Integration health status

The status of the integration is visible on the integrations tab of the Immuta application settings page. If errors occur in the integration, a banner will appear in the Immuta UI with guidance for remediating the error.

The definitions for each status and the state of configured data platform integrations is available in the [response schema of the integrations API](/2026.2/developer-guides/api-intro/integrations-api/reference-guides/response-schema#integration-statuses). However, the UI consolidates these error statuses and provides detail in the error messages.

## Data flow

1. An Immuta Application Administrator [configures the Redshift integration](/2026.2/configuration/integrations/redshift/how-to-guides/redshift) and registers Redshift warehouse and databases with Immuta.
2. Immuta creates a database inside the configured Redshift ecosystem that contains Immuta policy definitions and user entitlements.
3. A Data Owner registers Redshift tables in Immuta as [data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/register-data-sources/redshift-tutorial).
4. A Data Owner, Data Governor, or Administrator [creates or changes a policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure) or user in Immuta.
5. Data source metadata, tags, user metadata, and policy definitions are stored in Immuta's Metadata Database.
6. The Immuta Web Service calls a stored procedure that modifies the user entitlements or policies.
7. A Redshift user who is subscribed to the data source in Immuta [queries the corresponding table](/2026.2/governance/data-consumers/query-data/redshift) directly in Redshift through the immuta database and sees policy-enforced data.

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/EFDYzoComWxrbqCmBZy6/redshift-integration.png" alt=""><figcaption></figcaption></figure>

## Redshift Spectrum

Redshift Spectrum ([Redshift external tables](https://docs.aws.amazon.com/redshift/latest/dg/c-using-spectrum.html)) allows Redshift users to query external data directly from files on Amazon S3. Because cross-database queries are not supported in Redshift Spectrum, Immuta's views must exist in the same database as the raw tables. Consequently, the steps for configuring the integration for Redshift clusters with external tables differ slightly from those that don't have external tables. Allow Immuta to create secure views of your external tables through one of these methods:

* [configure the integration with an existing database that contains the external tables](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum#use-an-existing-database): Instead of creating an `immuta` database that manages all schemas and views created when Redshift data is registered in Immuta, the integration adds the Immuta-managed schemas and views to an existing database in Redshift
* [configure the integration by creating a new `immuta` database](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum#create-a-new-immuta-database) and re-create all of your external tables in that database.

Once the integration is configured, Data Owners must [register Redshift Spectrum data sources using the Immuta CLI or V2 API](/2026.2/developer-guides/api-intro/immuta-v2-api/data-source).


# Redshift Pre-Configuration Details

This page describes the Redshift integration, configuration options, and features. For a tutorial to enable this integration, see the [installation guide](/2026.2/configuration/integrations/redshift/how-to-guides/redshift).

## Feature Availability

| Project Workspaces | Tag Ingestion | User Impersonation   | Query Audit | Multiple Integrations |
| ------------------ | ------------- | -------------------- | ----------- | --------------------- |
| :x:                | :x:           | :white\_check\_mark: | :x:         | :white\_check\_mark:  |

## Prerequisite

For automated installations, the credentials provided must be a Superuser or have the ability to create databases and users and modify grants.

## Supported Features

* Redshift datashares
* Redshift Serverless
* [Redshift Spectrum](https://docs.aws.amazon.com/redshift/latest/dg/c-getting-started-using-spectrum.html) For configuration and data source registration instructions, see the [configuration page](/2026.2/configuration/integrations/redshift/how-to-guides/redshift-spectrum).

## Authentication Methods

The Redshift integration supports the following authentication methods to configure the integration and create data sources:

* **Username and Password**: Users can authenticate with their Redshift username and password.
* **AWS Access Key**: Users can authenticate with an [AWS access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html).

## Tag Ingestion

Immuta cannot ingest tags from Redshift, but you can connect any of these [supported external catalogs](/2026.2/configuration/manage-data-metadata/catalogs/reference-guides/pre-configuration) to work with your integration.

## User Impersonation

{% hint style="info" %}
**Required Redshift privileges**

**Setup User**:

* `OWNERSHIP ON GROUP IMMUTA_IMPERSONATOR_ROLE`
* `CREATE GROUP`

**Immuta System Account**:

* `GRANT EXECUTE ON PROCEDURE grant_impersonation`
* `GRANT EXECUTE ON PROCEDURE revoke_impersonation`
  {% endhint %}

Impersonation allows users to query data as another Immuta user in Redshift. To enable user impersonation, see the [Configure Redshift guide](/2026.2/configuration/integrations/redshift/how-to-guides/redshift).

## Multiple Integrations

Users can enable multiple [Redshift integrations](/2026.2/configuration/integrations/redshift/how-to-guides/redshift) with a single Immuta tenant.

## Redshift Limitations

* The host of the data source must match the host of the connection for the view to be created.
* When using multiple Redshift integrations, a user has to have the same user account across all hosts.
* Case sensitivity of database, table, and column identifiers is not supported. The [<mark style="color:blue;">`enable_case_sensitive_identifier`</mark> <mark style="color:blue;">parameter</mark>](https://docs.aws.amazon.com/redshift/latest/dg/r_enable_case_sensitive_identifier.html) must be set to `false` (default setting) for your Redshift cluster to configure the integration and register data sources.

### Python UDF Specific Limitations

For most policy types in Redshift, Immuta uses SQL clauses to implement enforcement logic; however Immuta uses Python UDFs in the Redshift integration to implement the following masking policies:

* Masking using a regular expression
* Reversible masking
* Format-preserving masking
* Randomized response

The number of Python UDFs that can run concurrently per Redshift cluster is limited to one-fourth of the total concurrency level for the cluster. For example, if the Redshift cluster is configured with a concurrency of 15, a maximum of three Python UDFs can run concurrently. After the limit is reached, Python UDFs are queued for execution within workload management queues.

The `SVL_QUERY_QUEUE_INFO` view in Redshift, which is visible to a Redshift superuser, summarizes details for queries that spent time in a workload management (WLM) query queue. Queries must be completed in order to appear as results in the `SVL_QUERY_QUEUE_INFO` view.

If you find that queries on Immuta-built views are spending time in the workload management (WLM) query queue, you should either edit your Redshift cluster configuration to increase concurrency, or use fewer of the masking policies which leverage Python UDFs. For more information on increasing concurrency, see the Redshift docs on implementing [workload management](https://docs.aws.amazon.com/redshift/latest/dg/cm-c-implementing-workload-management.html).


# Snowflake

Learn about how you can register data from Snowflake and govern access to that data

This page describes the recommended workflow for setting up Immuta with [Snowflake](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide). Following these steps connects your Snowflake environment, registers users, ingests metadata, and enables automated governance through global policies and access requests.

## Before you begin

To complete this workflow, ensure you have:

* Access to a Snowflake account and the permissions required to configure the connection
* An Immuta application administrator who can register the connection

For the recommended implementation described on this page, you should also have:

* An enterprise identity provider
* Identified owners or stewards for your major data domains
* An understanding of the metadata maintained in your external catalog, if you use one

{% hint style="info" icon="lightbulb" %}
Completing this workflow typically requires coordination among an Immuta application administrator, a Snowflake administrator, an identity administrator, governance users, and data stewards.
{% endhint %}

{% stepper %}
{% step %}

## Connect your Snowflake environment

1. An application administrator will [register the Snowflake connection](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection) to allow Immuta to discover databases, schemas, and tables in Snowflake. As object sync runs, Immuta creates corresponding data sources that can be governed through policies.
2. After registering the connection, [organize your data into domains](/2026.2/configuration/domains). Domains assign ownership of data to the appropriate teams and determine who can manage policies, identification, and audit for those data sources.

Once your [data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/data-source-overview) are registered in Immuta and organized into domains, you can apply policy to them.

{% hint style="info" icon="lightbulb" %}
Start by registering a select Snowflake business domain by [restricting the permissions of the Snowflake system account](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account). Once your implementation is established, you can onboard additional data sources using the same governance model.
{% endhint %}
{% endstep %}

{% step %}

## Register and map your users

1. [Connect your organization's identity provider](/2026.2/configuration/people/section-contents) and configure SSO so that users can authenticate with their existing credentials and be automatically registered in Immuta.
   1. If your identity provider supports SCIM, [enable provisioning to synchronize users, groups, and attributes](/2026.2/configuration/people/section-contents/reference-guides/scim-protocol). These attributes can then be used when authoring policies so access automatically changes as the user information in the IAM is synced with Immuta.
2. After your identity provider is configured, [map Snowflake user identities to Immuta users](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping). This ensures that policies written in Immuta are enforced for the correct users when they query data in Snowflake.

Once your users are registered and mapped to their Snowflake identities, any policies that apply to data sources will be enforced for those users.

{% hint style="info" icon="lightbulb" %}
If your identity provider supports SCIM, synchronize the user attributes that you plan to reference in policies, such as `department`, `region`, or `employment type`. These attributes provide a strong foundation for reusable global policies.
{% endhint %}
{% endstep %}

{% step %}

## Add metadata to your data

Metadata allows you to author policies that automatically apply across your Snowflake environment instead of managing individual tables and columns.

1. If your organization already maintains metadata in an external catalog, [connect your external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure) so Immuta continuously synchronizes tags, classifications, and descriptions.
2. You can also [enable identification to automatically discover and tag sensitive data](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/enable-sdd). Identification is recommended for all deployments and is especially useful if you do not maintain an external catalog.

Once your data sources are tagged in Immuta, you can author global policies based on those tags. These policies can apply automatically as additional data sources are registered through object sync and tagged.
{% endstep %}

{% step %}

## Configure automated policies

Once users and metadata are available, begin authoring global policies that automatically protect your data.

1. [Create subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial) to automatically grant access to users who meet the required conditions. You can also use subscription policies to enforce organization-wide requirements, such as limiting access to users with specific attributes or training before access can be granted.
2. [Create data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial) to mask sensitive columns or filter rows based on metadata such as catalog or identification tags.

Author global policies using metadata and user attributes instead of individual Snowflake objects or users. This allows the same policies to automatically apply as new data is registered and users are synchronized into Immuta.

{% hint style="info" icon="lightbulb" %}
A common first policy is to mask sensitive data identified through identification or your external catalog. As new Snowflake tables are registered and tagged, the policy automatically protects those columns without additional configuration.
{% endhint %}
{% endstep %}

{% step %}

## Configure audit

After your data, users, and policies are configured, [configure audit to export governance activity](/2026.2/configuration/self-managed-deployment/configure/audit-best-practices).

Audit records provide visibility into user queries, policy evaluations, access requests, policy changes, and metadata updates, allowing your organization to monitor how data is accessed and governed across your Snowflake environment.
{% endstep %}
{% endstepper %}

## Next steps

**After completing this workflow, your Snowflake environment is ready for automated governance.** From here you can continue configuring advanced features, refining policies, and onboarding additional Snowflake data sources. See the [Snowflake integration reference guide](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide) for architecture details, platform behavior, and additional configuration options.


# How-to Guides


# Register a Snowflake Connection

Register your Snowflake data

### **Requirements**

* `APPLICATION_ADMIN` Immuta permission
* The Snowflake user registering the connection and running the script must have the following privileges:
  * `CREATE DATABASE ON ACCOUNT WITH GRANT OPTION`
  * `CREATE ROLE ON ACCOUNT WITH GRANT OPTION`
  * `MANAGE GRANTS ON ACCOUNT WITH GRANT OPTION`

## Set up the Immuta system account

Complete the following actions in Snowflake:

1. [Create a new user in Snowflake to be the Immuta system account](https://docs.snowflake.com/en/sql-reference/sql/create-user). Immuta will use this system account continuously to orchestrate Snowflake policies and maintain state between Immuta and Snowflake.
2. [Create a Snowflake role](https://docs.snowflake.com/en/sql-reference/sql/create-role) with a minimum of the following privileges:
   * `USAGE` on all databases and schemas with registered data sources.
   * If using Iceberg tables, `USAGE` on the external volume.
   * [`REFERENCES` on all tables and views registered in Immuta.](#user-content-fn-1)[^1]
   * [`SELECT` on all tables and views registered in Immuta](#user-content-fn-2)[^2].
3. [Grant the new Snowflake role](https://docs.snowflake.com/en/sql-reference/sql/grant-role) to the system account you just created.

## Register a connection

To register a Snowflake connection, follow the instructions below.

1. Click <i class="fa-database">:database:</i> **Data** and select the the **Connections** tab in the navigation menu.
2. Click the **+ Add Connection** button.
3. Select the Snowflake data platform tile.
4. Enter the connection information:
   * **Display Name**: The display name represents the unique name of your connection and will be used as prefix in the name for all data objects associated with this connection. It will also appear as the display name in the UI and will be used in all API calls made to update or delete the connection. Avoid the use of periods (`.`) or restricted words in your connection name.
   * **Host**: The URL of your Snowflake account.
   * **Port**: Your Snowflake port.
   * **Warehouse**: The warehouse the Immuta system account user will use to run queries and perform Snowflake operations.
   * **Role**: Enter the role with the [listed privileges](#requirements).
   * **Immuta Database**: The new, empty database for Immuta to manage. The script in the last step of registering the connection will create this database. This is where system views, user entitlements, row access policies, column-level policies, procedures, and functions managed by Immuta will be created and stored.
5. Opt to configure an HTTP proxy for this connection by selecting **Enable** and entering the required details:
   * **Proxy Host**: Enter the full proxy URL.
   * **Proxy Port**: Enter the proxy port.
   * Select if the proxy requires authentication:
     * **Disabled**
     * **Enabled**:
       * **Proxy Username**: Enter the username for the proxy connection.
       * **Proxy Password**: Enter the password for the proxy connection.
6. Select an authentication method from the dropdown menu and enter the authentication information for the [Immuta system account you created](#set-up-the-immuta-system-account).

<details>

<summary>OAuth M2M (Client Secret)</summary>

1. Fill out the **Client ID**, which is the subject of the generated token. It is also known as `sub` (subject).
2. Fill out the **Authority URL**, which is the authority URL of your identity provider.
3. Fill out the **Scope**, which is the scope of operations and roles allowed by the secret. Use `session:role-any`.
4. Fill out the **Client Secret**, which is the client secret Immuta will use to connect to your application.

</details>

<details>

<summary>OAuth M2M (Certificate)</summary>

1. Fill out the **Client ID**, which is the subject of the generated token. It is also known as `sub` (subject).
2. Fill out the **Authority URL**, which is the authority URL of your identity provider.
3. Fill out the **Scope**, which is the scope of operations and roles allowed by the secret. Use `session:role-any`.
4. Enter the **Certificate Thumbprint**. This identifies the corresponding key to the token and is often abbreviated as `x5t` or is called `kid` (key identifier).
5. Opt to fill out the **Resource** field with a URI of the resource where the requested token will be used.
6. Upload the **Private Key**, which is the client certificate that is used to sign the authorization request.

</details>

<details>

<summary>Key Pair (Unencrypted)</summary>

1. Complete the **Username** field. This user must be [assigned the public key in Snowflake](https://docs.snowflake.com/en/user-guide/key-pair-auth#assign-the-public-key-to-a-snowflake-user).
2. Click **Private Key**, and upload the Snowflake private key pair file.

</details>

<details>

<summary>Key Pair (Encrypted)</summary>

1. Complete the **Username** field. This user must be [assigned the public key in Snowflake](https://docs.snowflake.com/en/user-guide/key-pair-auth#assign-the-public-key-to-a-snowflake-user).
2. Click **Private Key**, and upload the Snowflake private key pair file.
3. When using an encrypted private key, enter the **Password**.

</details>

1. Click **Next**.
2. Configure the **Policy** settings:
   1. Opt to enable **Impersonation**. If you enable it, enter the **Impersonation Role** that will be used to impersonate other users in Snowflake.
   2. Opt to [exclude specific users from policy](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide#excepted-roles-users) by adding them to the **Exclude User Group Pattern**.
3. Click **Next**.
4. Opt to **Enable Audit**.
5. Click **Next**.
6. Opt to **Enable Object Sync**, which will keep your connection objects up to date with your Snowflake environment.
   1. Select the **Start Time** for when the first object sync job will run each day.
   2. Select the **Run Frequency** to determine how frequently object sync will run each day.
   3. Opt to **Run Object Sync on Create** to create all the data objects for your connection. If you do not select this option, you must run object sync manually or wait for the scheduled object sync for your connection's data objects.
7. Click **Save connection**.
8. Copy the provided script and run it in Snowflake as a user with the privileges [listed in the requirements section](#requirements). Running this script grants the following privileges to the Immuta system account and creates the new Immuta database in Snowflake:
   1. `CREATE ROLE ON ACCOUNT WITH GRANT OPTION`
   2. `MANAGE GRANTS ON ACCOUNT WITH GRANT OPTION`
   3. `APPLY MASKING POLICY ON ACCOUNT WITH GRANT OPTION`
   4. `APPLY ROW ACCESS POLICY ON ACCOUNT WITH GRANT OPTION`
9. Click **Validate Connection**.
10. If the connection is successful, click **Finish**. If there are any errors, check the connection details and credentials to ensure they are correct and try again.

[^1]: You must specify the Snowflake object type when granting `REFERENCES` on the table or view. For example, running `GRANT REFERENCES ON ALL TABLES` will grant this privilege to the standard table object type, but not to Iceberg tables or external tables. Instead, you would also have to run `GRANT REFERENCES ON ALL ICEBERG TABLES` and `GRANT REFERENCES ON ALL EXTERNAL TABLES`.

[^2]: Only required when using [identification](/2026.2/configuration/manage-data-metadata/data-discovery) or [specialized masking policies that require fingerprinting](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/masking-matrix-functions).\
    \
    You must specify the Snowflake object type when granting `SELECT` on the table or view. For example, running `GRANT SELECT ON ALL TABLES` will grant this privilege to the standard table object type, but not to Iceberg tables or external tables. Instead, you would also have to run `GRANT SELECT ON ALL ICEBERG TABLES` and `GRANT SELECT ON ALL EXTERNAL TABLES`.


# Remove a Snowflake Connection

Delete your Snowflake integration

{% hint style="info" %}
**Cleanup script**

You must run the cleanup script to completely remove Immuta-managed items from your environment. Until you manually run the cleanup script in your Snowflake environment, Immuta-managed [roles](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide#subscription-policies) and Immuta policies will still exist in Snowflake.
{% endhint %}

To delete the host,

1. Click **Data** in the navigation menu and select **Connections**.
2. Click the **overflow menu** in the Actions column and select **Delete Host**.
3. Download the **cleanup script** from the modal.
4. Click **Delete Host** again to confirm.
5. Navigate to Snowflake and run the cleanup script in your environment to remove the Immuta-managed roles and policies.


# Manage Snowflake Connection Settings

Manage Snowflake integration and connection settings

## Run object sync <a href="#run-object-sync" id="run-object-sync"></a>

1. Navigate to the connection or connection-backed object.
2. Click **Run Object Sync**.

## Edit the connection details <a href="#edit-the-connection-details" id="edit-the-connection-details"></a>

1. Click the **Edit** button in the Connection details box.
2. Edit the field you want:
   1. **Host**
   2. **Port**
   3. **Warehouse**
   4. **Role**: If you edit the role, ensure the new role has the [required privileges](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account) to see the data objects.
   5. **HTTP Proxy**
   6. **Authentication Method**: If you are editing the authentication method to be a different system account user, [grant the new system user the connection role and the role created from the setup script](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account).
   7. **Object Synchronization**: Use the dropdown to select a new **Start Time** or **Run Frequency**.
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the policy settings <a href="#edit-the-policy-settings" id="edit-the-policy-settings"></a>

1. Click the **Edit** button in the Policy settings box.
2. Opt to enable or disable **Impersonation**.
   1. Enter the **Impersonation Role**.
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the audit settings <a href="#edit-the-audit-settings" id="edit-the-audit-settings"></a>

1. Click the **Edit** button in the Audit settings box.
2. Opt to enable or disable **Query Audit**: If you enable audit, ensure the system account has the [required permissions for audit](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account).
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the object settings <a href="#edit-the-object-settings" id="edit-the-object-settings"></a>

1. Click the **Edit** button in the Object settings box.
2. Opt to enable or disable **Policy Synchronization**: When policy sync is enabled, all child objects will be represented by Immuta data sources and policies will be applied to the data sources.
3. Opt to **Add Users and Groups** as data owners:
   1. Start typing in the text box and select the user or group from the dropdown.
   2. Click **Add Owners**.
4. Click **Save**.


# Enable Snowflake Tag Ingestion

Enable Snowflake tag ingestion to pull Snowflake tags and apply them to data sources

To allow Immuta to automatically import table and column tags from Snowflake, enable Snowflake tag ingestion in the external catalog section of the Immuta app settings page.

**Requirements**

* A configured Snowflake connection
* The Snowflake user configuring the Snowflake tag ingestion must have the following privileges and should be able to access all securables registered as data sources:
  * `IMPORTED PRIVILEGES ON DATABASE snowflake`
  * `APPLY TAG ON ACCOUNT`

{% hint style="info" %}
**Credentials**

Use the same credentials as your connection.

For tag ingestion to work smoothly, ensure the credentials provided for tag ingestion can access all the data objects in Immuta. Any data objects the credentials do not have access to will not be tagged.
{% endhint %}

1. Navigate to the **App Settings** page.
2. Scroll to **2 External Catalogs**, and click **Add Catalog**.
3. Enter a **Display Name** and select **Snowflake** from the dropdown menu.
4. Enter the **Account**.
5. Enter the **Authentication** information based on your authentication method:
   1. **Username and password**: Fill out **Username** and **Password**.
   2. **Key pair**:
      1. Fill out **Username**.
      2. Click **Upload Certificates** to enter in the **Certificate Authority**, **Certificate File**, and **Key File**.
      3. Close the modal and opt to enter the **Encrypted Key File Passphrase**.
6. Enter the additional Snowflake details: **Port**, **Default Warehouse**, and **Role**.
7. Opt to enter the **Proxy Host** and **Proxy Port**.
8. Click the **Test Connection** button.
9. Click the **Test Data Source Link**.
10. Once both tests are successful, click **Save**.


# Use Snowflake Data Sharing with Immuta

Immuta is compatible with [Snowflake Secure Data Sharing](https://docs.snowflake.com/en/user-guide/data-sharing-intro.html). Using both Immuta and Snowflake, organizations can share the policy-protected data of their Snowflake database with other Snowflake accounts with Immuta policies enforced in real time.

**Prerequisite**

* [Snowflake connection registered](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection)

## Create Immuta Policies to Protect the Data

**Required Permission**: Immuta: `GOVERNANCE`

[Build Immuta data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies) to fit your organization's compliance requirements.

It's important to understand that subscription policies are not relevant to Snowflake data shares, because the act of sharing the data *is* the subscription policy. Data policies can be enforced on the consuming account from the producer account on a share following these instructions.

## Register the Snowflake Data Consumer with Immuta

**Required Permission**: Immuta: `USER_ADMIN`

To register the Snowflake data consumer in Immuta,

1. [Create a new Immuta user](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#create-users).
2. [Update the Immuta user's Snowflake username](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#manually-configure-external-user-id-mapping-on-a-users-page) to match the account ID for the data consumer. This value is the output on the data consumer side when `SELECT CURRENT_ACCOUNT()` is run in Snowflake.
3. [Give the Immuta user the appropriate attributes and groups](/2026.2/configuration/people/immuta-users/how-to-guides/managing-attribute-and-group#add-group-or-user-attribute) for your organization's policies.
4. [Subscribe the Immuta user to the data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/data-source-settings/how-to-guides/manage-members).

## Create the Snowflake Data Share

**Required Permission**: Snowflake `ACCOUNTADMIN`

To share the policy-protected data source,

1. [Create a Snowflake Data Share](https://docs.snowflake.com/en/user-guide/data-sharing-gs.html#getting-started-with-secure-data-sharing) of the Snowflake table that has been registered in Immuta.
2. Grant reference usage on the Immuta database to the share you created:

   ```sql
   GRANT REFERENCE_USAGE ON DATABASE "<Immuta database of the provider account>" TO SHARE "<DATA_SHARE>";
   ```

   Replace the content in angle brackets above with the name of your Immuta database and Snowflake data share.


# Reference Guides


# Snowflake Integration Reference Guide

Learn about how the Snowflake integration works and what Immuta creates in your environment to administer Snowflake access controls directly on objects in Snowflake

Using the Snowflake connection, you can register a Snowflake integration for your Snowflake Enterprise account.

The sequence diagram below outlines the events that occur when an Immuta user wants to query a Snowflake table that has been registered as an Immuta data source.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FNS520sRsSKrJXgNpcj9j%2Fimage.png?alt=media&amp;token=a4b972f5-2ce5-4d95-92de-af249883cc04" alt=""><figcaption></figcaption></figure>

## What does Immuta do in my environment?

### Registering a connection <a href="#registering-a-connection" id="registering-a-connection"></a>

Immuta utilizes [connections](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) to register and manage data from your entire Snowflake environment all at once. This approach simplifies data registration and allows Immuta to automatically monitor your Snowflake platform for changes. Data sources are then added or removed to reflect the current state of your data platform.

When a [connection is first registered](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection), Immuta will ask your application admin to provide the following:

* The name of an **Immuta system database** in Snowflake that Immuta will control and create schemas (`immuta_procedures`, `immuta_policies`, and `immuta_functions`) in to contain policy definitions and user entitlements. This database will be created when you run the setup script.
* A **Snowflake role** with the required privileges that the system account will use to maintain state of data objects between Snowflake and Immuta.
* A **set of Snowflake credentials to a system account** with the [required privileges](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account) to connect between Snowflake and Immuta. These credentials will be used to initially register all your [Snowflake objects](#supported-object-types) as data objects. Immuta will also continue to use those credentials for scheduled [object syncs](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide#object-sync), [identification](/2026.2/configuration/manage-data-metadata/data-discovery), and to orchestrate policies in Snowflake.

The application admin will then run the setup script in Snowflake, which will create the following:

* The **new Immuta system database** to contain policy definitions and user entitlements.
* A **new system Snowflake role** to orchestrate policies in Snowflake, which will be attached to the Snowflake system account.

When policies are applied to Snowflake objects, the following will be done in your Snowflake environment:

* Subscription policies will require **a new role to be created for each user**, which will be granted access to the object in Snowflake. The role prefix is set on the [Immuta app settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#integration-settings). For example, if the user is `jane.doe@immuta.com` and if the role prefix is set to `IMMUTA`, the role will be `IMMUTA_USER_jane.doe@immuta.com` and granted access to the table.
* Data policies will require **Immuta to manage and apply** [**Snowflake governance column**](https://docs.snowflake.com/en/user-guide/security-column.html) **and** [**row access policies**](https://docs.snowflake.com/en/user-guide/security-row.html) **to Snowflake objects** that are registered as Immuta data sources using the system Snowflake account and role.

After the setup and registration is complete, Immuta ingests and stores connection metadata in the Immuta metadata database. In the example below, the Immuta application administrator connects the database that contains `marketing-data`, `research-data`, and `cs-data` tables. Immuta registers these tables as data objects and stores the table metadata in the Immuta metadata database. Creating the connection does not impact any user's existing access in Snowflake until subscription policies are applied to the tables.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FFfGdtTenIrrOFKmjgP3D%2Fimage.png?alt=media&amp;token=80ba77b0-f296-4387-8bbe-cacc06e6d089" alt=""><figcaption></figcaption></figure>

Beyond making the registration of your data more intuitive, connections provide more control. Instead of performing operations on individual schemas or tables, you can perform operations (such as object sync) at the connection level.

See the [Connections reference guide](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) for details about connections and how to manage them. To configure your Snowflake connection, see the [Register a Snowflake connection guide](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection).

### Applying policies <a href="#applying-policies" id="applying-policies"></a>

By default, the Snowflake integration is designed to be minimally invasive: if a table does not have policy sync enabled, users will still have access to it in Snowflake.

#### Subscription policies

Immuta enforces read and write [subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) on Snowflake tables by granting access to the appropriate tables in Snowflake.

Once the connection is registered, this is what happens when a user applies a subscription policy to a Snowflake data source:

1. Immuta creates a role for the user querying the table in Snowflake, if one doesn't already exist. The role will be `<IMMUTA>_USER_<username>`.
2. Snowflake stores that role in its internal system catalog.
3. Immuta issues grants to that user's role in Snowflake to enforce policy. The [Protecting data page](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/protecting-data) provides an example of this policy enforcement.
4. Immuta will then grant that personalized role to the Immuta user in Snowflake. The [Accessing data page](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/accessing-data) provides details about how the user should set their Snowflake roles.
5. Users will query data in Snowflake, using [`USE SECONDARY ROLES ALL`](https://docs.snowflake.com/en/sql-reference/sql/use-secondary-roles.html#syntax), which allows them to use the privileges from all roles that have been granted to them including the `<IMMUTA>_USER_<username>` role and their current active primary role.

#### Data policies

You can author [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) in Immuta to enforce fine-grained access controls on Snowflake data objects registered as Immuta data sources. For more details about how enforcement works, see the [Protecting data page](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/protecting-data).

When a data policy is applied to a Snowflake data source in Immuta,

1. A data owner, data governor, or administrator [creates or changes a policy](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure) or a [user's attributes change](/2026.2/configuration/people/immuta-users/how-to-guides/managing-attribute-and-group) in Immuta.
2. Immuta manages and applies [Snowflake governance column](https://docs.snowflake.com/en/user-guide/security-column.html) and [row access policies](https://docs.snowflake.com/en/user-guide/security-row.html) to Snowflake tables that are registered as Immuta data sources using the system Snowflake account and role.
3. A Snowflake user who is subscribed to the data source in Immuta queries the corresponding table directly in Snowflake and sees policy-enforced data.

See the integration support matrix on the [Data policies reference guide](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) for a list of supported data policy types in Snowflake.

#### **Snowflake privileges granted by Immuta**

See the [Subscription policy access types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-snowflake-privileges) for details about the Snowflake privileges granted to users when they are subscribed to a data source protected by a subscription policy.

### Required Snowflake privileges

The privileges the Snowflake integration requires align to the least privilege security principle. The table below describes each privilege required in Snowflake for the [setup user](#user-content-fn-1)[^1] or the [system account user](#user-content-fn-2)[^2]. The references to `IMMUTA_DB` , `IMMUTA_WH`, and `IMMUTA_IMPERSONATOR_ROLE` in the table can be replaced with what you chose for the name of your Immuta database, warehouse, and impersonation role when setting up the integration, respectively.

| Snowflake privilege                                                                                                                                                                                                                                                                                                                                                                                                          | User requiring privilege | Features                                                                    | Explanation                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CREATE DATABASE ON ACCOUNT WITH GRANT OPTION`                                                                                                                                                                                                                                                                                                                                                                               | Setup user               | All                                                                         | The setup script this user runs creates an Immuta database in your organization's Snowflake account where all Immuta managed objects (UDFs, masking policies, row access policies, and user entitlements) will be written and stored.                                                                                                                           |
| `CREATE ROLE ON ACCOUNT WITH GRANT OPTION`                                                                                                                                                                                                                                                                                                                                                                                   | Setup user               | All                                                                         | The setup user must create a `ROLE` for Immuta that will be used to manage the integration and policies once it has been initialized.                                                                                                                                                                                                                           |
| `MANAGE GRANTS ON ACCOUNT`                                                                                                                                                                                                                                                                                                                                                                                                   | Setup user               | All                                                                         | The user registering the connection must be able to `GRANT` global privileges and access to objects within the Snowflake account. All privileges that are documented here must be granted to the system account user by the setup user manually or through the setup script.                                                                                    |
| <ul><li><code>ALL PRIVILEGES ON DATABASE IMMUTA\_DB</code></li><li><code>ALL PRIVILEGES ON ALL SCHEMAS IN DATABASE IMMUTA\_DB</code></li><li><code>USAGE ON FUTURE PROCEDURES IN SCHEMA IMMUTA\_DB.IMMUTA\_PROCEDURES</code></li></ul>                                                                                                                                                                                       | System account user      | All                                                                         | Immuta requires these privileges because Immuta must have full ownership of the Immuta database where Immuta objects are managed.                                                                                                                                                                                                                               |
| `USAGE ON WAREHOUSE IMMUTA_WH`                                                                                                                                                                                                                                                                                                                                                                                               | System account user      | All                                                                         | To make changes to state in the Immuta database, Immuta requires access to compute (a Snowflake warehouse). Some state changes are DDL operations, and others are DML and require compute.                                                                                                                                                                      |
| `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`                                                                                                                                                                                                                                                                                                                                                                                  | System account user      | Audit                                                                       | To ingest audit information from Snowflake, Immuta must have access to the `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY` view. See the [Snowflake documentation](https://docs.snowflake.com/en/sql-reference/account-usage/access_history) for details.                                                                                                              |
| <ul><li><code>APPLY MASKING POLICY ON ACCOUNT</code></li><li><code>APPLY ROW ACCESS POLICY ON ACCOUNT</code></li></ul>                                                                                                                                                                                                                                                                                                       | System account user      | Data policies                                                               | Immuta must be able to apply policies to objects throughout your organization's Snowflake account and query for existing policies on objects using the `POLICY_REFERENCES` [table function](https://docs.snowflake.com/en/sql-reference/functions/policy_references.html).                                                                                      |
| `USAGE` on the external volume if registering Iceberg tables                                                                                                                                                                                                                                                                                                                                                                 | System account user      | Data policies on Iceberg tables                                             | Immuta must have this privilege to apply data policies to Iceberg tables.                                                                                                                                                                                                                                                                                       |
| `SELECT` on all tables and views registered in Immuta                                                                                                                                                                                                                                                                                                                                                                        | System account user      | Identification and specialized masking policies that require fingerprinting | Immuta must have this privilege to run the necessary queries for [identification](/2026.2/configuration/manage-data-metadata/data-discovery) on your data sources.                                                                                                                                                                                              |
| `OWNERSHIP ON ROLE IMMUTA_IMPERSONATOR_ROLE`                                                                                                                                                                                                                                                                                                                                                                                 | System account user      | Impersonation                                                               | If impersonation is enabled, Immuta must be able to manage the Snowflake roles used for impersonation in order to manage the impersonation feature.                                                                                                                                                                                                             |
| <ul><li><code>USAGE</code> on all databases and schemas with registered data sources</li><li><code>REFERENCES</code> on all tables and views registered in Immuta</li></ul>                                                                                                                                                                                                                                                  | System account user      | Object sync                                                                 | Immuta must be able to see metadata on securables to register them as data sources.                                                                                                                                                                                                                                                                             |
| `MANAGE GRANTS ON ACCOUNT` or [`OWNERSHIP` on the objects that Immuta will secure](#user-content-fn-3)[^3]                                                                                                                                                                                                                                                                                                                   | System account user      | Subscription policies                                                       | Immuta must be able to `MANAGE GRANTS` on objects throughout your organization's Snowflake account.                                                                                                                                                                                                                                                             |
| `CREATE ROLE ON ACCOUNT`                                                                                                                                                                                                                                                                                                                                                                                                     | System account user      | Subscription policies                                                       | Immuta must be able to create roles as targets for Immuta subscription policy permissions in your organization’s Snowflake account.                                                                                                                                                                                                                             |
| `APPLY TAG ON ACCOUNT`                                                                                                                                                                                                                                                                                                                                                                                                       | System account user      | Tag ingestion                                                               | To ingest table, view, and column tag information from Snowflake, Immuta must have this permission. Immuta reads from the `TAG_REFERENCES` [table function](https://docs.snowflake.com/en/sql-reference/functions/tag_references.html).                                                                                                                         |
| `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`                                                                                                                                                                                                                                                                                                                                                                                  | System account user      | Tag ingestion                                                               | To ingest table, view, and column tag information from Snowflake, Immuta must have access to the `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY` view. See the [Snowflake documentation](https://docs.snowflake.com/en/sql-reference/account-usage/access_history) for details.                                                                                        |
| <ul><li><code>USAGE ON DATABASE IMMUTA\_DB</code></li><li><code>USAGE ON SCHEMA IMMUTA\_DB.IMMUTA\_PROCEDURES</code></li><li><code>USAGE ON SCHEMA IMMUTA\_DB.IMMUTA\_FUNCTIONS</code></li><li><code>USAGE ON FUTURE FUNCTIONS IN SCHEMA IMMUTA\_DB.IMMUTA\_FUNCTIONS</code></li><li><code>USAGE ON SCHEMA IMMUTA\_DB.IMMUTA\_SYSTEM</code></li><li><code>SELECT ON IMMUTA\_DB.IMMUTA\_SYSTEM.USER\_PROFILE</code></li></ul> | `PUBLIC` role            | All                                                                         | Immuta has stored procedures and functions that are used for policy enforcement and do not expose or contain any sensitive information. These objects must be accessible by all users to facilitate the use and creation of policies or views to enforce Immuta policies in Snowflake.                                                                          |
| `SELECT ON IMMUTA_DB.IMMUTA_SYSTEM.ALLOW_LIST`                                                                                                                                                                                                                                                                                                                                                                               | `PUBLIC` role            | All                                                                         | Immuta retains a list of excepted roles and users when using the Snowflake integration. The roles and users in this list will be exempt from policies applied to tables in Snowflake to give organizations flexibility in case there are entities that should not be bound to Immuta policies in Snowflake (for example, a system or application role or user). |

#### Maintaining state with Snowflake

The following user actions spur various processes in the Snowflake integration so that Immuta data remains synchronous with data in Snowflake. The list below provides an overview of each process:

* **Data source created**: Immuta registers data source metadata and stores that metadata in the Immuta metadata database.
* [**User account is mapped to Immuta**](#user-registration-and-id-mapping): When a user account is mapped to Immuta, their metadata is stored in the metadata database.
* **User subscribed to a data source**: When a user is added to a data source by a data owner or through a subscription policy, Immuta creates a role for that user (if a role for them does not already exist) and grants Snowflake privileges to their role.
* **Automatic subscription policy applied to or updated on a data source**: Immuta calculates the users and data sources affected by the policy change and grants or revokes users' privileges on the Snowflake object. See the [Protecting data page](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/protecting-data) for details about this process.
* **Subscription policy deleted**: Immuta revokes privileges from the affected roles.
* **Data policy created or updated**: Snowflake row access policies and column masking policies are applied to the Snowflake object to reflect the Immuta policy. See the [Protecting data page](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/protecting-data) for details about this process.
* **Data policy deleted**: Immuta removes the policy from the Snowflake object.
* **User removed from a data source**: Immuta revokes privileges from the user's role.

### Supported object types <a href="#supported-object-types" id="supported-object-types"></a>

| Object type       | Subscription policy support | Data policy support  |
| ----------------- | --------------------------- | -------------------- |
| Table             | :white\_check\_mark:        | :white\_check\_mark: |
| View              | :white\_check\_mark:        | :white\_check\_mark: |
| Materialized view | :white\_check\_mark:        | :white\_check\_mark: |
| External table    | :white\_check\_mark:        | :white\_check\_mark: |
| Event table       | :white\_check\_mark:        | :white\_check\_mark: |
| Iceberg table     | :white\_check\_mark:        | :white\_check\_mark: |
| Dynamic table     | :white\_check\_mark:        | :white\_check\_mark: |

## Supported policies

The Snowflake integration allows users to author subscription and data policies to enforce access controls. See the corresponding pages for details about specific types of policies supported:

* [Subscription policy access types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types)
* [Data policy types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#data-policy-support-matrix)

## Supported Snowflake features <a href="#supported-snowflake-features" id="supported-snowflake-features"></a>

The Immuta Snowflake integration supports the following Snowflake feature.

* [Snowflake external tables](https://docs.snowflake.com/en/user-guide/tables-external-intro.html): However, you cannot add a masking policy to an external table column while creating the external table in Snowflake because masking policies cannot be attached to virtual columns.

## Security and compliance <a href="#security-and-compliance" id="security-and-compliance"></a>

### Authentication methods <a href="#authentication-methods" id="authentication-methods"></a>

The Snowflake integration supports the following authentication methods to register a connection. The credentials provided must be for an account with the permissions listed in the [Register a Snowflake connection guide](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection).

* **Key pair**: Users can authenticate with a [Snowflake key pair authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth.html#key-pair-authentication-key-pair-rotation).
* **Snowflake External OAuth**: Users can authenticate with [Snowflake External OAuth](https://docs.snowflake.com/en/user-guide/oauth-intro.html). For more information about this authentication option, see the [Security and compliance guide](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide/security-and-compliance).

### User registration and ID mapping

The built-in Immuta IAM can be used as a complete solution for authentication and user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and user entitlement instead. Each of the [supported IAM protocols](/2026.2/releases/support-matrix#iam-protocols) includes a set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

For policies to impact the right users, the user account in Immuta must be mapped to the user account in Snowflake. You can ensure these accounts are mapped correctly in the following ways:

* [Automatically](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#configure-external-user-id-mapping-on-app-settings-page): If usernames in Snowflake align with usernames in the external IAM and those accounts align with an IAM attribute, you can enter that IAM attribute on the app settings page to automatically map user IDs in Immuta to Snowflake.
* [Manually](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#manually-configure-external-user-id-mapping-on-a-users-page): You can manually map user IDs for individual users.

For guidance on connecting your IAM to Immuta, see the [how-to guide for your protocol](/2026.2/configuration/people/section-contents).

### Excepted roles/users <a href="#excepted-roles-users" id="excepted-roles-users"></a>

Excepted roles and users are assigned when the connection is registered, and no policies will apply to these users' queries, despite any Immuta policies enforced on the tables they are querying. Consequently, roles and users added to this list should be limited to service accounts.

#### How do excepted roles/users work?

Immuta excludes the listed roles and users from policies by wrapping all policies in a `CASE` statement that will check if a user is acting under one of the listed usernames or roles. If a user is on the list, then the policy will not be acted on the queried table. If the user is not, then the policy will be executed like normal. Immuta does not distinguish between role and username, so if you have a role and user with the exact same name, both the user and any user acting under that role will have full access to the data sources and no policies will be enforced for them.

#### When should you use excepted roles/users?

* Add **service accounts** to the excepted roles/users list so that Immuta subscription and data policies will not unintentionally impact their jobs.
* When using both tables and their views as data sources, add **the owner of the view** in Snowflake as an excepted role/user. Otherwise, the backing table's policies will be applied to that view.

### Tag ingestion <a href="#tag-ingestion" id="tag-ingestion"></a>

You can enable Snowflake tag ingestion so that Immuta will ingest Snowflake object tags from your Snowflake instance into Immuta and add them to the appropriate data sources. The Snowflake tags' key and value pairs will be reflected in Immuta as two levels: the key will be the top level and the value the second. As Snowflake tags are hierarchical, Snowflake tags applied to a database will also be applied to all of the schemas in that database, all of the tables within those schemas, and all of the columns within those tables. For example: If a database is tagged `PII`, all of the tables and columns in that database will also be tagged `PII`.

Snowflake tag ingestion supports two authentication methods:

* **Username and password**
* **Key pair**

To enable Snowflake tag ingestion, see the [Enable Snowflake tag ingestion page](/2026.2/configuration/integrations/snowflake/how-to-guides/enable-snowflake-tag-ingestion).

**Credentials**

If you want all Snowflake data sources to have Snowflake data tags ingested into Immuta, ensure the credentials provided on the [Immuta app settings page](/2026.2/configuration/integrations/snowflake/how-to-guides/enable-snowflake-tag-ingestion) for the external catalog feature can access all the data sources registered in Immuta. Any data sources the credentials do not have access to will not be tagged in Immuta. In practice, it is recommended to just **use the same credentials for the** [**connection**](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection#set-up-the-immuta-system-account) **and tag ingestion**.

**Caveats**

Snowflake has some [natural data latency](https://docs.snowflake.com/en/sql-reference/account-usage.html#data-latency). If you manually refresh the governance page to see all tags created globally, users can experience a delay of up to two hours. However, if you run object sync or a health check to find where those tags are applied, the delay will not occur because Immuta will only refresh tags for those specific tables.

### Limitations and known issues <a href="#limitations-and-known-issues" id="limitations-and-known-issues"></a>

* Snowflake workspaces are deprecated and are not supported with Snowflake table grants enabled, which is the default for all new connections.
* If there are errors in generating or applying policies natively in Snowflake, the data source will be locked and only users on the [excepted roles/users list](#excepted-roles-users) and the credentials used to register the connection will be able to access the data.
* Once a Snowflake connection is deactivated in Immuta, the user must remove the access that was granted in Snowflake. If that access is not revoked, users will be able to access the raw table in Snowflake.
* When configuring one Snowflake instance with multiple Immuta tenants, the Snowflake system account for the connection must be unique in each Immuta tenant.
* You cannot add a masking policy to an external table column while creating the external table because a masking policy cannot be attached to a virtual column.
* If you create an Immuta data source from a Snowflake view created using a `select * from` query, Immuta cannot get the column metadata because [Snowflake views are not automatically updated based on backing table changes](https://docs.snowflake.com/en/sql-reference/sql/create-view.html#usage-notes). To remedy this, you can create views that have the specific columns you want or you can `CREATE AND REPLACE` the view in Snowflake whenever the backing table is updated and manually run the object sync job on the data source page.
* If a user is created in Snowflake after that user is already registered in Immuta, Immuta does not grant usage on the per-user role automatically - meaning Immuta does not govern this user's access without manual intervention. If a Snowflake user is created after that user is registered in Immuta, the user account must be [disabled](/2026.2/configuration/people/immuta-users/how-to-guides/managing-personas-and-permissions#disable-users) and re-enabled to trigger a sync of Immuta policies to govern that user. Whenever possible, Snowflake users should be created before registering those users in Immuta.
* Snowflake tables from imported databases are not supported. Instead, create a view of the table and register that view as a data source.
* Data sources created from connections cannot be deleted. To remove the Immuta-applied policies from a Snowflake table, remove the policies from the data source, then disable it. To remove the Immuta-managed policies from all Snowflake tables, deactivate the connection.

**Custom WHERE clause limitations**

The Immuta Snowflake integration uses Snowflake governance features to let users query data natively in Snowflake. This means that Immuta also inherits some Snowflake limitations using correlated subqueries with [row access policies](https://docs.snowflake.com/en/user-guide/security-row-intro.html#considerations) and [column-level security](https://docs.snowflake.com/en/user-guide/security-column-intro.html#limitations). These limitations appear when writing [custom WHERE policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/custom-where-clause-functions), but do not remove the utility of row-level policies.

**Requirement for a custom WHERE policy**: The Immuta system account must have `SELECT` privileges on all tables/views referenced in a subquery via the system Snowflake role created by the setup script. Reach out to your Immuta support professional if you do not know the role to grant privileges to.

**Subquery limitations**

**Any subqueries that error in Snowflake will also error in Immuta.**

1. Including one or more subqueries in the Immuta policy condition may cause errors in Snowflake. If an error occurs, it may happen during policy creation or at query-time. To avoid these errors, limit the number of subqueries, limit the number of JOIN operations, and simplify WHERE clause conditions.
2. For more information on the Snowflake subquery limitations see
   * ​[Understanding column-level security](https://docs.snowflake.com/en/user-guide/security-column-intro.html#limitations)​
   * ​[Understanding row access policies](https://docs.snowflake.com/en/user-guide/security-row-intro.html#considerations)

[^1]: The user registering the Snowflake connection.

[^2]: This system account is used by Immuta to manage the Snowflake integration once it has been set up.

[^3]: The current role that has `OWNERSHIP` on the securables will need to be granted to the Immuta system role. However, if granting `OWNERSHIP` instead of `MANAGE GRANTS ON ACCOUNT`, Immuta will not be able to manage the role that is granted to the account.


# Security and Compliance

Understand the authentication methods and audit features supported by the Snowflake integration to ensure you are meeting your organization's security and compliance needs

## Authentication <a href="#authentication" id="authentication"></a>

### Registering the connection

The Snowflake integration supports the following authentication methods to register a connection. The credentials provided must be for an account with the permissions listed in the [Register a Snowflake connection guide](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection).

* **Key pair**
* **Snowflake External OAuth**

#### Snowflake External OAuth

Immuta's OAuth authentication method uses the [Client Credentials Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) to integrate with Snowflake External OAuth. When a user configures the Snowflake integration, Immuta uses the token credentials (obtained using a certificate or passing a client secret) to craft an authenticated access token to connect with Snowflake. This allows organizations that already use Snowflake External OAuth to use that secure authentication with Immuta.

This is what will happen if you use Snowflake External OAuth to authenticate your Snowflake connection:

1. An Immuta application administrator registers the Snowflake connection.
2. Immuta creates a custom token and sends it to the authorization server.
3. The authorization server confirms the information sent from Immuta and issues an access token to Immuta.
4. Immuta sends the access token it received from the authorization server to Snowflake.
5. Snowflake authenticates the token and grants access to the requested resources from Immuta.
6. The integration is connected and users can query data.

### Identity providers for user authentication

The built-in Immuta IAM can be used as a complete solution for authentication and user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and user entitlement instead.

Each of the supported identity providers includes a specific set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

See the [Identity managers guide](/2026.2/configuration/people/section-contents/reference-guides/identity-managers) for a list of supported providers and details.

See the [Snowflake integration reference guide](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide#user-registration-and-id-mapping) for details about user provisioning and mapping user accounts to Immuta.

## Auditing and compliance <a href="#auditing-and-compliance" id="auditing-and-compliance"></a>

Immuta provides auditing features and governance reports so that data owners and governors can monitor users' access to data and detect anomalies in behavior.

You can view the information in these audit logs on [dashboards](/2026.2/governance/detect-your-activity/detection/detect-concept).

See the [Audit documentation](/2026.2/governance/detect-your-activity/audit/reference-guides/universal-audit-model-uam) for details about these capabilities and how they work with the Snowflake integration.

### Snowflake query audit <a href="#snowflake-query-audit" id="snowflake-query-audit"></a>

Immuta captures queries in Snowflake, making audit records more useful in assessing what users are doing. To audit Snowflake queries, Immuta runs a query in Snowflake to retrieve user query histories. Those histories are then populated into comprehensive audit logs. Immuta will only audit queries from Immuta users on objects registered as Immuta data sources.

Query audit can be [enabled through the connection](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection). Audit ingestion will run at the schedule set on the [app settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#snowflake-audit-sync-schedule). Audit ingestion can be manually requested at any time from the Immuta audit page. When manually requested, it will only search for new queries that were created since the last query that had been audited. The job is run in the background, so the new queries will not be immediately available.

See the [Snowflake audit page](/2026.2/governance/detect-your-activity/audit/reference-guides/query-audit-logs/snowflake) for details about the contents of the logs and an example of the resulting audit record.

### Governance reports <a href="#governance-reports" id="governance-reports"></a>

Immuta governance reports allow users with the `GOVERNANCE` Immuta permission to use a natural language builder to instantly create reports that delineate user activity across Immuta. These reports can be based on various entity types, including users, groups, projects, data sources, purposes, policy types, or connection types.

See the [Governance report types](/2026.2/governance/detect-your-activity/audit/reference-guides/reports) page for a list of report types and guidance.<br>


# Protecting Data

Learn how Immuta enforces policies on data in your Snowflake environment

In the Snowflake integration, Immuta administers Snowflake privileges on data registered in Immuta. Then, Immuta users who have been granted access to the data sources can query them.

The sequence diagram below outlines the events that occur when an Immuta user who is subscribed to a data source queries it in Snowflake.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FNS520sRsSKrJXgNpcj9j%2Fimage.png?alt=media&amp;token=a4b972f5-2ce5-4d95-92de-af249883cc04" alt=""><figcaption></figcaption></figure>

## Registering a connection

The Snowflake integration is configured and data is registered through [connections](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide), an Immuta feature that allows administrators to register data objects in a technology through a single connection to make data registration more scalable for your organization.

Once the Snowflake connection is registered, you can author subscription and data policies in Immuta to enforce access controls.

See the [Snowflake integration reference guide](/2026.2/configuration/integrations/snowflake/reference-guides/snowflake-integration-reference-guide) for more details about registering a connection.

## Protecting data

#### Subscription policies <a href="#subscription-policies" id="subscription-policies"></a>

When a subscription policy is applied to a data source, users who meet the conditions of the policy will be automatically subscribed to the data source. Immuta creates roles for those users (if an Immuta-generated role for them does not already exist) and grants Snowflake privileges to that role.Consider the following example that illustrates how Immuta enforces a subscription policy that only allows users in the `analysts` group to access the `yellow-table`. When this policy is authored and applied to the data source, Immuta issues a SQL statement in Snowflake that grants the `SELECT` privilege on `yellow-table` to Immuta-created roles of users registered in Immuta that are part of the `analysts` group.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FXs2PRrV2xyFYBcidai0t%2Fimage.png?alt=media&amp;token=45c368cb-8e44-49ad-a30a-f7f945a2f41c" alt=""><figcaption></figcaption></figure>

In the image above, the user in the `analysts` group accesses `yellow-table`, while the user who is a part of the `research` group is denied access.

### Data policies

After Snowflake objects are registered in Immuta, you can author data policies in Immuta to enforce fine-grained access controls.

When a data policy is applied to a Snowflake data source, Immuta enforces that policy natively in Snowflake. Depending on the policy type, Immuta manages Snowflake [row access policies](https://docs.snowflake.com/en/user-guide/security-row.html) and [masking policies](https://docs.snowflake.com/en/user-guide/security-column.html) on the registered object so that queries return policy-enforced results.

As data policies are created, updated, or removed in Immuta, Immuta updates the corresponding Snowflake policy objects and attachments to keep enforcement in sync. Users continue querying the Snowflake object directly and see policy-enforced data in Snowflake.

See the [Data policies page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial) for guidance on authoring data policies in Immuta and the [supported data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#data-policy-support-matrix) for the Snowflake integration.

## **Comply with column length and precision requirements in a Snowflake masking policy**

When a user applies a masking policy to a Snowflake data source, Immuta truncates masked values to align with Snowflake column length ([`VARCHAR(X)`](https://docs.snowflake.com/en/sql-reference/data-types-text#varchar) types) and precision ([`NUMBER (X,Y)`](https://docs.snowflake.com/en/sql-reference/data-types-numeric) types) requirements.

Consider these columns in a data source that have the following masking policies applied.

* Column A (VARCHAR(6)): Mask using hashing for everyone
* Column B (VARCHAR(5)): Mask using a constant `REDACTED` for everyone
* Column C (VARCHAR(6)): Mask by making null for everyone
* Column D (NUMBER(3, 0)): Mask by rounding to the nearest 10 for everyone

Querying this data source in Snowflake would return the following values:

| A        | B       | C    | D     |
| -------- | ------- | ---- | ----- |
| `5w4502` | `REDAC` | null | `990` |
| `6e3611` | `REDAC` | null | `750` |
| `9s7934` | `REDAC` | null | `380` |

{% hint style="info" %}
**Hashing collisions**

Hashing collisions are more likely to occur across or within Snowflake columns restricted to short lengths, since Immuta truncates the hashed value to the limit of the column. (Hashed values truncated to 5 characters have a higher risk of collision than hashed values truncated to 20 characters.) Therefore, avoid applying hashing policies to Snowflake columns with such restrictions.
{% endhint %}

For more details about Snowflake column length and precision requirements, see the [Snowflake behavior change release](https://docs.snowflake.com/en/release-notes/bcr-bundles/2024_04/bcr-1355) documentation.

#### **Query performance**

When a policy is applied to a column, Immuta uses [Snowflake memoizable functions](https://docs.snowflake.com/en/developer-guide/udf/sql/udf-sql-scalar-functions#memoizable-udfs) to cache the result of the called function. Then, when a user queries a column that has that policy applied to it, Immuta uses that cached result to dramatically improve query performance.


# Accessing Data

Learn how end users can access policy-enforced data in Snowflake

Once data is registered through the Snowflake connection, you will access your data through your Snowflake queries as you normally would. If you are subscribed to the data source, Immuta grants you access to the data in Snowflake.

When you submit a query, the Snowflake client submits the SQL query to the Snowflake server, which then processes the query and determines what data your role is allowed to see. Then, the Snowflake server queries the database and returns the query results to the Snowflake client, which then returns policy-enforced data to you.

The diagram below illustrates how Immuta, the Snowflake server, and Snowflake client interact to access data.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2FNS520sRsSKrJXgNpcj9j%2Fimage.png?alt=media&amp;token=a4b972f5-2ce5-4d95-92de-af249883cc04" alt=""><figcaption></figcaption></figure>

## Querying data <a href="#querying-data" id="querying-data"></a>

Because subscription policies are managed through roles, you must be acting under the role Immuta creates for you to get access to your subscribed data sources. When querying data in Snowflake, do one of the following:

* ​[Use the role](https://docs.snowflake.com/en/sql-reference/sql/use-role.html#syntax) that Immuta creates and manages. (For example, `USE ROLE <prefix>_USER_<username>`: The role prefix is set on the [Immuta app settings page](/2026.2/configuration/application-settings/how-to-guides/config-builder-guide#integration-settings) and the `<username>` is your Immuta username.) If the current active primary role is used to query tables, `USAGE` on a Snowflake warehouse must be granted to the Immuta-managed Snowflake role for each user.
* ​Set your Snowflake to use secondary roles ([`USE SECONDARY ROLES ALL`](https://docs.snowflake.com/en/sql-reference/sql/use-secondary-roles.html#syntax)), which allows users to use the privileges from all roles that they have been granted, including `<prefix>_USER_<username>`, in addition to the current active primary role. Users may also set a value for `DEFAULT_SECONDARY_ROLES` as an [object property](https://docs.snowflake.com/en/sql-reference/sql/create-user.html#optional-object-properties-objectproperties) on a Snowflake user. To learn more about primary roles and secondary roles in Snowflake, see [Snowflake documentation](https://docs.snowflake.com/en/user-guide/security-access-control-overview.html#enforcement-model-the-primary-role-and-secondary-roles).

### User impersonation <a href="#user-impersonation" id="user-impersonation"></a>

Impersonation allows Immuta users or system accounts to query data sources they are subscribed to as another Immuta user.Consider the following users and their data source subscriptions.**User 1 data source subscriptions**

* HR data source
* Research data source

**User 2 data source subscriptions**

* HR data source
* Consumer report data source

The table below illustrates what data is returned when User 1, User 2, and User 2 impersonating User 1 query these data sources.

|                                 | HR data source          | Research data source                           | Consumer report data source |
| ------------------------------- | ----------------------- | ---------------------------------------------- | --------------------------- |
| **User 1**                      | `name` column is masked | `ssn` column is masked with hashing            | ​ :x: Denied access         |
| **User 2**                      | All data visible        | ​ :x: Denied access                            | `address` column is masked  |
| **User 2 impersonating User 1** | `name` column is masked | ​ :x: [Denied access​](#user-content-fn-1)[^1] | `address` column is masked  |

Users with the `APPLICATION_ADMIN` Immuta permission can enable impersonation when [registering a Snowflake connection](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection) for the first time or [edit an existing connection](/2026.2/configuration/integrations/snowflake/how-to-guides/register-a-snowflake-connection/manage-snowflake-connection-settings) to enable impersonation.

#### Audit <a href="#audit" id="audit"></a>

Snowflake query audit will show the user running the queries as the user logged in to Snowflake, **not** as the user they are impersonating.

[^1]: Even though they are impersonating a user who is subscribed to the data source, User 2 will be denied access to the data because they are not subscribed to the data source.


# Integration Settings


# Snowflake Data Sharing

Immuta is compatible with [Snowflake Secure Data Sharing](https://docs.snowflake.com/en/user-guide/data-sharing-intro.html). Using both Immuta and Snowflake, organizations can share the policy-protected data of their Snowflake database with other Snowflake accounts with Immuta policies enforced in real time. This integration gives data consumers a live connection to the data and relieves data providers of the legal and technical burden of creating static data copies that leave their Snowflake environment.

**Requirements**:

* Snowflake Enterprise Edition or higher

## Configuration

This method requires that the data consumer account is registered as an Immuta user with the Snowflake user name equal to the consuming account.

At that point, the user that represents the account being shared with can have the appropriate attributes and groups assigned to them, relevant to the data policies that need to be enforced. Once that user has access to the share in the consuming account (not managed by Immuta), they can query the share with the data policies from the producer account enforced because Immuta is treating that account as if they are a single user in Immuta.

For a tutorial on this workflow, see the [Using Snowflake Data Sharing page](/2026.2/configuration/integrations/snowflake/how-to-guides/use-data-sharing).

## Benefits

Using Immuta with Snowflake Data Sharing allows the sharer to

* Only need limited knowledge of the context or goals of the existing policies in place: Because the sharer is not editing or creating policies to share their data, they only need a limited knowledge of how the policies work. Their main responsibility is making sure they properly represent the attributes of the data consumer (the account being shared to).
* Leave policies untouched.


# Snowflake Low Row Access Policy Mode

The Snowflake low row access policy mode improves query performance in Immuta's Snowflake integration by decreasing the number of [Snowflake row access policies](https://docs.snowflake.com/en/user-guide/security-row.html) Immuta creates and by using table grants to manage user access.

Immuta manages access to Snowflake tables by administering [Snowflake row access policies](https://docs.snowflake.com/en/user-guide/security-row.html) and [column masking policies](https://docs.snowflake.com/en/user-guide/security-column.html) on those tables, allowing users to query them directly in Snowflake while policies are enforced.

## Project-scoped purpose exceptions for Snowflake

Project-scoped purpose exceptions for Snowflake integrations allow you to apply [purpose-based policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/purpose-tutorial) to Snowflake data sources in a project. As a result, users can only access that data when they are working within that specific project.

## Masked joins for Snowflake

This feature allows masked columns to be joined across data sources that belong to the same project. When data sources do not belong to a project, Immuta uses a unique salt per data source for hashing to prevent masked values from being joined. (See the [Why use masked joins?](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/masked-joins/masked-joins-explained) guide for an explanation of that behavior.) However, once you add Snowflake data sources to a project and enable masked joins, Immuta uses a consistent salt across all the data sources in that project to allow the join.

For more information about masked joins and enabling them for your project, see the [Masked joins section](/2026.2/governance/author-policies-for-data-access-control/projects-and-purpose-based-access-control/masked-joins) of documentation.


# Snowflake Table Grants

Snowflake table grants simplifies the management of privileges in Snowflake when using Immuta. Instead of having to manually grant users access to tables registered in Immuta, you allow Immuta to manage privileges on your Snowflake tables and views according to subscription policies. Then, users subscribed to a data source in Immuta can view and query the Snowflake table, while users who are not subscribed to the data source cannot view or query the Snowflake table.

## Snowflake privileges

Enabling Snowflake table grants gives the following privileges to the Immuta Snowflake role:

* **`MANAGE GRANTS ON ACCOUNT`** allows the Immuta Snowflake role to grant and revoke `SELECT` privileges on Snowflake tables and views that have been added as data sources in Immuta.
* **`CREATE ROLE ON ACCOUNT`** allows for the creation of a Snowflake role for each user in Immuta, enabling fine-grained, attribute-based access controls to determine which tables are available to which individuals.

## Table grants role

Since table privileges are granted to roles and not to users in Snowflake, Immuta's Snowflake table grants feature creates a new Snowflake role for each Immuta user. This design allows Immuta to manage table grants through fine-grained access controls that consider the individual attributes of users.

Each Snowflake user with an Immuta account will be granted a role that Immuta manages. The naming convention for this role is `<IMMUTA>_USER_<username>`, where

* **`<IMMUTA>`** is the prefix you specified when enabling the feature on the Immuta app settings page.
* **`<username>`** is the user's Immuta username.

## Querying Snowflake tables managed by Immuta

Users are granted access to each Snowflake table or view automatically when they are subscribed to the corresponding data source in Immuta.

Users have two options for querying Snowflake tables that are managed by Immuta:

* [Use the role](https://docs.snowflake.com/en/sql-reference/sql/use-role.html#syntax) that Immuta creates and manages. (For example, `USE ROLE IMMUTA_USER_<username>`. See the [section above](#table-grants-role) for details about the role and name conventions.) If the current active primary role is used to query tables, `USAGE` on a Snowflake warehouse must be granted to the Immuta-managed Snowflake role for each user.
* [<mark style="color:blue;">`USE SECONDARY ROLES ALL`</mark>](https://docs.snowflake.com/en/sql-reference/sql/use-secondary-roles.html#syntax), which allows users to use the privileges from all roles that they have been granted, including `IMMUTA_USER_<username>`, in addition to the current active primary role. Users may also set a value for `DEFAULT_SECONDARY_ROLES` as an [object property](https://docs.snowflake.com/en/sql-reference/sql/create-user.html#optional-object-properties-objectproperties) on a Snowflake user. To learn more about primary roles and secondary roles in Snowflake, see [Snowflake documentation](https://docs.snowflake.com/en/user-guide/security-access-control-overview.html#enforcement-model-the-primary-role-and-secondary-roles).

## Applying GRANTs and REVOKEs at scale

Immuta uses an algorithm to determine the most optimal way to group users in a role hierarchy in order to optimize the number of GRANTs (or REVOKES) executed in Snowflake. This is done by determining the least amount of possible permutations of access across tables and users based on the policies in place; then, those become intermediate roles in the hierarchy that each user is added to, based on the intermediate roles they belong to.

As an example, take the below users and data sources they have access to. To do this naively by individually granting every user to the tables they have access to would result in 37 grants:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/eiyWxmXXVxElyxgmSOgc/naive-grants.png" alt=""><figcaption></figcaption></figure>

Conversely, using the Immuta algorithm, we can optimize the number of grants in the same scenario down to 29:

<figure><img src="https://content.gitbook.com/content/6t660m9uhCtqfzQU5bjY/blobs/WEBPGOnnTxvE7ZRZESsh/optimized-grants.png" alt=""><figcaption></figcaption></figure>

It’s important to consider a few things here:

1. If the permutations of access are small, there will be a huge optimization realized (very few intermediate roles). If every user has their own unique permutation of access, the optimization will be negligible (an intermediate role per user). It is most common that the number of permutations of access will be many multiples smaller than the actual user count, so there should be large optimizations. In other words, a much smaller number of intermediate roles and the number of total overall grants reduced, since the tables are granted to roles and roles to users.
2. This only happens once up front. After that, changes are incremental based on policy changes and user attribute changes (smaller updates), unless there’s a policy that makes a sweeping change across all users. The addition of new users who have access becomes much more straightforward also due to the fact above. User’s access will be granted via the intermediate role, and, therefore, a lot of the work is front loaded in the intermediate role creation.

## Limitations

* If an Immuta tenant is connected to an external IAM and that external IAM has a username identical to another username in Immuta's built-in IAM, those users will have the same Snowflake role, leading both to see the same data.
* Sometimes the role generated can contain special characters such as `@` because it's based on the user name configured from your identity manager. Because of this, it is recommended that any code references to the Immuta-generated role be enclosed with double quotes.


# Warehouse Sizing Recommendations

The warehouse you select when configuring the Snowflake integration uses compute resources to set up the integration, register data sources, orchestrate policies, and run jobs like identification. Snowflake credit charges are based on the size of and amount of time the warehouse is active, not the number of queries run.

This document prescribes how and when to adjust the size and scale of clusters for your warehouse to manage workloads so that you can use Snowflake compute resources the most cost effectively.

In general, increase the size of and number of clusters for the warehouse to handle heavy workloads and multiple queries. Workloads are typically lighter after data sources are onboarded and policies are established in Immuta, so compute resources can be reduced after those workloads complete.

## Integration and data source registration warehouse use

The Snowflake integration uses warehouse compute resources to sync policies created in Immuta to the Snowflake objects registered as data sources and, if enabled, to run [identification](/2026.2/configuration/manage-data-metadata/data-discovery) and [schema monitoring](/2026.2/configuration/integrations/registering-metadata/data-sources/schema-monitoring/reference-guides/schema-monitoring). Follow the guidelines below to adjust the warehouse size and scale according to your needs.

* Increase the [size](https://docs.snowflake.com/en/user-guide/warehouses-tasks#resizing-a-warehouse) of and [number](https://docs.snowflake.com/en/user-guide/warehouses-multicluster#increasing-or-decreasing-clusters-for-a-multi-cluster-warehouse) of clusters for the warehouse during large policy syncs, updates, and changes.
* Enable [auto-suspend and auto-resume](https://docs.snowflake.com/en/user-guide/warehouses-overview#auto-suspension-and-auto-resumption) to optimize resource use in Snowflake. In the Snowflake UI, the lowest auto suspend time setting is 5 minutes. However, through SQL query, you can set `auto_suspend` to 61 seconds (since the minimum uptime for a warehouse is 60 seconds). For example,

  ```sql
  ALTER WAREHOUSE "WH_NAME" SET WAREHOUSE_SIZE = 'XSMALL' AUTO_SUSPEND = 61 AUTO_RESUME = TRUE MIN_CLUSTER_COUNT = 1 MAX_CLUSTER_COUNT = 2 SCALING_POLICY = 'STANDARD' COMMENT = '';
  ```
* Identification uses compute resources for each table it runs on. Consider [turning off autoscanning for your domains with identifiers and dynamic assignment](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/manage-sdd-tags#configure-a-domains-autoscanning-setting) when registering data sources if you have an [external catalog available](/2026.2/configuration/manage-data-metadata/catalogs/reference-guides/pre-configuration) or a tagging strategy in place.
* Register data before creating global policies. Immuta does not apply a subscription policy on registered data unless an existing global policy applies to it, which allows Immuta to only pull metadata instead of also applying policies when data sources are created. Registering data before policies are created reduces the workload and the Snowflake compute resources needed.
* Begin onboarding with a small dataset of tables, and then review and monitor query performance in the [Snowflake Query Monitor](https://docs.snowflake.com/en/user-guide/ui-snowsight-activity). Adjust the virtual warehouse accordingly to handle heavier loads.
* [Schema monitoring](/2026.2/configuration/integrations/registering-metadata/data-sources/schema-monitoring) uses the compute warehouse that was employed during the initial ingestion to periodically monitor the schema for changes. If you expect a low number of new tables or minimal changes to the table structure, consider scaling down the warehouse size.
* Resize the warehouse after data sources are registered and policies are established. For example,

{% code overflow="wrap" %}

```sql
ALTER WAREHOUSE "INTEGRATION_WH" SET WAREHOUSE_SIZE = 'XSMALL' AUTO_SUSPEND = 120 AUTO_RESUME = TRUE MIN_CLUSTER_COUNT = 1 MAX_CLUSTER_COUNT = 2 SCALING_POLICY = 'STANDARD'; 
```

{% endcode %}

For more details and guidance about warehouse sizing, see the [Snowflake Warehouse Considerations documentation](https://docs.snowflake.com/en/user-guide/warehouses-considerations).

## Identifying bulk jobs and heavy workloads

Even after your integration is configured, data sources are registered, and policies are established, changes to those data sources or policies may initiate heavy workloads. Follow the guidelines below to adjust your warehouse size and scale according to your needs.

* Review your [Snowflake query history](https://docs.snowflake.com/en/user-guide/ui-snowsight-activity) to identify query performance and bottlenecks.
* Check how many credits queries have consumed:

  ```sql
  SELECT h.* FROM "SNOWFLAKE"."ACCOUNT_USAGE"."QUERY_HISTORY" h
  INNER JOIN "SNOWFLAKE"."ACCOUNT_USAGE"."SESSIONS" s
  ON s.session_id = h.session_id
  WHERE GET(parse_json(s.client_environment), 'APPLICATION') = 'IMMUTA' limit 25;
  ```
* After reviewing query performance and cost, implement [strategies above](#integration-and-data-source-registration-warehouse-use) to adjust your warehouse.


# Starburst (Trino)

Learn about how you can register data from Starburst (Trino) and govern access to that data

This page describes the recommended workflow for setting up Immuta with Starburst (Trino). Following these steps connects your Starburst (Trino) environment, registers users, ingests metadata, and enables automated governance through global policies and access requests.

## Before you begin

To complete this workflow, ensure you have:

* Access to a Starburst (Trino) account and the permissions required to configure the connection
* Access to install a plugin on your Trino cluster
* Access to update the Starburst (Trino) `config.properties` file
* An Immuta application administrator who can register the connection

For the recommended implementation described on this page, you should also have:

* An enterprise identity provider
* Identified owners or stewards for your major data domains
* An understanding of the metadata maintained in your external catalog, if you use one

{% hint style="info" icon="lightbulb" %}
Completing this workflow typically requires coordination among an Immuta application administrator, a Starburst (Trino) administrator, an identity administrator, governance users, and data stewards.
{% endhint %}

{% stepper %}
{% step %}

## Connect your Starburst (Trino) environment

1. An application administrator will [register the Starburst (Trino) connection](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection) to allow Immuta to discover databases, schemas, and tables in Starburst (Trino). As object sync runs, Immuta creates corresponding data sources that can be governed through policies.
2. A Starburst (Trino) admin will [install the Immuta plugin and update the Starburst (Trino) `config.properties` file](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) to allow Immuta to apply policies to Starburst (Trino) securables.
3. After registering the connection, [organize your data into domains](/2026.2/configuration/domains/configure-domains). Domains assign ownership of data to the appropriate teams and determine who can manage policies, identification, and audit for those data sources.

Once your [data sources](/2026.2/configuration/integrations/registering-metadata/data-sources/data-source-overview) are registered in Immuta and organized into domains, you can apply policy to them.

{% hint style="info" icon="lightbulb" %}
Start by registering a select Starburst (Trino) business domain by [restricting the permissions of the Starburst (Trino) system account](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection#create-the-system-account-user). Once your implementation is established, you can onboard additional data sources using the same governance model.
{% endhint %}
{% endstep %}

{% step %}

## Register and map your users

1. [Connect your organization's identity provider](/2026.2/configuration/people/section-contents) and configure SSO so that users can authenticate with their existing credentials and be automatically registered in Immuta.
   1. If your identity provider supports SCIM, [enable provisioning to synchronize users, groups, and attributes](/2026.2/configuration/people/section-contents/reference-guides/scim-protocol). These attributes can then be used when authoring policies so access automatically changes as the user information in the IAM is synced with Immuta.
2. After your identity provider is configured, [map Starburst (Trino) user identities to Immuta users](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping). This ensures that policies written in Immuta are enforced for the correct users when they query data in Starburst (Trino).

Once your users are registered and mapped to their Starburst (Trino) identities, any policies that apply to data sources will be enforced for those users.

{% hint style="info" icon="lightbulb" %}
If your identity provider supports SCIM, synchronize the user attributes that you plan to reference in policies, such as `department`, `region`, or `employment type`. These attributes provide a strong foundation for reusable global policies.
{% endhint %}
{% endstep %}

{% step %}

## Add metadata to your data

Metadata allows you to author policies that automatically apply across your Starburst (Trino) environment instead of managing individual tables and columns.

1. If your organization already maintains metadata in an external catalog, [connect your external catalog](/2026.2/configuration/manage-data-metadata/catalogs/configure) so Immuta continuously synchronizes tags, classifications, and descriptions.
2. You can also [enable identification to automatically discover and tag sensitive data](/2026.2/configuration/manage-data-metadata/data-discovery/how-to-guides/enable-sdd). Identification is recommended for all deployments and is especially useful if you do not maintain an external catalog.

Once your data sources are tagged in Immuta, you can author global policies based on those tags. These policies can apply automatically as additional data sources are registered through object sync and tagged.
{% endstep %}

{% step %}

## Configure automated policies

Once users and metadata are available, begin authoring global policies that automatically protect your data.

1. [Create subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/how-to-guides/subscription-policy-tutorial) to automatically grant access to users who meet the required conditions. You can also use subscription policies to enforce organization-wide requirements, such as limiting access to users with specific attributes or training before access can be granted.
2. [Create data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/how-to-guides/data-policy-tutorial) to mask sensitive columns or filter rows based on metadata such as catalog or identification tags.

Author global policies using metadata and user attributes instead of individual Starburst (Trino) objects or users. This allows the same policies to automatically apply as new data is registered and users are synchronized into Immuta.

{% hint style="info" icon="lightbulb" %}
A common first policy is to mask sensitive data identified through identification or your external catalog. As new Starburst (Trino) tables are registered and tagged, the policy automatically protects those columns without additional configuration.
{% endhint %}
{% endstep %}

{% step %}

## Configure audit

After your data, users, and policies are configured, [configure audit to export governance activity](/2026.2/configuration/self-managed-deployment/configure/audit-best-practices).

Audit records provide visibility into user queries, policy evaluations, access requests, policy changes, and metadata updates, allowing your organization to monitor how data is accessed and governed across your Starburst (Trino) environment.
{% endstep %}
{% endstepper %}

## Next steps

**After completing this workflow, your Starburst (Trino) environment is ready for automated governance.** From here you can continue configuring advanced features, refining policies, and onboarding additional Starburst (Trino) data sources. See the [Starburst (Trino) integration reference guide](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide) for architecture details, platform behavior, and additional configuration options.


# Register a Starburst (Trino) Connection

Register your Trino data

## Requirements

**For Trino connections**

* Trino cluster

**For Starburst connections**

* A valid [Starburst Enterprise license](https://docs.starburst.io/latest/license-requirements.html).

## Permissions

The user registering the connection must have the permissions below.

* `APPLICATION_ADMIN` Immuta permission
* The Trino user must have the ability to
  * Create a new file in the Trino `etc` directory
  * Create a new Trino user and grant that new user permissions

## Create the system account user

In Trino, create a new system account user with the privileges listed below. Immuta uses this system account continuously to crawl the connection, maintain state between Immuta and Trino, and run identification.

* `SELECT` on all securables you want registered in Immuta as data sources

## Register a Starburst (Trino) connection

1. In Immuta, click **Data** and select **Connections** in the navigation menu.
2. Click the **+ Add Connection** button.
3. Select the **Trino** tile.
4. Enter the cluster connection information:
   1. **Display Name**: This is the name of your new connection. This name will be used in the API (`connectionKey`), in data source names from the host, and on the connections page. Avoid the use of periods (`.`) or restricted words in your connection name.
   2. **Hostname**: URL of your Trino cluster.
   3. **Port**: Port configured for Trino.
   4. **SSL Mode**: Use the dropdown to select the SSL mode to connect to the host.
      1. **Enabled**: Use this mode if you have `http-server.https.enabled=true` set in your Trino cluster's `config.properties` file.
      2. **Disabled**: Use this mode for plain, unencrypted connections (e.g., your URL starts with `http://`).
   5. **Certificate Validation**: Use the dropdown to select whether to require certificate validation to connect to the host.
      1. **Enabled**: Use this to ensure Immuta verifies that the server's certificate was issued by a trusted Certificate Authority (CA).
      2. **Disabled**: Use this setting if you are using a self-signed certificate to skip certificate validation for the connection.
5. Opt to configure an HTTP proxy for this connection by selecting **Enable** and entering the required details:
   * **Proxy Host**: Enter the full proxy URL.
   * **Proxy Port**: Enter the proxy port.
   * **Proxy Username**: Enter the username for the proxy connection.
   * **Proxy Password**: Enter the password for the proxy connection.
6. Select an authentication method from the dropdown menu and enter the authentication information for the [Immuta system account you created](#create-the-system-account-user).

<details>

<summary><strong>Username and Password</strong></summary>

Enter the username and password for the system account user.

</details>

<details>

<summary><strong>OAuth M2M (Client Secret)</strong></summary>

1. Fill out the **Client ID**. This is a combination of letters, numbers, or symbols, used as a public identifier. This is the subject of the generated token.
2. Fill out the **Authority URL** with the full URL of the identity provider. This is where the generated token is sent.
3. Enter the **Scope** (string). The scope limits the operations allowed in Trino by the access token. See the [OAuth 2.0 documentation](https://oauth.net/2/scope/) for details about scopes.
4. Enter the **Client Secret**. Immuta uses this secret to authenticate with the authorization server when it requests a token.

</details>

<details>

<summary><strong>OAuth M2M (Certificate)</strong></summary>

1. Fill out the **Client ID**. This is a combination of letters, numbers, or symbols, used as a public identifier. This is the subject of the generated token.
2. Fill out the **Authority URL** with the full URL of the identity provider. This is where the generated token is sent.
3. Enter the **Scope** (string). The scope limits the operations allowed in Trino by the access token. See the [OAuth 2.0 documentation](https://oauth.net/2/scope/) for details about scopes.
4. Enter the **Certificate Thumbprint**. This identifies the corresponding key to the token and is often abbreviated as `x5t` or is called `sub` (Subject).
5. Opt to fill out the **Resource** field with a URI of the resource where the requested token will be used.
6. Upload the **Private Key**, which is used to sign the authorization request.

</details>

7. Click **Next**.
8. Opt to **Enable Object Sync**, which will keep your connection objects up to date with your Starburst (Trino) environment.
   1. Select the **Start Time** for when the first object sync job will run each day.
   2. Select the **Run Frequency** to determine how frequently object sync will run each day.
   3. Opt to **Run Object Sync on Create** to create all the data objects for your connection. If you do not select this option, you must run object sync manually or wait for the scheduled object sync for your connection's data objects.
9. Click **Save connection**.
   1. If you are using **Starburst**, move on to the next step.
   2. If you are using open-source **Trino**, you must download the Immuta Trino plugin and add it to your Trino cluster.
      1. The Immuta Trino plugin version matches the version of the corresponding Trino releases. Navigate to the [Immuta GitHub repository](https://github.com/immuta/trino-artifacts/releases) for a list of supported Trino versions. Immuta follows [Starburst's release cycle](https://docs.starburst.io/latest/versions.html), but you can contact your Immuta representative for a specific Trino OSS release.
      2. Download the assets for the release that corresponds to your Trino version.
      3. Enable Immuta on your cluster:
         1. **Docker installations**
            1. Follow [Trino's documentation](https://trino.io/docs/current/installation/plugins.html#plugins-installation) to install the plugin archive on all nodes in your cluster.
            2. Create the Immuta access control configuration file in the Trino configuration directory: **`/etc/trino/immuta-access-control.properties`**.
         2. **Standalone installations**
            1. Follow [Trino's documentation](https://trino.io/docs/current/installation/plugins.html#plugins-installation) to install the plugin archive on all nodes in your cluster.
            2. Create the Immuta access control configuration file in the Trino configuration directory: **`<trino_install_directory>/etc/immuta-access-control.properties`**.
10. On the **Next Steps** page, copy the provided `immuta-access-control.properties` file. It is pre-populated with the required fields:
    1. `access-control.name`: Leave this as `immuta`.
    2. `immuta.endpoint`: This is your tenant URL. Use the value provided in the file.
    3. `immuta.apikey`: This is how Immuta applies policy to your users' queries. Use the value provided in the file.
    4. `immuta.user.admin`: This is your Trino system account user. To ensure tables can be properly ingested into Immuta, no Immuta policies will ever apply to this user. Use the value pre-populated in the file to match the username you initially used to create the connection.
11. Customize any other properties in the file. See the [Customize the Immuta Trino plugin page](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) for detailed descriptions of all the properties.
12. Once your file is customized, add it to your Trino cluster's `etc` folder.
13. Enable the Immuta access control plugin in your Trino cluster's **`config.properties`** file:

```
access-control.config-files=/etc/trino/immuta-access-control.properties
```

14. Ensure you have completed all the connection steps, and click **Finish**.


# Customize Read and Write Access Policies for Starburst (Trino)

Customize how read and write access policies will be enforced when authored

{% hint style="info" %}
**Private preview**: Write policies are available to select accounts. Contact your Immuta representative to enable this feature.
{% endhint %}

## Requirements

* Starburst (Trino) version 438 or newer
* Write policies for Starburst (Trino) enabled. Contact your Immuta representative to get this feature enabled on your account.

## Configuration options

In its default setting, the Starburst (Trino) integration's write access value controls the authorization of SQL operations that perform data modification (such as `INSERT`, `UPDATE`, `DELETE`, `MERGE`, and `TRUNCATE`). However, administrators can allow table modification operations (such as `ALTER` and `DROP` tables) to be authorized as write operations. Two locations allow administrators to specify how [read and write access policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types) are applied to data in Starburst (Trino). Select one or both of the options below to customize these settings. If the `access-control.properties` file is used, it may override the policies configured in the Immuta web service.

* [**Immuta web service**](#immuta-web-service-configuration): Configure write policies in the Immuta web service to allow all Starburst (Trino) clusters targeting that Immuta tenant to receive the same write policy configuration for data sources. This configuration will only affect tables or views registered as Immuta data sources.
* [**Starburst (Trino) cluster**](#starburst-cluster-configuration): Configure write policies using the [`access-control.properties` file](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) in Starburst or Trino to broadly customize access for Immuta users on a specific cluster. This configuration file takes precedence over write policies passed from the Immuta web service. Use this option if all Immuta users should have the same level of access to tables regardless of the write policy setting in the Immuta web service.

### Immuta web service configuration

Contact your Immuta representative to configure read and write access in the Immuta web service if all Starburst (Trino) data source operations should be affected identically across Starburst (Trino) clusters connected to your Immuta tenant. A configuration example is provided below.

#### Configuration example

The following example maps `WRITE` to `READ`, `WRITE` and `OWN` permissions and `READ` to just `READ`. Both `READ` and `WRITE` permissions should always include `READ`:

```yaml
accessGrantMapping:
  WRITE: ['READ', 'WRITE', 'OWN']
  READ: ['READ']
```

Given the above configuration, when a user gets write access to a Starburst (Trino) data source, they will have both data and table modification permissions on that data source. See the [Starburst (Trino) privileges section of the Subscription policy access types guide](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-starburst-trino-privileges) for details about these operations.

### Starburst cluster configuration

Configure the integration to allow read and write policies to apply to any data source (registered or unregistered in Immuta) on a Starburst cluster.

1. Create the Immuta access control configuration file in the Starburst configuration directory (**`/etc/starburst/immuta-access-control.properties`** for Docker installations or **`<starburst_install_directory>/etc/immuta-access-control.properties`** for standalone installations).
2. Modify one or both properties below to customize the behavior of read or write access policies for all users:

   * **`immuta.allowed.immuta.datasource.operations`**: This property governs objects (catalogs, schemas, tables, etc.) that are registered as data sources in Immuta. These permissions apply to all querying users except for administrators defined in `immuta.user.admin` (who get all permissions).
     * `READ`: Grants `SELECT` on tables or views; grants `SHOW` on tables, views, or columns
     * `WRITE`: Grants `INSERT`, `UPDATE`, `DELETE`, `MERGE`, or `TRUNCATE` on tables; grants `REFRESH` on materialized views.
     * `OWN`: Grants `ALTER` and `DROP` on tables; grants `SET` on comments and properties
   * **`immuta.allowed.non.immuta.datasource.operations`**: This property governs objects (catalogs, schemas, tables, etc.) that are not registered as data sources in Immuta. Use all or a combination of the following access values:
     * `READ`: Grants `SELECT` on tables or views; grants `SHOW` on tables, views, or columns
     * `WRITE`: Grants `INSERT`, `UPDATE`, `DELETE`, `MERGE`, or `TRUNCATE` on tables; grants `REFRESH` on materialized views.
     * `OWN`: Grants `ALTER` and `DROP` on tables; grants `SET` on comments and properties
     * `CREATE`: Grants `CREATE` on catalogs, schema, tables, and views. *This is the only property that can allow `CREATE` permissions, since `CREATE` is enforced on new objects that do not exist in Starburst or Immuta yet (such as a new table being created with `CREATE TABLE`).*

   For example, the following configuration allows `READ`, `WRITE`, and `OWN` operations to be authorized on data sources registered in Immuta and all operations are permitted on data that is not registered in Immuta:

   ```bash
   immuta.allowed.immuta.datasource.operations=READ,WRITE,OWN
   immuta.allowed.non.immuta.datasource.operations=READ,WRITE,CREATE,OWN
   ```
3. Enable the Immuta access control plugin in the Starburst cluster's configuration file (**`/etc/starburst/config.properties`** for Docker installations or **`<starburst_install_directory>/etc/config.properties`** for standalone installations). For example,

   ```conf
   access-control.config-files=/etc/starburst/immuta-access-control.properties
   ```

### Trino cluster configuration

1. Create the Immuta access control configuration file in the Trino configuration directory (**`/etc/trino/config.properties`** for Docker installations or **`<trino_install_directory>/etc/config.properties`** for standalone installations).
2. Modify one or both properties below to customize the behavior of read or write access policies for all users:

   * **`immuta.allowed.immuta.datasource.operations`**: This property governs objects (catalogs, schemas, tables, etc.) that are registered as data sources in Immuta. These permissions apply to all querying users except for administrators defined in `immuta.user.admin` (who get all permissions).
     * `READ`: Grants `SELECT` on tables or views; grants `SHOW` on tables, views, or columns
     * `WRITE`: Grants `INSERT`, `UPDATE`, `DELETE`, `MERGE`, or `TRUNCATE` on tables; grants `REFRESH` on materialized views.
     * `OWN`: Grants `ALTER` and `DROP` on tables; grants `SET` on comments and properties
   * **`immuta.allowed.non.immuta.datasource.operations`**: This property governs objects (catalogs, schemas, tables, etc.) that are not registered as data sources in Immuta. Use all or a combination of the following access values:
     * `READ`: Grants `SELECT` on tables or views; grants `SHOW` on tables, views, or columns
     * `WRITE`: Grants `INSERT`, `UPDATE`, `DELETE`, `MERGE`, or `TRUNCATE` on tables; grants `REFRESH` on materialized views.
     * `OWN`: Grants `ALTER` and `DROP` on tables; grants `SET` on comments and properties
     * `CREATE`: Grants `CREATE` on catalogs, schema, tables, and views. *This is the only property that can allow `CREATE` permissions, since `CREATE` is enforced on new objects that do not exist in Starburst or Immuta yet (such as a new table being created with `CREATE TABLE`).*

   For example, the following configuration allows `READ`, `WRITE`, and `OWN` operations to be authorized on data sources registered in Immuta and all operations are permitted on data that is not registered in Immuta:

   ```bash
   immuta.allowed.immuta.datasource.operations=READ,WRITE,OWN
   immuta.allowed.non.immuta.datasource.operations=READ,WRITE,CREATE,OWN
   ```
3. Enable the Immuta access control plugin in Trino's configuration file (**`/etc/trino/config.properties`** for Docker installations or **`<trino_install_directory>/etc/config.properties`** for standalone installations). For example,

   ```conf
   access-control.config-files=/etc/trino/immuta-access-control.properties
   ```


# Rotate the System API Key

Rotate the system API key to mitigate potential security risks

When you register the Trino connection, Immuta generates an API key for you to add to your Immuta access control properties file for API authentication between Starburst (Trino) and Immuta. You can rotate this shared secret to mitigate potential security risks and comply with your organizational policies.

**Required Immuta permission**: `APPLICATION_ADMIN`

{% hint style="warning" %}
**Cluster restart required**

To update your API key in Starburst (Trino), you must shut down your cluster, generate and update the API key, and then restart your cluster. If you do not shut down your cluster, generating a new API key using the endpoint below will cause downtime for your deployment.
{% endhint %}

1. [Disable your Starburst (Trino) cluster](https://docs.starburst.io/starburst-galaxy/cluster-administration/create-edit-and-delete-galaxy-clusters.html#cluster-disable).
2. Navigate to the Trino connection in Immuta.
3. Scroll to the **Policy settings** section, and select **Edit**.
4. Click **Regenerate system API key**. The old API key will be invalidated immediately.
5. Copy the new `immuta.apikey`. Store it in a secure place; the API key will not be shown again.
6. Click **Finish**.
7. [Replace the old `immuta.apikey` value in the Immuta access control properties file](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) with this new key.
8. [Enable your Starburst (Trino) cluster](https://docs.starburst.io/starburst-galaxy/cluster-administration/create-edit-and-delete-galaxy-clusters.html#enable-a-cluster).


# Remove a Trino Connection

Delete your Trino connection

To delete the host,

1. Click **Data** in the navigation menu and select **Connections**.
2. Click the **overflow menu** in the Actions column and select **Delete Connection**.
3. Click **Delete Host** again to confirm.
4. Navigate to Trino and delete the `immuta-access-control.properties` file and Immuta plugin.


# Manage Trino Connection Settings

Manage Trino integration and connection settings

## Run object sync <a href="#run-object-sync" id="run-object-sync"></a>

1. Navigate to the connection or connection-backed object.
2. Click **Run Object Sync**.

## Edit the connection details <a href="#edit-the-connection-details" id="edit-the-connection-details"></a>

1. Click the **Edit** button in the Connection details box.
2. Edit the field you want:
   1. **Hostname**
   2. **Port**
   3. **SSL Mode**
   4. **Certificate Validation**
   5. **HTTP Proxy**
   6. **Authentication Method**: If you are editing the authentication method to be a different system account user, [grant the new system user the required permissions](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection#create-the-system-account-user).
3. Select **Validate**, and once the validation is successful, select **Save**.

## Edit the object sync settings <a href="#edit-the-object-sync-settings" id="edit-the-object-sync-settings"></a>

1. Click the **Edit** button in the Object Sync settings box.
2. Opt to enable or disable object sync.
3. Opt to update the **Start Time** and **Run Frequency** from the dropdown menus.
4. Opt for all data objects to be scanned despite the policy sync setting using the checkbox.
5. Click **Save**.

## Edit the object settings <a href="#edit-the-object-settings" id="edit-the-object-settings"></a>

1. Click the **Edit** button in the Object settings box.
2. Opt to enable or disable **Policy Synchronization**: When policy sync is enabled, all child objects will be represented by Immuta data sources and policies will be applied to the data sources.
3. Opt to **Add Users and Groups** as data owners:
   1. Start typing in the text box and select the user or group from the dropdown.
   2. Click **Add Owners**.
4. Click **Save**.


# Customize the Immuta Trino Plugin

Learn about the available Trino plugin properties so that you can customize your Trino integration

When you register a connection, there is a provided `immuta-access-control.properties` file pre-populated with the required properties. You can also add these additional properties to further customize your connection.

## `immuta-access-control.properties`

{% hint style="warning" %}
Starburst does not support using Starburst built-in access control (BIAC) concurrently with any other access control providers such as Immuta. If Starburst BIAC is in use, it must be disabled to allow Immuta to enforce policies on cluster.
{% endhint %}

{% hint style="info" %}
**Default configuration property values**

If you use the default property values in the configuration file described in this section,

* you will **give users read and write access to tables that are not data sources in Immuta** and
* results for `SHOW` queries will not be filtered on table metadata.

These default settings help ensure that a new Starburst connection is minimally disruptive for existing Starburst deployments, allowing you to then create Immuta data sources and update configuration to enforce more controls as you see fit.

However, the **`access-control.config-files`** property can be configured to allow Immuta to work with existing Starburst installations that have already configured an access control provider. For example, if the Starburst integration is configured to allow users write access to tables that are not protected by Immuta, you can still lock down write access for specific non-Immuta tables using an additional access control provider.
{% endhint %}

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Property</th><th>Trino version</th><th>Required or optional</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>access-control.name</code></strong></td><td>392 and newer</td><td>Required</td><td>This property enables the integration.</td></tr><tr><td><strong><code>access-control.config-files</code></strong></td><td>392 and newer</td><td>Optional</td><td>Trino allows you to enable multiple system access control providers at the same time. To do so, add providers to this property as comma-separated values. This approach allows Immuta to work with existing Trino installations that have already configured an access control provider. Immuta does not manage all permissions in Trino and will default to allowing access to anything Immuta does not manage so that the Starburst (Trino) integration complements existing controls. For example, if the Starburst (Trino) integration is configured to allow users write access to tables that are not protected by Immuta, you can still lock down write access for specific non-Immuta tables using an additional access control provider.</td></tr><tr><td><strong><code>immuta.allowed.immuta.datasource.operations</code></strong></td><td>413 and newer</td><td>Optional</td><td>This property defines a comma-separated list of allowed operations for Starburst (Trino) users on tables registered as Immuta data sources: <code>READ</code>,<code>WRITE</code>, and <code>OWN</code>. (See the <a href="/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/write-access-mapping">Customize read and write access policies for Starburst (Trino) guide</a> for details about the <code>OWN</code> operation.) When set to <code>WRITE</code>, all querying users are allowed read and write operations to data source schemas and tables. By default, this property is set to <code>READ</code>, which blocks write operations on data source tables and schemas. <em>If</em> <a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types"><em>write policies</em></a> <em>are enabled for your Immuta tenant, this property is set to <code>READ,WRITE</code> by default, so users are allowed read and write operations to data source schemas and tables.</em></td></tr><tr><td><strong><code>immuta.allowed.non.immuta.datasource.operations</code></strong></td><td>392 and newer</td><td>Optional</td><td>This property defines a comma-separated list of allowed operations users will have on tables not registered as Immuta data sources: <code>READ</code>, <code>WRITE</code>, <code>CREATE</code>, and <code>OWN</code>. (See the <a href="/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/write-access-mapping">Customize read and write access policies for Starburst (Trino) guide</a> for details about <code>CREATE</code> and <code>OWN</code> operations.) When set to <code>READ</code>, users are allowed read operations on tables not registered as Immuta data sources. When set to <code>WRITE</code>, users are allowed read and write operations on tables not registered as Immuta data sources. If this property is left empty, users will not get access to any tables outside Immuta. By default, this property is set to <code>READ,WRITE</code>. <em>If</em> <a href="/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types"><em>write policies</em></a> <em>are enabled for your Immuta tenant, this property is set to <code>READ,WRITE,OWN,CREATE</code> by default.</em></td></tr><tr><td><strong><code>immuta.apikey</code></strong></td><td>392 and newer</td><td>Required</td><td>This should be set to the Immuta API key displayed when <a href="/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection">registering the connection</a>. To rotate this API key, <a href="/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/rotate-the-system-api-key">follow these instructions</a> to generate a new API key, and then replace the existing <code>immuta.apikey</code> value with the new one.</td></tr><tr><td><strong><code>immuta.audit.legacy.enabled</code></strong></td><td>435 and newer</td><td>Optional</td><td>This property allows you to turn off Starburst (Trino) audit. Must set both <code>immuta.audit.legacy.enabled</code> and <code>immuta.audit.uam.enabled</code> to <code>false</code> to fully disable query audit.</td></tr><tr><td><strong><code>immuta.audit.uam.enabled</code></strong></td><td>435 and newer</td><td>Optional</td><td>This property allows you to turn off Starburst (Trino) audit. Must set both <code>immuta.audit.legacy.enabled</code> and <code>immuta.audit.uam.enabled</code> to <code>false</code> to fully disable query audit.</td></tr><tr><td><strong><code>immuta.ca-file</code></strong></td><td>392 and newer</td><td>Optional</td><td>This property allows you to specify a path to your CA file.</td></tr><tr><td><strong><code>immuta.cache.views.seconds</code></strong></td><td>392 and newer</td><td>Optional</td><td>Amount of time in seconds for which a user's specific representation of an Immuta data source will be cached for. Changing this will impact how quickly policy changes are reflected for users actively querying Trino. By default, cache expires after 30 seconds.</td></tr><tr><td><strong><code>immuta.cache.datasources.seconds</code></strong></td><td>392 and newer</td><td>Optional</td><td>Amount of time in seconds for which a user's available Immuta data sources will be cached for. Changing this will impact how quickly data sources will be available due to changing projects or subscriptions. By default, cache expires after 30 seconds.</td></tr><tr><td><strong><code>immuta.endpoint</code></strong></td><td>392 and newer</td><td>Required</td><td>The protocol and fully qualified domain name (FQDN) for the Immuta tenant used by Trino (for example, <code>https://my.immuta.tenant.io</code>). This should be set to the endpoint displayed when <a href="/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection">registering the connection</a>.</td></tr><tr><td><strong><code>immuta.filter.unallowed.table.metadata</code></strong></td><td>392 and newer</td><td>Optional</td><td>When set to false, Immuta won't filter unallowed table metadata, which helps ensure Immuta remains noninvasive and performant. If this property is set to true, running <code>show catalogs</code>, for example, will reflect what that user has access to instead of returning all catalogs. By default, this property is set to false.</td></tr><tr><td><strong><code>immuta.http.timeout.milliseconds</code></strong></td><td>464 and newer</td><td>Optional</td><td>The timeout for all HTTP calls made to Immuta in milliseconds. Defaults to <code>30000</code> (30 seconds).</td></tr><tr><td><strong><code>immuta.user.admin</code></strong></td><td>392 and newer</td><td>Required</td><td>This property identifies the Trino user who is an Immuta administrator (for example, <code>immuta.user.admin=immuta_system_account</code>). This user will not have Immuta policies applied to them because this account will run the subqueries. This should be the Starburst user provided when registering the connection. Note that you must escape regex special characters (for example, <code>john\\.doe+svcacct@immuta\\.com</code>).</td></tr></tbody></table>

### Example Immuta system access control file <a href="#example-immuta-system-access-control-file" id="example-immuta-system-access-control-file"></a>

The example configuration snippet below uses the default configuration settings for `immuta.allowed.immuta.datasource.operations` and `immuta.allowed.non.immuta.datasource.operations`, which allow read access for data registered as Immuta data sources and read and write access on data that is not registered in Immuta. See the [Granting Starburst (Trino) privileges section](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-starburst-trino-privileges) for details about customizing and enforcing read and write access controls in Starburst.

```conf
# Enable the Immuta System Access Control implementation.
access-control.name=immuta

# The Immuta endpoint that was displayed when registering the Trino connection in Immuta.
immuta.endpoint=http://service.immuta.com:3000

# The Immuta API key that was displayed when registering the Trino in Immuta.
immuta.apikey=45jdljfkoe82b13eccfb9c

# The administrator user regex. Trino usernames matching this regex will not be subject to
# Immuta policies. This regex should match the user name provided at Immuta data source
# registration.
immuta.user.admin=immuta_system_account

# Optional argument (default is shown).
# A CSV list of operations allowed on schemas/tables registered as Immuta data sources.
immuta.allowed.immuta.datasource.operations=READ

# Optional argument (default is shown).
# A CSV list of operations allowed on schemas/tables not registered as Immuta data sources.
# Set to empty to allow no operations on non-Immuta data sources.
immuta.allowed.non.immuta.datasource.operations=READ,WRITE

# Optional argument (default is shown).
# Controls table metadata filtering for inaccessible tables.
#   - When this property is enabled and non-Immuta reads are also enabled, a user performing
#     'show catalogs/schemas/tables' will not see metadata for a table that is registered as
#     an Immuta data source but the user does not have access to through Immuta.
#   - When this property is enabled and non-Immuta reads and writes are disabled, a user
#     performing 'show catalogs/schemas/tables' will only see metadata for tables that the
#     user has access to through Immuta.
#   - When this property is disabled, a user performing 'show catalogs/schemas/tables' can see
#     all metadata.
immuta.filter.unallowed.table.metadata=false
```


# Trino Integration Reference Guide

Learn about how the Trino integration works and what Immuta creates in your environment to administer Trino access controls directly on objects in Trino

Using the Trino connection, you can register a Trino integration for your open-source Trino or Starburst Enterprise cluster.

The sequence diagram below outlines the events that occur when an Immuta user queries a Trino table that has been registered as an Immuta data source.

<figure><img src="https://231393832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6t660m9uhCtqfzQU5bjY%2Fuploads%2Fmfqr7Tdwm7KxgoJMNQ6D%2Fimage.png?alt=media&amp;token=151f3508-6b0d-4fe6-83a9-d4f76a4cf610" alt=""><figcaption></figcaption></figure>

## What does Immuta do in my Trino cluster?

### Registering a connection <a href="#registering-a-connection" id="registering-a-connection"></a>

Immuta utilizes [connections](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) to register and manage data from your entire Trino cluster all at once. This approach simplifies data registration and allows Immuta to automatically monitor your Trino platform for changes. Data sources are then added or removed to reflect the current state of your data platform.

When a [connection is first registered](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection), Immuta will complete or ask your application admin to complete a few actions:

* The application admin must provide **credentials** that Immuta will use to initially register all of your Trino tables as data objects. Immuta will also continue to use those credentials for scheduled [object syncs](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide#object-sync) and [identification](/2026.2/configuration/manage-data-metadata/data-discovery).
* The application admin will also [**install the Immuta Trino plugin on your Trino cluster**](#user-content-fn-1)[^1] and update your Trino cluster's `config.properties` file to use the Immuta Trino plugin for access control. Immuta will use the Immuta Trino plugin to [apply policies](#applying-policies) to user queries and provide [query audit](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/security-and-compliance-in-trino#auditing-and-compliance) events.
* Immuta ingests and stores connection metadata in the Immuta metadata database.

Immuta presents a hierarchical view of your data that reflects the hierarchy of objects in Trino after registration is complete:

* Cluster
* Catalog
* Schema
* Tables

Beyond making the registration of your data more intuitive, connections provide more control. Instead of performing operations on individual schemas or tables, you can perform operations (such as object sync) at the connection level.

See the [Connections reference guide](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide) for details about connections and how to manage them. To configure your Trino connection, see the [Register a Trino connection guide](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection).

### Applying policies

By default, the Trino integration is designed to be minimally invasive: if a catalog is not registered as an Immuta data source, users will still have access to it in Trino.

However, this limited enforcement can be changed in the [configuration file](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) provided by Immuta. Additionally, you can continue to use Trino's file-based access control provider or [Trino's built-in access control system](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/security-and-compliance-in-trino#identity-providers-for-user-authentication) on catalogs that are not protected or controlled by Immuta.

#### Subscription policies

Immuta enforces read and write [subscription policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-policies) on Trino tables by checking the user's access at query time and resulting in the appropriate access. The [Protecting data in Trino page](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/protecting-data-in-trino) shows an example of this policy enforcement.

Once the connection is registered, this is what happens when a user makes a query in Trino:

1. User runs a query for a Trino table registered in Immuta.
2. Trino checks with the Immuta Trino plugin in charge of access control to see if the user should see the table.
3. The Immuta Trino plugin reaches out to the Immuta API to confirm table access.
4. The query results are returned to the data consumer. If the user is not subscribed to the data source, it will result in `ACCESS_DENIED`.

#### Data policies

You can author [data policies](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) in Immuta to enforce fine-grained access controls on Trino data objects registered as Immuta data sources. The [Protecting data in Trino page](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/protecting-data-in-trino) shows an example of this policy enforcement.

Once a data policy is applied to a Trino data source in Immuta,

1. A Trino user, who is subscribed to the data source in Immuta, [queries the corresponding table](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/accessing-data-in-trino) directly in their Trino catalog.
2. The Trino execution engine calls various methods on the interface to ask the Immuta Trino plugin where the policies should be applied. The masking and row-level security methods apply the actual policy expressions.
3. The Immuta Trino plugin calls the Immuta API to retrieve policy information for that data source for the querying user, using the querying user's project, purpose, and entitlements.
   1. For each column, the Immuta Trino plugin requests a SQL view expression. If there are no masking policies on the column, nothing is returned.
   2. For each table, the Immuta Trino plugin requests the rows the user is allowed to see. If there is a row-level policy on the table, the Immuta API returns a corresponding view expression as a WHERE clause. If there are no row-level policies on the table, nothing is returned.
4. The Immuta Trino plugin provides the returned SQL view expression (for masked columns) or WHERE clause SQL view expression (for row filtering) to the Trino execution engine.
5. The Trino execution engine constructs and executes the SQL statement on the backing catalogs and retrieves the data with appropriate policy enforcement.
6. Data consumer sees policy-enforced data in their query result.

See the [Data policies reference page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies) for a matrix on the data policies supported for this integration.

#### Trino privileges granted by Immuta

See the [Subscription policy access types page](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-starburst-trino-privileges) for details about the Trino privileges granted to users when they are subscribed to a data source protected by a subscription policy.

#### Trino query passthrough blocked <a href="#starburst-trino-query-passthrough" id="starburst-trino-query-passthrough"></a>

Trino's query passthrough is available in most connectors using the `query` table function or `raw_query` in the Elasticsearch connector. Consequently, Immuta blocks functions named `raw_query` or `query`, as those table functions would completely bypass Immuta’s access controls.

For example, without blocking those functions, this query would access the `public.customer` table directly:

`select * from table(postgres.system.query(query => 'select * from public.customer limit 10'));`

You can add or remove functions that are blocked by Immuta in the Trino configuration file. See the [Customize the Immuta Trino plugin page](/2026.2/configuration/integrations/starburst-trino/register-a-trino-connection/customize-the-immuta-trino-plugin) for details.

### Required Trino privileges

The privileges that the Trino connection requires align to the least privilege security principle. The table below describes the privilege required by the [`IMMUTA_SYSTEM_ACCOUNT`](#user-content-fn-2)[^2] user.

| Trino privilege        | User requiring the privilege | Explanation                                                                                |
| ---------------------- | ---------------------------- | ------------------------------------------------------------------------------------------ |
| `SELECT` on all tables | Immuta system account        | This privilege provides access to all the Trino tables that you want registered in Immuta. |

### Maintaining state with Trino

The following user actions spur various processes in the Trino connection so that Immuta data remains synchronous with data in Trino. The list below provides an overview of each process:

* **Data source created or updated**: Immuta registers data source metadata and stores that metadata in the Immuta metadata database.
* **Data source deleted**: Immuta deletes the data source metadata from the metadata database.
* ​[**User account is mapped to Immuta**](#user-registration-and-id-mapping): When a user account is mapped to Immuta, their metadata is stored in the metadata database.

## Supported object types <a href="#supported-object-types" id="supported-object-types"></a>

| Object type       | Subscription policy support | Data policy support  | Request app support  |
| ----------------- | --------------------------- | -------------------- | -------------------- |
| Table             | :white\_check\_mark:        | :white\_check\_mark: | :white\_check\_mark: |
| View              | :white\_check\_mark:        | :white\_check\_mark: | :white\_check\_mark: |
| Materialized view | :white\_check\_mark:        | :white\_check\_mark: | :white\_check\_mark: |

### Trino-created logical view support <a href="#starburst-trino-created-logical-view-support" id="starburst-trino-created-logical-view-support"></a>

Immuta policies can be applied to [Trino-created logical views](https://docs.starburst.io/latest/sql/create-view.html#description).

The descriptions below provide guidance for applying policies to Trino-created logical views in two modes:

* [`DEFINER` security mode](#views-created-in-the-definer-security-mode)
* [`INVOKER` security mode](#views-created-in-the-invoker-security-mode)

However, there are other approaches you can use to apply policies to Trino-created logical views. The examples below are the simplest approaches.

<details>

<summary><strong>Views created in the <code>DEFINER</code> security mode</strong></summary>

For views created using the `DEFINER` security mode, follow the recommendations below:

* Ensure the user who created the view is configured as the admin user in the Immuta plugin so that policies are never applied to the underlying tables.
* Create Immuta data sources and apply policies to logical views exposing those tables.
* Lock down access to the underlying tables in Trino so that all end user access is provided through the views.

</details>

<details>

<summary><strong>Views created in the <code>INVOKER</code> security mode</strong></summary>

{% hint style="info" %}
Avoid creating data policies for both a logical view and its underlying tables. Instead, apply policies to the logical view **or** the underlying tables.
{% endhint %}

For views created using the `INVOKER` security mode, the querying user needs access to the logical view and underlying tables.

* If **non-Immuta table reads are disabled**, provide access to the views and tables through Immuta. To do so, create Immuta data sources for the view and underlying tables, and grant access to the querying user in Immuta. If creating data policies, apply the policies to either the view or underlying tables, not both.
* If **non-Immuta table reads are enabled**, the user already has access to the table and view. Create Immuta data sources and apply policies to the underlying table; this approach will enforce access controls for both the table and view in Trino.

</details>

### Object sync

Supported object types are found by object sync and automatically kept up to date. The performance of object sync is dependent on how quickly Trino can pull information from the underlying systems. This can impact the time object sync takes to complete.

For more details about object sync, see the [Connections reference guide](/2026.2/configuration/integrations/registering-metadata/connections/reference-guides/connections-reference-guide).

### Supported policies

The Trino integration allows users to author subscription and data policies to enforce access controls. See the corresponding pages for details about specific types of policies supported:

* [Subscription policy access types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/section-contents/reference-guides/subscription-access-types#granting-starburst-trino-privileges)
* [Data policy types](/2026.2/governance/author-policies-for-data-access-control/authoring-policies-in-secure/data-policies/reference-guides/data-policies#data-policy-support-matrix)

## Security and compliance <a href="#security-and-compliance" id="security-and-compliance"></a>

See the [Security and compliance in Trino guide](/2026.2/configuration/integrations/starburst-trino/trino-integration-reference-guide/security-and-compliance-in-trino) for details about security, supported authentication methods, and audit.

## User registration and ID mapping <a href="#user-registration-and-id-mapping" id="user-registration-and-id-mapping"></a>

The built-in Immuta IAM can be used as a complete solution for authentication and user entitlement. However, you can connect your existing identity management provider to Immuta to use that system for authentication and user entitlement instead. Each of the [supported IAM protocols](/2026.2/releases/support-matrix#iam-providers) includes a set of configuration options that enable Immuta to communicate with the IAM system and map the users, permissions, groups, and attributes into Immuta.

For policies to impact the right users, the user account in Immuta must be mapped to the user account in Trino. You can ensure these accounts are mapped correctly in the following ways:

* [Automatically](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#configure-external-user-id-mapping-on-app-settings-page): If usernames in Trino align with usernames in the external IAM and those accounts align with an IAM attribute, you can enter that IAM attribute on the app settings page to automatically map user IDs in Immuta to Trino.
* [Manually](/2026.2/configuration/people/immuta-users/how-to-guides/external-user-mapping#manually-configure-external-user-id-mapping-on-a-users-page): You can manually map user IDs for individual users.

For guidance on connecting your IAM to Immuta, see the [how-to guide for your protocol](/2026.2/configuration/people/section-contents).

## Limitations and caveats

* Tag ingestion is not supported.
* Object sync may be delayed due to delays in Trino and the underlying data platforms.
* **Limit your masked joins to columns with matching column types**: Trino truncates the result of the masking expression to conform to the column type when performing the join, so joining two masked columns with different data types produces invalid results when one of the columns' lengths is less than the length of the masked value.

  For example, if the value of a hashed column is 64 characters, joining a hashed varchar(50) and a hashed varchar(255) column will not be joined correctly, since the varchar(50) value is truncated and doesn’t match the varchar(255) value.

[^1]: The Immuta Trino plugin comes pre-installed on Starburst clusters.

[^2]: This user account is used by Immuta to manage the connection once it has been set up.




---

[Next Page](https://documentation.immuta.com/2026.2/llms-full.txt/1)

