> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnao.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> Per-user identity passthrough to your warehouse and row-level security on Redshift

nao Enterprise can pass each end user's identity through to the warehouse, so queries run **as the user asking them** instead of as a single shared service account. This unlocks native row-level security (RLS) policies you've already configured on the warehouse - the agent inherits those policies automatically, with no nao-side rule duplication.

Today this is supported on **Amazon Redshift via Microsoft Entra ID**. Other warehouses can be added on request.

## Why per-user identity matters

When nao runs queries with one shared connection, every user sees the same rows: the warehouse can't tell them apart. That's fine for analytics agents inside a small team, but it doesn't fit organizations that already enforce RLS or column-level security at the warehouse layer (sales reps see only their accounts, finance sees only their region, etc.).

With per-user identity:

* Each chat message is executed against the warehouse using the asking user's access token.
* Redshift identifies the user and applies whatever native policies you've defined (RLS, column masking, role-based grants).
* nao does not need a parallel rules system - the warehouse stays the source of truth for who can see what.

## Redshift row-level security via Entra ID

Use this when your Redshift cluster is configured to authenticate end users via Microsoft Entra ID (federated single sign-on).

### Prerequisites

* Microsoft SSO is configured for your nao deployment (see [Authentication](/nao-agent/enterprise/authentication#microsoft-sso-azure-ad--entra-id)).
* Your Redshift cluster is set up with [Microsoft Entra ID federation](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect-azure-ad.html) and your Azure app registration includes the Redshift scope.
* Your RLS policies are already defined on the Redshift side (Redshift's native [row-level security](https://docs.aws.amazon.com/redshift/latest/dg/t_rls.html) feature).

### Configure the connection

In `nao_config.yaml`, set `auth_mode: azure_entra_id` on the Redshift database:

```yaml theme={null}
databases:
  - name: redshift_prod
    type: redshift
    host: your-cluster.region.redshift.amazonaws.com
    port: 5439
    database: analytics
    auth_mode: azure_entra_id
    user: "{{ env('REDSHIFT_USER') }}"          # optional, sync-only
    password: "{{ env('REDSHIFT_PASSWORD') }}"  # optional, sync-only
    schema_name: public
```

Two auth modes are available:

* `password` (default) - traditional service-account auth. All queries run as the same Redshift user.
* `azure_entra_id` - per-user identity. Sync-time queries (metadata, previews, query history) use the optional `user`/`password` if provided. Runtime queries from the chat agent **always** flow through the end user's Azure access token.

### How it works

1. The user signs in to nao with Microsoft SSO (Entra ID).
2. nao stores the user's encrypted refresh token.
3. When the agent runs a query, nao silently exchanges the refresh token for an Azure access token scoped to your Redshift API.
4. The query is sent to Redshift over the IAM-federated connection with that token.
5. Redshift identifies the user and enforces its native RLS policies.

If a user does not have access to a given row or table, Redshift returns the same response it would return for any other client - the agent surfaces the result as-is.

### Verifying it works

1. Sign in as a user with restricted access.
2. Ask the agent a question that should hit RLS-protected data.
3. The query result should reflect the user's policy. Cross-check with the same query run directly against Redshift as that user.
4. Sign in as a user with broader access and confirm the result set widens accordingly.

<Info>
  The sync-time `user`/`password` credentials in `azure_entra_id` mode are never used at runtime - they only exist so `nao sync` can read schema metadata and query history. If your security policy forbids any service-account access, leave them unset and provide warehouse metadata through another sync source.
</Info>

## Other warehouses

BigQuery, Snowflake, Databricks, and other warehouses also support identity-federated auth. We add per-user identity passthrough on request as we see customer demand. Email [claire@getnao.io](mailto:claire@getnao.io) with your warehouse + identity-provider combination and we'll scope it for your deployment.
