CREATE PRIVACY POLICY¶
Creates a new privacy policy or replaces an existing privacy policy.
- See also:
ALTER PRIVACY POLICY , DESCRIBE PRIVACY POLICY , DROP PRIVACY POLICY , SHOW PRIVACY POLICIES
Syntax¶
CREATE [ OR REPLACE ] PRIVACY POLICY [ IF NOT EXISTS ] <name>
AS () RETURNS PRIVACY_BUDGET -> <body>
[ COMMENT = '<string_literal>' ]
Required parameters¶
name
String that specifies the identifier (that is, name) for the privacy policy; must be unique for the schema in which the privacy policy is created.
In addition, the identifier must start with an alphabetic character and cannot contain spaces or special characters unless the entire identifier string is enclosed in double quotes (for example,
"My object"
). Identifiers enclosed in double quotes are also case-sensitive.For more information, see Identifier requirements.
body
The SQL expression of the body calls two functions to control the return value of the policy: NO_PRIVACY_POLICY and PRIVACY_BUDGET. When a query is executed against a table that has been assigned the policy, Snowflake evaluates the conditions of the body to call the appropriate function and return a value. This return value determines which privacy budget, if any, is associated with the query against the privacy-protected table.
The expression can use context functions such as CURRENT_ROLE or INVOKER_ROLE to associate a user or group of users with a privacy budget.
If you use a CASE block in the body’s expression, it must include an ELSE statement that calls either NO_PRIVACY_POLICY or PRIVACY_BUDGET. Every user must either be associated with a privacy budget or have unrestricted access to the privacy-protected table. If a user should not have any access to a privacy-protected table or view, revoke SELECT privileges rather than trying to define this in the privacy policy.
NO_PRIVACY_POLICY
Use the body’s expression to call the
NO_PRIVACY_POLICY
function when you want a query to have unrestricted access to the table or view to which the privacy policy is assigned.PRIVACY_BUDGET
Use the body’s expression to call the
PRIVACY_BUDGET
function when you want to return a privacy budget from the policy. The expression can contain conditions that allow the policy to return different privacy budgets for different queries based on factors like the user who is executing the query.In cross-account collaboration, privacy budgets are automatically namespaced by the account identifier of the consumer account, which prevents two different consumer accounts from sharing the same privacy budget even if the name of the privacy budget is the same. Using the CURRENT_ACCOUNT function to concatenate the name of the account with the name of the privacy budget can help distinguish between privacy budgets. For example, you could call the function as follows:
PRIVACY_BUDGET(BUDGET_NAME => 'external_budget.' || CURRENT_ACCOUNT())
.The signature of the
PRIVACY_BUDGET
function is:PRIVACY_BUDGET( BUDGET_NAME=> '<string>' [, BUDGET_LIMIT=> <decimal> ] [, MAX_BUDGET_PER_AGGREGATE=> <decimal> ] [, BUDGET_WINDOW=> <string> ] )
Privacy budget arguments:
BUDGET_NAME => expression
Resolves to the name of a privacy budget. Snowflake creates the privacy budget automatically when its name is specified in the body of the privacy policy.
BUDGET_LIMIT => decimal
A decimal number > 0 that specifies the budget limit for this privacy policy. This controls the total amount of privacy loss allowed. Adjusting this value changes how many total differentially private aggregates can be calculated against tables protected by this privacy budget during the refresh period. When a query is run that would cause the cumulative privacy loss to exceed this number, the query will fail. As a rough estimate, a budget limit of 233 with
MAX_BUDGET_PER_AGGREGATE=1
permits about 1000 aggregates per refresh period.Default: 233.0
MAX_BUDGET_PER_AGGREGATE => decimal
Specifies how much privacy budget is used for each aggregate function in a query. Adjusting this value changes the amount of noise added to each aggregate query, as well as the number of aggregates that can be calculated before the budget limit is reached. As an example, the query
select count(*), avg(a) ...
has two aggregates:count(*)
andavg(a)
. Specify a decimal value > 0.Default: 0.5
BUDGET_WINDOW => string
How often the privacy budget is refreshed, that is, has its cumulative privacy loss reset to 0. Valid values:
Daily
: Refreshed every day at 12:00 AM UTCWeekly
: Refreshed every Sunday at 12:00 AM UTCMonthly
: Refreshed on the first day of the calendar month at 12:00 AM UTCYearly
: Refreshed on January 1 at 12:00 AM UTCNever
: Privacy budget is never refreshed.
Default: Weekly
Optional parameters¶
COMMENT = 'string_literal'
Specifies a comment for the privacy policy.
Default: No value
Access control requirements¶
A role used to execute this SQL command must have the following privileges at a minimum:
Privilege |
Object |
Notes |
---|---|---|
CREATE PRIVACY POLICY |
Schema |
Note that operating on any object in a schema also requires the USAGE privilege on the parent database and schema.
For instructions on creating a custom role with a specified set of privileges, see Creating custom roles.
For general information about roles and privilege grants for performing SQL actions on securable objects, see Overview of Access Control.
Usage notes¶
Regarding metadata:
Attention
Customers should ensure that no personal data (other than for a User object), sensitive data, export-controlled data, or other regulated data is entered as metadata when using the Snowflake service. For more information, see Metadata fields in Snowflake.
CREATE OR REPLACE <object> statements are atomic. That is, when an object is replaced, the old object is deleted and the new object is created in a single transaction.
Examples¶
Create a privacy policy that always returns a budget named analysts
:
CREATE PRIVACY POLICY my_priv_policy AS ( ) RETURNS PRIVACY_BUDGET -> PRIVACY_BUDGET(BUDGET_NAME=> 'analysts');
Create a privacy policy that will give admin
unrestricted access to the privacy-protected table while associating all other users with
the privacy budget analysts
:
CREATE PRIVACY POLICY my_priv_policy AS () RETURNS PRIVACY_BUDGET -> CASE WHEN CURRENT_USER() = 'ADMIN' THEN NO_PRIVACY_POLICY() ELSE PRIVACY_BUDGET(BUDGET_NAME => 'analysts') END;