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

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

Snowflake 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 tested 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, we 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

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 possible).

With this GA release, in addition to the conventional type-level 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 Prohibit creating any tasks Prohibit only serverless tasks
Target types 12 types including TASKS, DATABASES, WAREHOUSES Expanded to TABLE, VIEW, STAGE, FUNCTION, PROCEDURE, etc.

Rules are written in YAML in the AS $$ ... $$ of the policy definition. Creation requests where the block_when SQL expression 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, SYS_CONTEXT('SNOWFLAKE$REQUEST', 'GET_OBJECT_PROPERTY', '<property>') is used to reference attributes of the creation request. There are 6 types of 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 verified 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 be targeted for application.

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 application
CREATE OR REPLACE DATABASE FP_TEST_DB2;    -- For priority verification

Tried It Out

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

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) were blocked with the same error, while table creation succeeded. Since control is at the type level, tasks are an all-or-nothing control.

Notably, even ACCOUNTADMIN is blocked. Since Feature Policy applies to the DB container rather than roles, administrator operations are no exception.

Let's remove it before the next verification.

ALTER DATABASE FP_TEST_DB UNSET FEATURE POLICY;

Rules: Block only TEMPORARY tables

Let's try rules, the highlight of this GA release. 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 fall under IS_TEMPORARY, so it succeeds (to also block TRANSIENT, add an IS_TRANSIENT condition). What was impossible with the conventional approach — "allow tables, but prohibit only temporary tables" — has been achieved.

Rules: Block only serverless tasks

The WAREHOUSE property of a task is NULL for serverless tasks without a warehouse specification. Using this as a condition, we can implement the popular cost-control requirement: "prohibit 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 attempting 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. Setting without FORCE when an existing DB-level policy is present results in an error. This time, we 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 two patterns of tasks.

-- Task with warehouse specification → 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 warehouse specification could be created, and only serverless tasks were blocked.

Named conditions allow reusing the same condition across multiple types

Expressions named with conditions can be referenced from multiple rules using block_when_any. Combining 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

Warehouses are account-level objects, and creating them is an operation outside the DB container. Therefore, they are 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 the current verification environment, when DESC-ing a policy without rules, the policy_definition row itself was not displayed.

For checking application status, use SHOW and POLICY_REFERENCES. IN refers to "policies created in that location," and ON refers to "policies applied to that location," 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 priority over account-level (FOR ALL DATABASES) policies. Let's try the officially documented technique of applying an account-wide restriction while releasing the restriction on 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

The same error occurred in FP_TEST_DB2 as well. The message is different from when applied at the DB level, indicating that it originates from an account policy and showing a confirmation command.

Next, we 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 priority over the account level, and the restriction was lifted only for FP_TEST_DB. In the current verification environment, while the account-level 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. Using it in an equality comparison in a TABLE rule results in rejection not at runtime, but at policy creation time.

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 expressions that pass creation-time validation may evaluate to NULL at runtime. When creating 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 through, while TRUE and NULL are blocked, and NULL cases result in a dedicated error message. In practice, COMPUTE_WH specification (TRUE) was blocked, and a different warehouse specification (FALSE) succeeded. Writing with the assumption that "if the condition doesn't match, it should be allowed" can lead to unintentional blocking on the NULL branch, so caution is needed.

Limitations and Notes

Limitations and Notes
  • Policies that are bound cannot be CREATE OR REPLACE / DROP. Use ALTER FEATURE POLICY for modifications, 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 rule expressions
  • When replicating account-level policy references, the policy storage DB must be included in the replication group, otherwise it will not be enforced on the replication target

Closing

With Feature Policy Rules, control over object creation has evolved from "entire type" to "conditional." Practical governance and cost-control policies — such as prohibiting only serverless tasks or temporary tables — can now be enforced on all users, including ACCOUNTADMIN. The only thing to be careful about during policy design is that NULL evaluation is fail-closed and results in blocking.

I hope this article proves useful to someone!


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

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

Snowflakeの詳細を見る

Share this article