Example: Setting Up Custom Roles for Prod and Stage

In this tutorial, we will go through an example of how to set up an Organization with custom roles for prod and stage. Starting from a fresh Organization, by the end of the tutorial we aim to have the following:

  • 2 Databases – prod_db and stage_db

  • 2 custom roles – prod_manager and stage_manager

    • prod_manager should have have full access to the prod_db database

    • stage_manager should have have full access to the stage_db database

  • 1 admin user

    • admin user will be the first user, granted the ORGADMIN role and inheriting all other admin roles

  • 2 non-admin users

    • prod user will be granted prod_manager and stage_manager

    • stage user will only be granted stage_manager

As Admin User

The first user in an Organization will log in and by default be using the sysadmin built-in role. However, this user has access to all of the built-in admin roles, including orgadmin. As the admin user for this example, there are 4 small tasks:

  • Create Databases

  • Create custom roles

  • Grant the appropriate privileges for these new roles

  • Invite non-admin users and assign them these custom roles

1. Create Databases

When creating objects in an Organization, users should use the sysadmin role or a lower role in the hierarchy. Let's switch to the sysadmin role:

USE ROLE sysadmin;

Use the CREATE DATABASE command to create the prod_db and stage_db Databases:

CREATE DATABASE prod_db;
CREATE DATABASE stage_db;

That's it! Now if we list our Databases, we should be able to see both:

prod_db.public/<no-store># LIST DATABASES;
    Name   | Default |  Owner   |      Created at      |      Updated at
-----------+---------+----------+----------------------+-----------------------
  stage_db |         | sysadmin | 2023-12-13T22:28:04Z | 2023-12-13T22:28:04Z
  prod_db  | ✓       | sysadmin | 2023-12-13T22:27:57Z | 2023-12-13T22:27:57Z

2. Create Custom Roles

Switch to the useradmin role, which is responsible for creating roles and granting roles to users:

USE ROLE USERADMIN;

Use the CREATE ROLE command to create the prod_manager and stage_manager roles:

CREATE ROLE prod_manager;
CREATE ROLE stage_manager;

By just creating these roles, they are standalone roles that are detached from any other roles. However, these custom roles should be granted to the sysadmin role and become lower members of the sysadmin role's hierarchy. We can grant these custom roles to the sysadmin using the GRANT ROLE command:

GRANT ROLE prod_manager TO ROLE sysadmin;
GRANT ROLE stage_manager TO ROLE sysadmin;

We can see the new roles we've just created with the LIST ROLES command:

<no-db>/<no-store># LIST ROLES;
      Name      | Current |      Created at
----------------+---------+-----------------------
  public        |         | 2023-12-13T22:16:12Z
  securityadmin |         | 2023-12-13T22:16:12Z
  useradmin     | ✓       | 2023-12-13T22:16:12Z
  prod_manager  |         | 2023-12-13T22:32:41Z
  orgadmin      |         | 2023-12-13T22:16:12Z
  sysadmin      |         | 2023-12-13T22:16:12Z
  stage_manager |         | 2023-12-13T22:32:44Z

3. Grant the Appropriate Privileges for each Role

Now that our new roles are created, we need to grant these roles the usage privilege to work with their respective Databases. As the owner of these Databases, the sysadmin role should be used to grant this privilege to the custom roles. So, let's switch to the sysadmin role:

USE ROLE sysadmin;

We can grant privileges to our custom roles by using the GRANT <PRIVILEGE> command (see the full list of privileges). For this example, we want to grant the USAGE privilege of a each Database to the matching role:

GRANT USAGE ON DATABASE prod_db TO ROLE prod_manager;
GRANT USAGE ON DATABASE stage_db TO ROLE stage_manager;

We can see the new granted privileges for our prod_manager role by describing the role using the DESCRIBE ROLE command:

<no-db>/<no-store># DESCRIBE ROLE prod_manager;
      Name     |      Created at
---------------+-----------------------
  prod_manager | 2023-12-13T22:32:41Z

Granted Roles
   Name
----------
  public

Granted Privileges
  Type  |  Target  | ID/Name | Grant option
--------+----------+---------+---------------
  Usage | Database | prod_db |

4. Invite Users and Assign them these Custom Roles

Now that we have our Databases and custom roles set up, we can invite users and assign them to a set of roles. Inviting users is one of the useradmin responsibilities, so let's switch to that role:

USE ROLE useradmin;

We can invite our new users using the INVITE USER command:

INVITE USER 'prod_user@demo.org' WITH ('roles'=(prod_manager, stage_manager), 'default'=stage_manager);
INVITE USER 'stage_user@demo.org' WITH ('roles'=(stage_manager), 'default'=stage_manager);

The email is used as the identifier for a particular user. In the above code block, we are inviting 'prod_user@demo.org' to our Organization and granting the prod_manager and stage_manager roles to them. For 'stage_user@demo.org', we are only granting the stage_manager role. Note that the useradmin can grant additional roles to users with the GRANT ROLE command, or revoke roles from users with the REVOKE ROLE command.

In the next sections, let's see how interacting with the Organization looks as each user.

As Prod User

As the prod user, after accepting the invitation into this Organization (see ACCEPT INVITATION command), we should see that our current role is the stage_manager role since the useradmin set it as the default role for the prod user. We can see which role we are using by using the LIST ROLES command:

<no-db>/<no-store># LIST ROLES;
      Name      | Current |      Created at       
----------------+---------+-----------------------
  public        |         | 2023-12-13T22:16:12Z  
  securityadmin |         | 2023-12-13T22:16:12Z  
  useradmin     |         | 2023-12-13T22:16:12Z  
  prod_manager  |         | 2023-12-13T22:32:41Z  
  orgadmin      |         | 2023-12-13T22:16:12Z  
  sysadmin      |         | 2023-12-13T22:16:12Z  
  stage_manager | ✓       | 2023-12-13T22:32:44Z  

If we list the Databases, we'll only see stage_db because that is the only Database that is available to the stage_manager role that we are assuming:

<no-db>/<no-store># LIST DATABASES;
    Name   | Default |  Owner   |      Created at      |      Updated at       
-----------+---------+----------+----------------------+-----------------------
  stage_db |         | sysadmin | 2023-12-13T22:28:04Z | 2023-12-13T22:28:04Z  

Since the prod user has access to both stage_manager and prod_manager roles, we can switch to the prod_manager role:

USE ROLE prod_manager;

Using the prod_manager role, if we list our Databases again we can see that only the prod_db Database is shown:

<no-db>/<no-store># list DATABASES;
   Name   | Default |  Owner   |      Created at      |      Updated at       
----------+---------+----------+----------------------+-----------------------
  prod_db |         | sysadmin | 2023-12-13T22:27:57Z | 2023-12-13T22:27:57Z  

As Stage User

As the stage user, after accepting the invitation into this Organization (see ACCEPT INVITATION command), we should see that our current role is the stage_manager role since the useradmin set it as the default role for the prod user. We can see which role we are using by using the LIST ROLES command:

<no-db>/<no-store># LIST ROLES;
      Name      | Current |      Created at       
----------------+---------+-----------------------
  public        |         | 2023-12-13T22:16:12Z  
  securityadmin |         | 2023-12-13T22:16:12Z  
  useradmin     |         | 2023-12-13T22:16:12Z  
  prod_manager  |         | 2023-12-13T22:32:41Z  
  orgadmin      |         | 2023-12-13T22:16:12Z  
  sysadmin      |         | 2023-12-13T22:16:12Z  
  stage_manager | ✓       | 2023-12-13T22:32:44Z  

If we list the Databases, we'll only see stage_db because that is the only Database that is available to the stage_manager role that we are assuming:

<no-db>/<no-store># LIST DATABASES;
    Name   | Default |  Owner   |      Created at      |      Updated at       
-----------+---------+----------+----------------------+-----------------------
  stage_db |         | sysadmin | 2023-12-13T22:28:04Z | 2023-12-13T22:28:04Z  

Notably, the stage user doesn't have access to the prod_manager role. If we try to use the prod_manager role we will get an error message:

<no-db>/<no-store># USE ROLE prod_manager;
ERROR: role prod_manager not granted to user

Last updated