Grant Group and Role Privileges Directly to Snowflake Users¶
By default, the Snowflake connector creates a shadow role for each user, group, and role:
- Per-user:
PRIV_USER_<username> - Per-group:
PRIV_GROUP_<groupname> - Per-role:
PRIV_ROLE_<rolename>
Object privileges (for example, SELECT on a table) are granted to the shadow role for that user, group, or role. Group and role shadow roles are then granted to the user’s shadow role, and the user’s default role is set to that per-user shadow role.
After you enable this feature, PolicySync does not create or use a per-user shadow role. Instead, it grants group and role shadow roles directly to the Snowflake user.
Overview¶
| Feature | How membership works | User shadow role (PRIV_USER_*) |
|---|---|---|
Default (false) | Group and role shadow roles are granted to the user’s shadow role | Created and used as the user’s default role |
Feature enabled (true) | Group and role shadow roles are granted directly to the Snowflake user | Not created for new users; default role set to PUBLIC when PolicySync manages users |
Object privileges (for example, SELECT on a table) continue to be granted to PRIV_GROUP_* / PRIV_ROLE_* whether the feature is enabled or disabled. What changes is how the user is connected to those roles.
Property summary¶
| Attribute | Value |
|---|---|
| Ranger property | ranger.policysync.connector.0.grant.group.role.directly.to.user |
| Privacera Manager variable | CONNECTOR_SNOWFLAKE_GRANT_GROUP_ROLE_DIRECTLY_TO_USER |
| Default | false |
When false | Feature disabled: create and use PRIV_USER_*, and grant group/role shadow roles to that role |
When true | Grant PRIV_GROUP_* / PRIV_ROLE_* directly to the Snowflake user; do not create new PRIV_USER_* roles |
When the property is true:
- PolicySync does not create new per-user shadow roles (
PRIV_USER_*). - Group and role membership is applied with
GRANT ROLE … TO USER/REVOKE ROLE … FROM USER. - User-level ACL grants on resources are skipped (fail closed). Access is through group and role shadow roles only.
- User-level masking and row-filter (RLF) principals are skipped (fail closed), same as user-level resource ACL grants.
- User-attribute masking/RLF (
USER.*/GET_USER_ATTR/HAS_USER_ATTR) is unsupported (requiresPRIV_USER_*). - Prefer group-based or role-based policies for access, masking, and row filters.
- For users managed by PolicySync (
create.service.user=true/CONNECTOR_SNOWFLAKE_CREATE_USER: "true"), the user’s default role is set toPUBLICinstead ofPRIV_USER_*(including create and migration repair for existing users).
Note
This feature does not set DEFAULT_SECONDARY_ROLES=('ALL'). Granted roles are activated by switching role in the Snowflake UI or with USE ROLE. The existing property create.service.user.with.empty.dsr (CONNECTOR_SNOWFLAKE_CREATE_USER_WITH_EMPTY_DSR) only controls whether new users are created with empty secondary roles (()); it is unrelated to auto-activating direct grants.
Configuration¶
-
Navigate to Settings → Applications in the Self-Managed Portal.
-
From the list of Connected Applications, select Snowflake.
-
Select the application name or the icon to edit. Then go to the Access Management tab.
-
Under Add New Custom Properties, add the following property:
Bash -
Select SAVE to apply the changes.
-
SSH to the instance where Privacera Manager is installed.
-
Run the following command to open the
.ymlfile to be edited.If you have multiple connectors, then replace
instance1with the appropriate connector instance name.Bash -
Add or update the following property:
YAML -
Once the property is configured, run the following commands to update your Privacera Manager platform instance:
Step 1 - Setup which generates the helm charts. This step usually takes few minutes.
Step 2 - Apply the Privacera Manager helm charts. Step 3 - (Optional) Post-installation step which generates Plugin tar ball, updates Route 53 DNS and so on. This step is not required if you are updating only connector properties.
-
In the PrivaceraCloud portal, navigate to Settings → Applications.
-
On the Connected Applications screen, select Snowflake.
-
Select the icon or the account name to modify the settings.
-
On the Edit Application screen, go to the Access Management tab.
-
Under Add New Custom Properties, add the following property:
Bash -
Select SAVE to apply the changes.
How users get access after enabling this feature¶
In Snowflake, a role granted to a user is not always active in the session. The user must switch the current role (Snowflake UI role dropdown, or USE ROLE "PRIV_GROUP_<name>").
Switch role in the UI¶
- PolicySync grants the group or role shadow role to the user.
- The user opens Snowflake and selects that role from the role dropdown (or runs
USE ROLE). - Queries run with that role’s privileges.
Example:
| SQL | |
|---|---|
Then object privileges on PRIV_GROUP_analyst apply for that session.
Interaction with create service user¶
create.service.user / CONNECTOR_SNOWFLAKE_CREATE_USER | Feature useful? | What PolicySync does |
|---|---|---|
true | Yes | Can create or alter users; sets DEFAULT_ROLE=PUBLIC; grants roles to users |
false | Yes, if users already exist | Does not create or alter users; still creates group and role shadow roles and runs GRANT ROLE … TO USER |
When create.service.user is false¶
Typical for customers who provision users through SSO, SCIM, or Snowflake administration.
- This feature still reduces
PRIV_USER_*role sprawl. - Users must already exist in Snowflake, and names must match PolicySync.
- PolicySync does not migrate
DEFAULT_ROLE. - Users get access by switching role in the session (or by secondary-role settings managed outside PolicySync).
For related principal settings, see Create and Manage Principals in Snowflake.
Recommended configurations¶
Default (unchanged behavior)¶
| YAML | |
|---|---|
Feature enabled with role switch in the UI¶
| YAML | |
|---|---|
Customer expectation: After sync, select the relevant PRIV_GROUP_* / PRIV_ROLE_* role in Snowflake (or run USE ROLE) before querying.
When CONNECTOR_SNOWFLAKE_CREATE_USER is "true", PolicySync also sets or repairs DEFAULT_ROLE=PUBLIC so new users are not pointed at a non-existent PRIV_USER_*.
Behavior details¶
What is created or granted¶
| Item | Default (false) | Feature enabled (true) |
|---|---|---|
PRIV_GROUP_* / PRIV_ROLE_* | Yes | Yes |
| Object privileges on those roles | Yes | Yes |
PRIV_USER_* for new users | Yes | No |
| Membership | Role → role (TO ROLE PRIV_USER_*) | Role → user (TO USER) |
| User-level resource ACLs | Supported | Skipped |
| User-level masking | Supported | Skipped (group/role masking still applied) |
| User-level row filter (RLF) | Supported | Skipped (group/role RLF still applied) |
| Default role (when PolicySync manages users) | PRIV_USER_* | PUBLIC |
DEFAULT_SECONDARY_ROLES=('ALL') | Not managed by this feature | Not managed by this feature |
Legacy PRIV_USER_* roles¶
If you enable this feature on an environment that previously had it disabled:
- Existing
PRIV_USER_*roles may remain until cleaned up (for example on user delete, when the role still exists). There is no bulk auto-drop on enable in this release. - Leftover
PRIV_USER_*access grants may still work until policy or user cleanup. - New users do not get a new
PRIV_USER_*role. - Membership for groups and roles is applied directly to the user going forward.
- During migration, a group or role may temporarily have both legacy memberships (
TO ROLE PRIV_USER_*) and direct grants (TO USER). PolicySync reconciles both when updating membership. - When
CONNECTOR_SNOWFLAKE_CREATE_USERis"true", PolicySync may alter existing users’DEFAULT_ROLEtoPUBLIC.
User-level policies¶
With this feature enabled, policies that target the individual user are not applied in Snowflake:
| Policy type | Behavior when the feature is true |
|---|---|
Resource access (SELECT, USAGE, …) | Skipped (fail closed) |
| Masking | User principals skipped; group/role masking still applied |
| Row filter (RLF) | User principals skipped; group/role RLF still applied |
Prefer group-based or role-based policies so privileges and masking/RLF land on PRIV_GROUP_* / PRIV_ROLE_*.
If a masking or RLF policy lists both users and groups/roles, only the group/role principals are kept; user principals are stripped.
When the flag is set back to false, user-level access, masking, and RLF behave as when the feature is disabled (after the next sync).
Until policy or user cleanup, leftover classic PRIV_USER_* grants may still grant access even though new user-level policies are skipped.
Tag-based policies¶
Tag sync itself is unchanged. Tag-based access, masking, and row-filter policies follow the same principal rules as non-tag policies:
| Tag policy principals | With feature enabled (true) |
|---|---|
| User | Not applied (fail closed) |
| Group / Role | Applied |
| User + Group/Role (masking/RLF) | Users stripped; group/role kept |
Prefer tag policies that grant to groups or roles, not individual users.
User-attribute masking and row filters¶
Not supported when this feature is enabled (these historically depended on PRIV_USER_*):
| Construct | Examples |
|---|---|
| User attribute conditions | USER.location, USER.dept, USER._name |
| User attribute functions | GET_USER_ATTR(...), GET_USER_ATTR_NAMES() |
| User attribute presence | HAS_USER_ATTR(...) |
| User macros in mask/RLF | ${{USER.location}}, other ${{USER.*}} forms |
Typical symptom: The user can still access data via group/role grants, but masking/RLF based on user attributes does not behave as when the feature is disabled.
What to do: Keep the flag false if you need these, or rewrite policies to group/role conditions that do not use user attributes.
Note (Feature Enabled)¶
- You can use this feature when PolicySync does not create users. Users must already exist; PolicySync only grants roles to those users.
- Enabling this feature does not automatically give access at login. The user (or client) must switch to the granted role (
USE ROLE/ Snowflake UI role dropdown), or enable secondary roles outside PolicySync. - PolicySync does not change
DEFAULT_ROLEifcreate.service.userisfalse. - Object privileges are not granted directly to the user. Privileges stay on
PRIV_GROUP_*/PRIV_ROLE_*. The user is linked to those roles by membership grant. - User-level masking and RLF do not work with this feature. User principals in masking and RLF are skipped, same as user-level access grants. Use group or role policies. Turning the flag off restores classic user-level masking/RLF after sync.
- If a masking/RLF policy has both a user and a group, only the group (and role) principals are applied; the user principal is ignored.
- Tag-based user policies do not work. User principals in tag-based access, masking, and RLF are skipped the same way as non-tag user policies. Use group/role principals on the tag policy.
USER.*/GET_USER_ATTRpolicies do not work with this feature. Keep the flagfalse, or rewrite to group/role-based conditions.
Related properties¶
| Property / variable | Default | Purpose |
|---|---|---|
grant.group.role.directly.to.user / CONNECTOR_SNOWFLAKE_GRANT_GROUP_ROLE_DIRECTLY_TO_USER | false | Grant group and role shadow roles directly to Snowflake users |
create.service.user / CONNECTOR_SNOWFLAKE_CREATE_USER | true | Whether PolicySync creates, alters, or deletes Snowflake users (also required for DEFAULT_ROLE=PUBLIC repair) |
create.service.user.role / CONNECTOR_SNOWFLAKE_CREATE_USER_ROLE | true | Whether PolicySync creates user shadow roles (skipped for new users when this feature is on) |
create.service.user.with.empty.dsr / CONNECTOR_SNOWFLAKE_CREATE_USER_WITH_EMPTY_DSR | false | Create user with empty secondary roles (()); unrelated to activating direct grants |
See also Create and Manage Principals in Snowflake.
- Prev topic: Advanced Configuration