Manage data sources
How data sources are shared with the Native App
Section titled “How data sources are shared with the Native App”PyRel semantic models are built on top of existing Snowflake tables and views in your account. These data sources must be shared with the RelationalAI (RAI) Native App so that the app can keep data in semantic models up to date with changes in those sources. Although PyRel users determine which tables and views to use as data sources when they build semantic models, administrators are responsible for ensuring that those sources are set up properly for sharing and that the app can access them.
The RAI Native App uses Snowflake’s Change Data Capture (CDC) features to track changes in source tables and views. This section of the docs explains how to operate the app’s CDC service and manage the data streams that are created for each data source.
How Snowflake access control is handled
Section titled “How Snowflake access control is handled”The RAI Native App uses Snowflake’s security features to manage access to data sources by PyRel users.
How RAI applies role-based access
Section titled “How RAI applies role-based access”RAI supports Snowflake’s role-based access control model.
In Snowflake, privileges such as SELECT or USAGE are granted to roles, and roles are assigned to users.
This lets your organization control who can access specific tables, views, and other objects, and what actions they can perform.
RAI enforces Snowflake RBAC as follows:
- All app operations use the privileges of the active roles in your Snowflake session, as set in your configuration.
- When a PyRel user needs access to a data source, Snowflake checks that your role has the required privileges on the object and its parent database and schema.
- If privileges are missing, access is denied.
How row and masking policies are resolved
Section titled “How row and masking policies are resolved”Users with the Enterprise Edition of Snowflake, including Business Critical and Virtual Private Snowflake, can use row access policies and masking policies to protect data.
When the RAI Native App executes SQL commands, all row and masking policies are evaluated against a role named RELATIONALAI, not the role defined in the user’s configuration.
This means that:
- RAI doesn’t support user-based policies at the row and column level.
- You can create policies that apply to the
RELATIONALAIrole, but those policies affect all users of the app.
Consider the following masking policy that masks sensitive employee passwords when the user does not have the FULL_ACCESS role:
CREATE MASKING POLICY employee_pwd_mask AS (val string) RETURNS string -> CASE WHEN CURRENT_ROLE() IN ('FULL_ACCESS') THEN val ELSE '******' END;The app executes all queries using the RELATIONALAI role, so this masking policy applies to all app users.
All users see the masked value, even if the user has the FULL_ACCESS role.
Now suppose you add RELATIONALAI to the list of roles that can see the original value:
CREATE MASKING POLICY employee_pwd_mask AS (val string) RETURNS string -> CASE WHEN CURRENT_ROLE() IN ('FULL_ACCESS', 'RELATIONALAI') THEN val ELSE '******' END;In this case, the app sees the original value, and so does any app user with SELECT privileges on the relevant table, even if they do not have the FULL_ACCESS role.
Follow these best practices when you use row and masking policies with the RAI Native App:
- Start with least privilege and grant only the access the app needs.
- Write row and masking policies against the app’s
RELATIONALAIrole, not individual users. - If you use mapping tables for access control, map to the app’s
RELATIONALAIrole rather than individual users.