![[New Feature] Feature Policy Rules is now generally available, so I tried blocking only the creation of TEMPORARY tables and serverless tasks](https://images.ctfassets.net/ct0aopd36mqt/wp-refcat-img-3610e3c1ff5961bdb7b464e17f8bf06d/90b168b240005ead852ec1d474bb74fb/snowflake-logo-1200x630-1.png?w=3840&fm=webp)
[New Feature] Feature Policy Rules is now generally available, so I tried blocking only the creation of TEMPORARY tables and serverless tasks
This page has been translated by machine translation. View original
This is Kawabata.
On August 16, 2026, Feature Policy Rules became generally available.
In this article, I will verify conditional blocking of object creation using rules, and the output of DESC FEATURE POLICY, which also became GA at the same time.
【Official Documentation】
Feature Policy Rules
【Addendum】
I was selected as a finalist in the "RISING COMMUNITY LEADER OF THE YEAR" category, APJ slot, of the Snowflake Community Awards.
Please see the link below for details.
Overview of Feature Policy Rules
Feature Policy is a governance feature that controls "which objects can be created within a container." The unit of application is not users or roles, but containers such as databases, Personal Databases, and Native Apps (account-level bulk application is also available).
With this GA, in addition to the conventional type-based blocking, you can now write conditional blocking using rules.
| Conventional: BLOCKED_OBJECT_TYPES_FOR_CREATION | New: rules (YAML body) | |
|---|---|---|
| Granularity | All-or-nothing per object type | Conditional based on request attributes |
| Example | Prevent creation of any tasks | Block only serverless tasks |
| Target types | 12 types such as TASKS, DATABASES, WAREHOUSES | Expanded to TABLE, VIEW, STAGE, FUNCTION, PROCEDURE, etc. |
Rules are written in YAML within AS $$ ... $$ of the policy definition. Creation requests for which the SQL expression in block_when evaluates to TRUE are blocked.
CREATE FEATURE POLICY <name>
[ BLOCKED_OBJECT_TYPES_FOR_CREATION = ( <type> [ , ... ] ) ]
AS $$
blocked_creation_rules:
- object_type: <OBJECT_TYPE>
block_when: "<SQL expression>"
$$;
Within the expression, you can reference attributes of the creation request using SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', '<property>'). There are 6 properties: IS_TEMPORARY / IS_TRANSIENT / WAREHOUSE / EXTERNAL_VOLUME / DATABASE / SCHEMA, and all return values are strings (Boolean types are compared with = 'TRUE').
Prerequisites
- Policy creation:
CREATE FEATURE POLICYprivilege on the schema where the policy is stored - Policy application:
APPLY FEATURE POLICYprivilege on the account, andAPPLYorOWNERSHIPprivilege on the Feature Policy to be applied - Edition requirements are not explicitly stated in the documentation (operation has been confirmed on a trial account)
Verification was conducted on August 21 and 23, 2026 (Japan time) on an account in the AWS Tokyo region. The role used throughout is ACCOUNTADMIN.
Preparation
Create a DB for storing policies and a DB to which policies will be applied.
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE DATABASE FP_POLICY_DB; -- For storing policies
CREATE SCHEMA FP_POLICY_DB.POLICIES;
CREATE OR REPLACE DATABASE FP_TEST_DB; -- Target for policy application
CREATE OR REPLACE DATABASE FP_TEST_DB2; -- For priority verification
What I Tried
Conventional: All-or-nothing per type
For comparison, let's first use the conventional BLOCKED_OBJECT_TYPES_FOR_CREATION to prohibit task creation.
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TASKS_ALL
BLOCKED_OBJECT_TYPES_FOR_CREATION = (TASKS)
COMMENT = 'Block all task creation (legacy style)';
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TASKS_ALL;
Let's try creating a task with a warehouse specified.
CREATE TASK FP_TEST_DB.PUBLIC.T_WH
WAREHOUSE = COMPUTE_WH SCHEDULE = '60 MINUTE' AS SELECT 1;

Serverless tasks (without WAREHOUSE specification) also received the same error and were blocked, while table creation succeeded. Because it operates at the type level, tasks are controlled on an all-or-nothing basis.
Notable is that even ACCOUNTADMIN is blocked. Since Feature Policy applies to the DB container rather than roles, even administrator operations are not exceptions.
Let's remove it for the next verification.
ALTER DATABASE FP_TEST_DB UNSET FEATURE POLICY;
rules: Only TEMPORARY tables can be blocked
Let's try rules, the main attraction of this GA. Using the IS_TEMPORARY property as a condition, we prohibit only the creation of TEMPORARY tables.
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TEMP_TABLES
COMMENT = 'Block only temporary tables'
AS $$
blocked_creation_rules:
- object_type: TABLE
block_when: "SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', 'IS_TEMPORARY') = 'TRUE'"
$$;
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TEMP_TABLES;

Here are the results of creating three types of tables.
CREATE TABLE FP_TEST_DB.PUBLIC.T2 (ID INT); -- Success
CREATE TEMPORARY TABLE FP_TEST_DB.PUBLIC.T3 (ID INT); -- Blocked (003001)
CREATE TRANSIENT TABLE FP_TEST_DB.PUBLIC.T4 (ID INT); -- Success



Only TEMPORARY was blocked. TRANSIENT does not match IS_TEMPORARY, so it succeeds (to also block TRANSIENT, add an IS_TRANSIENT condition). This achieves "allow tables, but prohibit only temporary tables" — something impossible with the conventional approach.
rules: Only serverless tasks can be blocked
The WAREHOUSE property of a task is NULL for serverless tasks without a warehouse specification. Using this as a condition, you can implement the classic cost-control requirement of "block only serverless tasks."
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_SERVERLESS_TASKS
COMMENT = 'Block only serverless tasks'
AS $$
blocked_creation_rules:
- object_type: TASK
block_when: "SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', 'WAREHOUSE') IS NULL"
$$;
When I tried to apply it, an error occurred.
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_SERVERLESS_TASKS;

Only one Feature Policy can be directly bound to a single database. If you SET without FORCE when an existing DB-level policy exists, you get an error. This time, I specify FORCE to directly replace it.
-- Directly replace the existing DB-level policy with FORCE
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_SERVERLESS_TASKS
FORCE;

Here are the results of creating tasks in two patterns.
-- Task with warehouse specified → Success
CREATE TASK FP_TEST_DB.PUBLIC.T_WH
WAREHOUSE = COMPUTE_WH SCHEDULE = '60 MINUTE' AS SELECT 1;
-- Serverless task → Blocked (003001)
CREATE TASK FP_TEST_DB.PUBLIC.T_SERVERLESS
SCHEDULE = '60 MINUTE' AS SELECT 1;


As intended, tasks with a warehouse specified could be created, and only serverless tasks were blocked.
Named conditions allow reusing the same condition across multiple types
Expressions named in conditions can be referenced from multiple rules using block_when_any. Combined use with conventional parameters is also possible.
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TEMP_AND_WH
COMMENT = 'Named condition + legacy param combined'
BLOCKED_OBJECT_TYPES_FOR_CREATION = (WAREHOUSES)
AS $$
conditions:
- name: is_temp
expression: "SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', 'IS_TEMPORARY') = 'TRUE'"
blocked_creation_rules:
- object_type: TABLE
block_when_any:
- is_temp
- object_type: STAGE
block_when_any:
- is_temp
$$;
ALTER DATABASE FP_TEST_DB UNSET FEATURE POLICY;
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TEMP_AND_WH;
CREATE TEMPORARY TABLE FP_TEST_DB.PUBLIC.T6 (ID INT); -- Blocked
CREATE TEMPORARY STAGE FP_TEST_DB.PUBLIC.S_TEMP; -- Blocked (Create STAGE denied)
CREATE STAGE FP_TEST_DB.PUBLIC.S1; -- Success



Only TEMPORARY was blocked for both tables and stages. On the other hand, the combined WAREHOUSES did not take effect.
CREATE WAREHOUSE FP_TEST_WH WITH WAREHOUSE_SIZE = 'XSMALL' INITIALLY_SUSPENDED = TRUE;

A warehouse is an account-level object, and its creation is an operation outside the DB container. Therefore, it is not controlled by a policy bound to a DB. The documentation also states that account-level object types are only effective when bound to a Native App.
DESC FEATURE POLICY: YAML is displayed in policy_definition
Let's check the rules using DESC FEATURE POLICY, which also became GA at the same time.
DESC FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_SERVERLESS_TASKS;

The configured YAML policy definition is displayed in the policy_definition property. In my verification environment, when DESC-ing a policy without rules, the policy_definition row itself was not displayed.
Use SHOW and POLICY_REFERENCES to check application status. IN refers to "policies created in that location," and ON refers to "policies being applied," with the ON results including a set_on column indicating where they are applied.
SHOW FEATURE POLICIES IN DATABASE FP_POLICY_DB; -- Lists all 4 created policies
SHOW FEATURE POLICIES ON DATABASE FP_TEST_DB; -- Only the 1 currently applied policy (set_on = DATABASE)
SELECT POLICY_NAME, POLICY_KIND, REF_ENTITY_NAME, REF_ENTITY_DOMAIN, POLICY_STATUS
FROM TABLE(FP_POLICY_DB.INFORMATION_SCHEMA.POLICY_REFERENCES(
POLICY_NAME => 'FP_POLICY_DB.POLICIES.BLOCK_TEMP_AND_WH'));

Verifying Application Priority
For regular databases, DB-level policies take precedence over account-level (FOR ALL DATABASES) policies. Let's try the officially documented technique of constraining the entire account while lifting restrictions for a specific DB using an empty policy.
ALTER DATABASE FP_TEST_DB UNSET FEATURE POLICY;
-- Apply TEMPORARY table prohibition to all regular DBs in the account
ALTER ACCOUNT
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_TEMP_TABLES FOR ALL DATABASES;
CREATE TEMPORARY TABLE FP_TEST_DB.PUBLIC.T8 (ID INT);

FP_TEST_DB2 also received the same error. The message differs from when applied at the DB level, indicating that it originates from the account policy and showing the verification command.
Next, I create an empty policy that "blocks nothing" and apply it only to FP_TEST_DB. It could be created with an empty list ().
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_NOTHING
BLOCKED_OBJECT_TYPES_FOR_CREATION = ()
COMMENT = 'Empty policy to lift account-level restrictions';
ALTER DATABASE FP_TEST_DB
SET FEATURE POLICY FP_POLICY_DB.POLICIES.BLOCK_NOTHING;
CREATE TEMPORARY TABLE FP_TEST_DB.PUBLIC.T8 (ID INT); -- Success
CREATE TEMPORARY TABLE FP_TEST_DB2.PUBLIC.T9 (ID INT); -- Still blocked


The DB-level empty policy took precedence over the account level, and only FP_TEST_DB had its restrictions lifted. Note that in my verification environment, while the account policy was applied, {"target_scopes":["ALL_DATABASES"]} was displayed in the options column of SHOW FEATURE POLICIES ON ACCOUNT.
After verification, remove the account-level application.
ALTER ACCOUNT UNSET FEATURE POLICY FOR ALL DATABASES;
Pitfalls
Expressions that cannot be evaluated are rejected at creation time
The WAREHOUSE property is always NULL for creation requests of objects other than TASK. When this is compared with equality in a TABLE rule, it was rejected at policy creation time rather than at runtime.
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.NULL_TRAP2
AS $$
blocked_creation_rules:
- object_type: TABLE
block_when: "SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', 'WAREHOUSE') = 'COMPUTE_WH'"
$$;

The same error occurs with object_type: ALL. Expressions that cannot be evaluated for the target type are rejected at the creation stage.
NULL evaluation is fail-closed and results in blocking
Even for expressions that pass creation-time validation, there are cases where they evaluate to NULL at runtime. When you create a serverless task with a condition of WAREHOUSE = 'COMPUTE_WH' on a TASK, NULL = 'COMPUTE_WH' becomes NULL.
CREATE FEATURE POLICY FP_POLICY_DB.POLICIES.NULL_TRAP3
AS $$
blocked_creation_rules:
- object_type: TASK
block_when: "SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', 'WAREHOUSE') = 'COMPUTE_WH'"
$$;
-- (After applying to FP_TEST_DB)
CREATE TASK FP_TEST_DB.PUBLIC.T_B SCHEDULE = '60 MINUTE' AS SELECT 1;

The behavior is fail-closed — only FALSE allows creation, while TRUE and NULL are blocked — and NULL cases produce a dedicated error message. In practice, COMPUTE_WH specification (TRUE) was blocked and a different warehouse specification (FALSE) succeeded. Be careful, because writing with the intuition that "if the condition doesn't match, it should be allowed" can result in unintended blocking in the NULL branch.
Limitations and Notes
Limitations and Notes
- Policies that are bound cannot be
CREATE OR REPLACE/DROP. UseALTER FEATURE POLICYfor changes, and remove the application first before deleting. - The
CLONEclause cannot be used in policy definitions. - DB objects such as tables or functions with side effects cannot be referenced in rules expressions.
- When replicating account-level policy references, if the policy storage DB is not included in the replication group, it will not be enforced at the replication target.
Closing
With Feature Policy Rules, control over object creation has evolved from "entire type" to "conditional." Practical policies for cost control and governance — such as prohibiting only serverless tasks or temporary tables — can be enforced for all users including ACCOUNTADMIN. Just be careful during policy design that NULL evaluation is fail-closed and results in blocking.
I hope this article is helpful to someone!
