[New Feature] Feature Policy Rules is now generally available, so I tried blocking only the creation of TEMPORARY tables and serverless tasks

[New Feature] Feature Policy Rules is now generally available, so I tried blocking only the creation of TEMPORARY tables and serverless tasks

Snowflake's Feature Policy now has conditional rules functionality available as GA. In this article, we verified flexible object creation control using rules and the behavior of DESC FEATURE POLICY, and tried out practical policy designs such as prohibiting serverless tasks and temporary tables.
2026.08.23

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
https://docs.snowflake.com/en/user-guide/feature-policies

https://docs.snowflake.com/en/sql-reference/sql/desc-feature-policy

【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.

https://dev.classmethod.jp/articles/snowflake-community-awards-finalist-activities-review/

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 POLICY privilege on the schema where the policy is stored
  • Policy application: APPLY FEATURE POLICY privilege on the account, and APPLY or OWNERSHIP privilege 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;

2026-08-23_22h15_25

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;

2026-08-23_22h16_17

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

2026-08-23_22h16_59

2026-08-23_22h17_18

2026-08-23_22h17_48

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;

2026-08-23_22h18_54

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;

2026-08-23_22h19_27
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;

2026-08-23_22h20_51

2026-08-23_22h21_24

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

2026-08-23_22h22_21

2026-08-23_22h22_47

2026-08-23_22h23_10

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;

2026-08-23_22h23_40

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;

2026-08-23_22h24_31

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'));

2026-08-23_22h26_05

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);

2026-08-23_22h27_33

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

2026-08-23_22h28_25

2026-08-23_22h28_50

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'"
  $$;

2026-08-23_22h31_18

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;

2026-08-23_22h32_06
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. Use ALTER FEATURE POLICY for changes, and remove the application first before deleting.
  • The CLONE clause 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!


Snowflake World Tour Tokyo 2026に参加しませんか?

Snowflakeの国内最大級イベント「Snowflake World Tour Tokyo」が2026年9月10日(木)・11日(金)にグランドプリンスホテル新高輪にて開催されます。
最新のAI・データ活用事例やライブデモを体感できる無料イベントです。

Snowflake World Tour Tokyoイベントに参加する


Snowflake Community Awards ファイナリストに選出されました

DevelopersIO で Snowflake 記事を執筆している かわばた が、Snowflake Community Awards「RISING COMMUNITY LEADER OF THE YEAR」部門・APJ枠のファイナリストに選ばれました。
最終選考の30%はコミュニティ投票です。記事がお役に立っていたようでしたら、9月15日(火)までにぜひ一票お願いします。フォームの「(4 of 6) RISING COMMUNITY LEADER OF THE YEAR」で Tomohiro Kawabata | Classmethod, Japan を選択、2分ほどで完了します。

投票フォームを開く


Snowflakeの導入支援はクラスメソッドに!

クラスメソッドでは Snowflake の導入を支援しております。
製品の詳細や支援の内容についてお気軽にお問い合わせください。

Snowflakeの詳細を見る

Share this article