Authentication Method: Margin uses RSA key pair authentication to connect to Snowflake.
You’ll generate an RSA private key (.p8 file) and configure the public key on your Snowflake user.If you encrypt your private key with a passphrase, you’ll need to enter it in Margin during setup.
It’s recommended to create a dedicated Snowflake user with the permissions needed to query and write to your data warehouse.If you’d prefer to use an existing user, ensure it has the appropriate privileges for both reading and writing to the relevant databases and schemas.The preferred way is to create a margin_user with the minimum required permissions.
⚠️ If you set a passphrase, remember it—you’ll need to enter it in Margin.
Locations to fill in required fields are highlighted in green
1. Create Margin Role/User
Copy
-- Margin user/role details--------------SET margin_default_warehouse = '<warehouse>'; -- e.g. 'COMPUTE_WH'SET margin_database = '<database>'; -- e.g. 'DATA_DB'SET margin_comment = 'For Margin integrations';-- Source data you want to read from (for granular access)SET source_database = '<database>'; -- e.g. 'APP_DB'SET source_schema = '<schema>'; -- e.g. 'EVENTS_SCHEMA'SET source_table_1 = '<table1>'; -- e.g. 'PAYMENT_EVENTS'SET source_table_2 = '<table2>'; -- e.g. 'KYC_EVENTS'-- etc. list all the tables here you want to read from --Use a high-privileged role and create Margin role/user-----------USE ROLE ACCOUNTADMIN;CREATE ROLE IF NOT EXISTS MARGIN_ROLE -- leave it as MARGIN_ROLE, do not changeCOMMENT = $margin_comment;CREATE USER IF NOT EXISTS MARGIN_USER -- leave it as MARGIN_USER, do not changeDEFAULT_WAREHOUSE = $margin_default_warehouseDEFAULT_ROLE = MARGIN_ROLECOMMENT = $margin_comment;ALTER USER MARGIN_USERSET RSA_PUBLIC_KEY='MIIB...'; -- Copy the public key here from the step aboveGRANT ROLE MARGIN_ROLETO USER MARGIN_USER;
2. Create MARGIN_SCHEMA + Grant USAGE on warehouse
Copy
----------------------------------------------------------------------------- Grant usage on warehouse---------------------------------------------------------------------------GRANT USAGE ON WAREHOUSE identifier($margin_default_warehouse) TO ROLE MARGIN_ROLE;------------------------------------------------------------------------------ Create MARGIN_SCHEMA (for cost/revenue data)----------------------------------------------------------------------------USE DATABASE identifier($margin_database);CREATE SCHEMA IF NOT EXISTS MARGIN_SCHEMA; -- leave it as MARGIN_SCHEMA, do not changeGRANT USAGE ON DATABASE identifier($margin_database)TO ROLE MARGIN_ROLE;
3. Grant USAGE on source data
Copy
------------------------------------------------------------------------------ Granular access to existing data (USAGE on DB/Schema)----------------------------------------------------------------------------GRANT USAGE ON DATABASE identifier($source_database) TO ROLE MARGIN_ROLE;SET grant_schema_usage_sql_command = 'GRANT USAGE ON SCHEMA ' || $source_database || '.' || $source_schema || ' TO ROLE MARGIN_ROLE';EXECUTE IMMEDIATE $grant_schema_usage_sql_command;
4. Grant SELECT on all Tables you want to read
Copy and paste for each table you want to read from the selected database:
Copy
------------------------------------------------------------------------------ Table-level SELECT for <table1>----------------------------------------------------------------------------SET grant_table_select_1 = 'GRANT SELECT ON TABLE ' || $source_database || '.' || $source_schema || '.' || $source_table_1 || ' TO ROLE MARGIN_ROLE';EXECUTE IMMEDIATE $grant_table_select_1;------------------------------------------------------------------------------ Table-level SELECT for <table2>----------------------------------------------------------------------------SET grant_table_select_2 = 'GRANT SELECT ON TABLE ' || $source_database || '.' || $source_schema || '.' || $source_table_2 || ' TO ROLE MARGIN_ROLE';EXECUTE IMMEDIATE $grant_table_select_2;-- do this for all tables you added in Step 1 (all tables you want to read from)
5. Mask Sensitive Columns
Configure the columns you want to mask in specific tables.
[Strongly Recommended] Use Option 1: built in masking policies if you have Snowflake Enterprise.
Otherwise, Option 2: secure views shows how to create secure views within MARGIN_SCHEMA.
Copy
------------------------------------------------------------------------------ Snowflake masking policies are strongly typed. You must create a separate-- masking policy for each data type. Below are examples for common types.------------------------------------------------------------------------------ (A) Masking Policy for STRING columns:CREATE OR REPLACE MASKING POLICY HIDE_STRING_FROM_MARGIN AS (VAL STRING) RETURNS STRING -> CASE WHEN CURRENT_ROLE() = 'MARGIN_ROLE' THEN '****' ELSE VAL END;-- (B) Masking Policy for NUMBER columns:CREATE OR REPLACE MASKING POLICY HIDE_NUMBER_FROM_MARGIN AS (VAL NUMBER) RETURNS NUMBER -> CASE WHEN CURRENT_ROLE() = 'MARGIN_ROLE' THEN 0 ELSE VAL END;-- (C) Masking Policy for DATE columns:CREATE OR REPLACE MASKING POLICY HIDE_DATE_FROM_MARGIN AS (VAL DATE) RETURNS DATE -> CASE WHEN CURRENT_ROLE() = 'MARGIN_ROLE' THEN NULL ELSE VAL END;-- (D) Masking Policy for VARIANT (and semi-structured) columns:CREATE OR REPLACE MASKING POLICY HIDE_VARIANT_FROM_MARGIN AS (VAL VARIANT) RETURNS VARIANT -> CASE WHEN CURRENT_ROLE() = 'MARGIN_ROLE' THEN NULL ELSE VAL END;------------------------------------------------------------------------------ Apply the masking policies to the corresponding columns in your table.----------------------------------------------------------------------------ALTER TABLE <database>.<schema>.<table> MODIFY COLUMN <secret_string_column> SET MASKING POLICY HIDE_STRING_FROM_MARGIN;ALTER TABLE <database>.<schema>.<table> MODIFY COLUMN <secret_number_column> SET MASKING POLICY HIDE_NUMBER_FROM_MARGIN;ALTER TABLE <database>.<schema>.<table> MODIFY COLUMN <secret_date_column> SET MASKING POLICY HIDE_DATE_FROM_MARGIN;ALTER TABLE <database>.<schema>.<table> MODIFY COLUMN <secret_variant_column> SET MASKING POLICY HIDE_VARIANT_FROM_MARGIN;
6. Grant Write Access to MARGIN_SCHEMA
Margin needs full control of MARGIN_SCHEMA to create tables, views, and stages for your cost/revenue data.
Copy
------------------------------------------------------------------------------ Transfer ownership of MARGIN_SCHEMA to MARGIN_ROLE----------------------------------------------------------------------------GRANT OWNERSHIP ON SCHEMA MARGIN_SCHEMA TO ROLE MARGIN_ROLE REVOKE CURRENT GRANTS;
This only grants control over MARGIN_SCHEMA. MARGIN_USER cannot create users/roles or access other schemas beyond what was explicitly granted.
If you need to connect to multiple databases, reach out to [email protected], we can enable this for you.
Account Name prefixed by its Organization (e.g. myorg-account123). Format may differ based on Snowflake account age. For details, visit Snowflake docs.
Warehouse
The warehouse name Margin should use to run queries.
Database
The default database for Margin queries.
Username
The Snowflake user you created (e.g., MARGIN_USER).
Private Key (.p8)
The RSA private key file generated during credential setup.
Private Key Passphrase
(Optional) Required if your private key is encrypted with a passphrase.
Role
The role you created (or an existing role with the necessary privileges).
Snowflake accounts can have different identifier formats depending on when they were created. For example, older accounts might look like ACCOUNT_LOCATOR.CLOUD_REGION_ID.CLOUD, while newer ones may look like ORGNAME-ACCOUNT_NAME. Check Snowflake’s documentation if unsure.
Sometimes the initial test might time out, especially if Snowflake is resuming from a suspended state. Simply click Test again to retry. Once a connection is established, further requests usually run quickly.