snowflake column masking policies for agents
Shows how to use Snowflake masking policies to give agents safe data access. Use it when a data agent needs to query production tables but must not see raw PII: mask emails, names, and IDs per role while keeping the schema realistic. Not for full access-control design, and not for non-Snowflake warehouses.
TL;DR
If an agent needs to explore real tables but shouldn't see real PII, Snowflake masking policies are the clean answer: you attach a policy to a column that returns the real value for privileged roles and a masked value (hash, partial, or NULL) for everyone else. The agent gets a realistic schema and real distributions to work with, but emails and names come back as ***. Set it once on the column and it applies to every query path, including the ones agents use.
The query
snowflake column masking policies for agentsUse this when
- a data agent needs read access to production tables containing PII
- analysts and agents share tables but should see different levels of detail
- you want masking enforced in the warehouse, not trusted to each client
Not for
- replacing role-based access entirely (masking complements grants, it does not replace them)
- warehouses other than Snowflake (the syntax here is Snowflake-specific)
- hiding data from account admins (they can always see through policies)
Steps
- Identify the sensitive columns. Start with the obvious PII: email, full name, phone, address, government IDs. Document the list; you will reuse it across tables.
Expected output: a short list of columns per table that need masking.
- Create the masking policy. The standard pattern returns the real value for privileged roles and a masked value otherwise:
CREATE OR REPLACE MASKING POLICY email_mask AS (val STRING)
RETURNS STRING ->
CASE
WHEN CURRENT_ROLE() IN ('PII_READER') THEN val
ELSE '***masked***'
END;Expected output: the policy exists and DESCRIBE MASKING POLICY email_mask shows the definition.
- Attach it to the columns with
ALTER TABLE ... MODIFY COLUMN ... SET MASKING POLICY. One policy can attach to many columns of the same type.
Expected output: SHOW COLUMNS or the table DDL shows the policy attached.
- Create the agent role with SELECT on the tables but without the privileged PII role, then query as that role to verify masking.
Expected output: querying as the agent role returns masked values; as PII_READER it returns real ones.
- Decide on the masked shape per column type. Emails often keep the domain (
***@example.com) so joins still behave; IDs can be hashed deterministically so the agent can still group by them without seeing the original.
Expected output: the agent can run realistic analysis (group-bys, joins on hashed keys) while PII stays hidden.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_InBWnK7WS93nprmOLh68-w
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.