Atlas now inspects, diffs, and migrates Amazon Redshift roles, groups, users, and the grants they hold, so a role hierarchy and every schema-, table-, and column-level GRANT live alongside your schema and are reconciled with the exact GRANT and REVOKE statements.
Enabling roles and permissions
Roles and permissions are excluded from inspection and schema management by default. Turn them on per environment with a schema.mode block:
env "redshift" { url = getenv("REDSHIFT_URL") dev = getenv("REDSHIFT_DEV_URL") schema { src = "file://schema.rs.hcl" mode { roles = true // Inspect and manage roles, groups, and users permissions = true // Inspect and manage GRANT / REVOKE } }}
Roles, groups, and users are cluster-wide rather than scoped to a database, so give the dev environment its own provisioned cluster or Serverless workgroup, and declare the accounts Atlas must never touch, such as the cluster admin, with external = true.
Defining roles, groups, and users
Redshift keeps these three apart, and Atlas manages all of them: a role block is an RBAC role, the same block with group = true is a group, and a user block is a login user. member_of builds the hierarchy across all three.
role "app_readonly" {} role "app_writer" { member_of = [role.app_readonly]} // A group is a role carrying the group marker: Redshift keeps// CREATE GROUP apart from CREATE ROLE.role "app_analysts" { group = true} user "app_api" { conn_limit = 5 member_of = [role.app_writer, role.app_analysts]}
Granting privileges
A permission block grants privileges on a schema, table, view, materialized view, or a single column, to a role, a group, a user, or PUBLIC. A group is referenced as role.<name>, and Atlas writes it as the GROUP grantee Redshift expects:
permission { to = role.app_readonly for = schema.reporting privileges = [USAGE]} permission { to = role.app_readonly for = table.orders privileges = [SELECT]} // Grants can go down to a single column.permission { to = role.app_analysts for = table.orders.column.total privileges = [SELECT]}
Applying the change
Both workflows are supported, and the statements are the same either way:
# Declarative: reconcile the cluster with the desired state.atlas schema apply --env redshift # Versioned: capture the change as a migration file.atlas migrate diff add_security --env redshift
Whether they land in a plan or in a migration file, Atlas orders them around the constraints the cluster enforces: revokes before grants, memberships dropped before new ones are added, and privileges revoked before the role or user holding them is dropped.
-- Create group "app_analysts"CREATE GROUP "app_analysts";-- Create role "app_readonly"CREATE ROLE "app_readonly";-- Create role "app_writer"CREATE ROLE "app_writer";-- Add "app_writer" to "app_readonly"GRANT ROLE "app_readonly" TO ROLE "app_writer";-- Create user "app_api"CREATE USER "app_api" PASSWORD DISABLE CONNECTION LIMIT 5;-- Add "app_api" to "app_analysts"ALTER GROUP "app_analysts" ADD USER "app_api";-- Add "app_api" to "app_writer"GRANT ROLE "app_writer" TO "app_api";-- Grant on schema "reporting" to "app_readonly"GRANT USAGE ON SCHEMA "reporting" TO ROLE "app_readonly";-- Grant on table "orders" to "app_readonly"GRANT SELECT ON TABLE "reporting"."orders" TO ROLE "app_readonly";-- Grant on column "total" on table "orders" to "app_analysts"GRANT SELECT ("total") ON TABLE "reporting"."orders" TO GROUP "app_analysts";
Going the other way works too: point Atlas at an existing cluster and atlas schema inspect writes the roles, groups, users, and grants it finds back out as HCL or SQL.
Getting Started
Redshift roles and permissions are part of Atlas Pro:
$ atlas loginSee the declarative and versioned security guides for the full walkthrough, the HCL reference for every attribute, and the Security Graph to see how the resulting grants connect across your repository.