Skip to content

Redshift Permissions

Qualytics calls Amazon Redshift through the Redshift JDBC driver (PostgreSQL-compatible) in one of two modes: Password (JDBC with a database user and password) or IAM Role (JDBC plus AWS STS AssumeRole, where the driver obtains short-lived database credentials from AWS). The identity behind the connection must hold permissions at two layers: database-level grants inside Redshift, and (for the IAM Role mode only) AWS IAM permissions on the target role.

Which identity carries those permissions depends on the authentication mode:

Authentication mode Identity that carries the permissions
Password The Redshift database user behind the username and password.
IAM Role The target role (the role ARN entered in the connection form) carries the AWS IAM permissions. The JDBC driver uses temporary database credentials issued by redshift:GetClusterCredentials (provisioned) or redshift-serverless:GetCredentials (Serverless). The dataplane identity only needs sts:AssumeRole against that target role. See IAM Role Authentication.

Where IAM Role is available

IAM Role authentication is offered only on AWS-hosted and local Qualytics deployments. On Azure and GCP deployments, only Password authentication is available, and the AWS IAM section below does not apply.

System schemas are filtered automatically

Qualytics filters the system schemas pg_catalog, pg_toast, pg_internal, and information_schema out of the schema picker. You do not need to restrict the connection user from those schemas manually, and you do not need to grant access to them.

Database-Level Permissions

These grants live inside Redshift and are required in both authentication modes. With Password, you grant them to the database user. With IAM Role, you grant them to the database user that the role maps to (typically the user named after the role, or one resolved via db_groups and group-based mappings).

Source Datastore (Read-Only)

A read-only user lets Qualytics discover, profile, and scan tables in the schema. It cannot write anywhere.

Permission Purpose
USAGE ON SCHEMA <schema_name> Access objects within the target schema
SELECT ON ALL TABLES IN SCHEMA <schema_name> Read data from all tables for profiling and scanning

Example: create a dedicated read-only user. Replace <schema_name> and <password> with your actual values.

-- Create a dedicated read-only user
CREATE USER qualytics_read PASSWORD '<password>';

-- Grant schema access and read permissions
GRANT USAGE ON SCHEMA <schema_name> TO qualytics_read;
GRANT SELECT ON ALL TABLES IN SCHEMA <schema_name> TO qualytics_read;

-- Grant read access to future tables automatically
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema_name>
    GRANT SELECT ON TABLES TO qualytics_read;

The ALTER DEFAULT PRIVILEGES line ensures the user keeps SELECT on tables that are created in the schema after the initial grant. Without it, you would have to re-grant after every new table.

Enrichment Datastore (Read-Write)

When you also use Redshift as an enrichment datastore, the enrichment user needs the source grants above plus write and lifecycle permissions, because Qualytics creates, updates, and deletes the _qualytics_* metadata tables it produces.

Permission Purpose
CREATE ON SCHEMA <schema_name> Create enrichment tables (_qualytics_*)
INSERT ON ALL TABLES IN SCHEMA <schema_name> Write anomaly records, scan results, and check metrics
UPDATE ON ALL TABLES IN SCHEMA <schema_name> Update enrichment records during rescans
DELETE ON ALL TABLES IN SCHEMA <schema_name> Remove stale enrichment records
ALTER TABLE Modify enrichment table schemas during version migrations (inherited via table ownership)
DROP TABLE Remove enrichment tables during cleanup (inherited via table ownership)

Example: create a dedicated read-write user.

-- Create a dedicated read-write user
CREATE USER qualytics_readwrite PASSWORD '<password>';

-- Grant schema access, table creation, and data manipulation
GRANT USAGE, CREATE ON SCHEMA <schema_name> TO qualytics_readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE
    ON ALL TABLES IN SCHEMA <schema_name>
    TO qualytics_readwrite;

-- Grant full access to future tables automatically
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema_name>
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES
    TO qualytics_readwrite;

ALTER TABLE and DROP TABLE come from ownership

ALTER DEFAULT PRIVILEGES covers SELECT, INSERT, UPDATE, and DELETE, but ALTER TABLE and DROP TABLE cannot be granted that way in Redshift. Qualytics gets them automatically because the enrichment user is the owner of every _qualytics_* table it creates, and Redshift gives owners full control over their objects. Use a separate user for enrichment so that source and enrichment privileges stay isolated.

AWS IAM Permissions (IAM Role mode only)

These permissions are required only when the connection's authentication type is IAM Role. They are attached to the target role (the role ARN you enter in the connection form), and they let the JDBC driver call AWS to exchange the assumed-role session for short-lived Redshift database credentials.

If your connection uses Password authentication, skip this section. Database-level grants are all you need.

Provisioned Redshift

The target role needs the two AWS actions below.

Permission Resource Purpose
redshift:GetClusterCredentials arn:aws:redshift:<region>:<account>:dbuser:<cluster-id>/<db-user> and arn:aws:redshift:<region>:<account>:dbname:<cluster-id>/<db-name> Issue short-lived database credentials for the configured user and database
redshift:DescribeClusters arn:aws:redshift:<region>:<account>:cluster:<cluster-id> Resolve cluster endpoint metadata at connection time

Example AWS IAM policy. Replace <region>, <account>, <cluster-id>, <db-user>, and <db-name> with your actual values.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RedshiftGetCredentials",
      "Effect": "Allow",
      "Action": "redshift:GetClusterCredentials",
      "Resource": [
        "arn:aws:redshift:<region>:<account>:dbuser:<cluster-id>/<db-user>",
        "arn:aws:redshift:<region>:<account>:dbname:<cluster-id>/<db-name>"
      ]
    },
    {
      "Sid": "RedshiftDescribeCluster",
      "Effect": "Allow",
      "Action": "redshift:DescribeClusters",
      "Resource": "arn:aws:redshift:<region>:<account>:cluster:<cluster-id>"
    }
  ]
}

Redshift Serverless

For Redshift Serverless workgroups, the target role needs a single action against the workgroup ARN.

Permission Resource Purpose
redshift-serverless:GetCredentials arn:aws:redshift-serverless:<region>:<account>:workgroup/<workgroup-id> Issue short-lived database credentials for the workgroup

Example AWS IAM policy. Replace <region>, <account>, and <workgroup-id> with your actual values.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RedshiftServerlessGetCredentials",
      "Effect": "Allow",
      "Action": "redshift-serverless:GetCredentials",
      "Resource": "arn:aws:redshift-serverless:<region>:<account>:workgroup/<workgroup-id>"
    }
  ]
}

Where to find the cluster endpoint

The Host field in the connection form takes the canonical Redshift endpoint, in one of two formats depending on whether you are connecting to a provisioned cluster or a Serverless workgroup. The same value goes into connection.host when you create the datastore via API.

  • Provisioned Redshift: <cluster-id>.<account-id>.<region>.redshift.amazonaws.com
  • Redshift Serverless: <workgroup-id>.<account-id>.<region>.redshift-serverless.amazonaws.com

To copy the endpoint from the AWS console:

  1. Open the Amazon Redshift console and select your cluster or workgroup.
  2. On the cluster (or workgroup) details page, find the General information panel.
  3. Copy the Endpoint value, dropping the trailing :<port>/<database> suffix if present. The Host field takes only the hostname; the Port and Database fields are separate.

VPC endpoints and private DNS aliases on IAM Role

On the IAM Role path, the JDBC driver infers the cluster (or workgroup) identity from the hostname, so the Host must be the canonical endpoint above. VPC endpoint URLs (vpce-...) and custom Route 53 / private DNS aliases are not supported on this path. With Password authentication, any hostname that routes to the cluster is acceptable.