5

I want to get list of all users along with the roles that are assigned to those users in a single query in snowflake.

SHOW GRANTS TO ROLE1; --> This gives me list of all users assigned to ROLE1

BUT I Cannot do something like below -

SHOW GRANTS TO ROLE1
UNION ALL
SHOW GRANTS TO ROLE2
UNION ALL
SHOW GRANTS TO ROLE3;

Objective is to achieve something like above in a single query of snowflake.

Regards, Yogesh

4 Answers 4

5

I wrote a blog post here that explains how to get the role hierarchy (list of roles in which each user is a member) and effective privileges (a complete list of privileges per user for all grant types). I think the first query may be closer to what you want, but I'm including both:

-- The data returned by both queries is in the
-- SNOWFLAKE database, which has latency of up
-- to 3 hours to reflect changes

-- Get the effective role hierarchy for each user.
with
   -- CTE gets all the roles each role is granted
   ROLE_MEMBERSHIPS(ROLE_GRANTEE, ROLE_GRANTED_THROUGH_ROLE)
   as
    (
    select   GRANTEE_NAME, "NAME"
    from     SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES
    where    GRANTED_TO = 'ROLE' and
             GRANTED_ON = 'ROLE' and
             DELETED_ON is null
    ),
    -- CTE gets all roles a user is granted
    USER_MEMBERSHIPS(ROLE_GRANTED_TO_USER, USER_GRANTEE, GRANTED_BY)
    as
     (
     select ROLE,
            GRANTEE_NAME,
            GRANTED_BY
     from SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_USERS
     where DELETED_ON is null
     )
-- 
select
        USER_GRANTEE,
        case
            when ROLE_GRANTED_THROUGH_ROLE is null
                then ROLE_GRANTED_TO_USER 
            else ROLE_GRANTED_THROUGH_ROLE
        end
        EFFECTIVE_ROLE,
        GRANTED_BY,
        ROLE_GRANTEE,
        ROLE_GRANTED_TO_USER,
        ROLE_GRANTED_THROUGH_ROLE
from    USER_MEMBERSHIPS U
    left join ROLE_MEMBERSHIPS R
        on U.ROLE_GRANTED_TO_USER = R.ROLE_GRANTEE
;

--------------------------------------------------------------------------------------------------

-- This gets all the grants for all of the users:
with
    ROLE_MEMBERSHIPS
        (
            ROLE_GRANTEE, 
            ROLE_GRANTED_THROUGH_ROLE
        )
    as
    (
        -- This lists all the roles a role is in
        select   GRANTEE_NAME, "NAME"
        from     SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES
        where    GRANTED_TO = 'ROLE' and
                 GRANTED_ON = 'ROLE' and
                 DELETED_ON is null
    ),
    USER_MEMBERSHIPS
        (
            ROLE_GRANTED_TO_USER,
            USER_GRANTEE,
            GRANTED_BY
        )
    as
     (
        select ROLE,GRANTEE_NAME,GRANTED_BY
        from SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_USERS
        where DELETED_ON is null
     ),
    EFFECTIVE_ROLES
    (
        USER_GRANTEE,
        EFFECTIVE_ROLE,
        GRANTED_BY,
        ROLE_GRANTEE,
        ROLE_GRANTED_TO_USER,
        ROLE_GRANTED_THROUGH_ROLE
    )
    as
    (
        select
            USER_GRANTEE,
            case
                when ROLE_GRANTED_THROUGH_ROLE is null
                    then ROLE_GRANTED_TO_USER
                else ROLE_GRANTED_THROUGH_ROLE
            end
            EFFECTIVE_ROLE,
            GRANTED_BY,
            ROLE_GRANTEE,
            ROLE_GRANTED_TO_USER,
            ROLE_GRANTED_THROUGH_ROLE
        from USER_MEMBERSHIPS U
            left join ROLE_MEMBERSHIPS R
            on U.ROLE_GRANTED_TO_USER = R.ROLE_GRANTEE
    ),
    GRANT_LIST
        (
            CREATED_ON,
            MODIFIED_ON,
            PRIVILEGE,
            GRANTED_ON, 
            "NAME",
            TABLE_CATALOG,
            TABLE_SCHEMA,
            GRANTED_TO,
            GRANTEE_NAME,
            GRANT_OPTION
        )
    as
    (
        -- This shows all the grants (other than to roles)
        select  CREATED_ON,
                MODIFIED_ON,
                PRIVILEGE,
                "NAME",
                TABLE_CATALOG,
                TABLE_SCHEMA,
                GRANTED_TO,
                GRANTEE_NAME,
                GRANT_OPTION,
                GRANTED_ON
        from    SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES
        where   GRANTED_ON <> 'ROLE' and
                PRIVILEGE <> 'USAGE' and
                DELETED_ON is null
    )
select * from EFFECTIVE_ROLES R
    left join GRANT_LIST G 
        on G.GRANTED_TO = R.EFFECTIVE_ROLE
where G.PRIVILEGE is not null
;
Sign up to request clarification or add additional context in comments.

2 Comments

I also need to get role access to each DB to identify if it is read or write access. Any help on this
I think your query will select users whose role has been revoked, because a past grant will still select DELETED_ON is null
1

A number of queries in snowflake are not really queries, so you have to fetch the results in an extra step using result_scan(-N) to fetch them

show grants to ROLE accountadmin;

show grants to ROLE sysadmin;

select * from table(result_scan(-1))
union all
select * from table(result_scan(-2));

works for me as you want...

Comments

0

More easy solution:

 SELECT  ROLE_NAME FROM SNOWFLAKE.INFORMATION_SCHEMA.APPLICABLE_ROLES
     START WITH GRANTEE in(select distinct ROLE from SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_USERS GTU 
    join  SNOWFLAKE.ACCOUNT_USAGE.USERS u on u.name = GTU.grantee_name
        where GTU.DELETED_ON is NULL AND not U.DISABLED AND not
 U.SNOWFLAKE_LOCK and U.DELETED_ON is null and U.LOGIN_NAME ='USER' ) 
    CONNECT BY GRANTEE = PRIOR ROLE_NAME

Comments

0

If you have access to snowflake.account_usage, this query solves your problem:

with granted as (
    select * from snowflake.account_usage.grants_to_users
    where role in ('ROLE1', 'ROLE2', 'ROLE3')
    qualify row_number() over (partition by role, grantee_name order by created_on desc) = 1
)
select distinct grantee_name as name, role from granted where deleted_on is null
order by name;

Note: I think other answers that rely on grants_to_users are incorrect in that they include revoked roles, because they don't have a condition on pairs (role, grantee) being the most recent with deleted_on is null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.