[New Feature] Snowflake's Multi-party Approval is now generally available, so we tried making approval flows mandatory for critical operations

[New Feature] Snowflake's Multi-party Approval is now generally available, so we tried making approval flows mandatory for critical operations

Snowflake's Multi-party Approval has reached GA. This feature allows you to require "review and approval by a second approver" for critical operations. Using network policy changes as an example, we actually tested everything from policy creation through the approval flow to error cases.
2026.08.11

This page has been translated by machine translation. View original

This is Kawabata.

With Multi-party Approval (MPA), which became GA on August 4, 2026, you can now require "review and approval by a second approver" for critical operations.

In this article, using network policy changes as the protected target, I will verify the entire flow from MPA policy creation to the approval workflow, abnormal scenarios such as rejection and cancellation, and auditing through the Account Usage view.

https://docs.snowflake.com/en/release-notes/2026/other/2026-08-04-multi-party-approval-ga

https://docs.snowflake.com/en/user-guide/multi-party-approval

Overview of Multi-party Approval

MPA is a feature that prevents specified critical operations (protected operations) from being executed by a single administrator alone. When someone attempts to execute a protected operation, it is temporarily blocked and an approval request is issued. Only after another approver reviews and approves the request can the original operation be executed.

The main motivation is that even if an administrator account is compromised in a ransomware attack or similar incident, the attacker cannot unilaterally execute fatal operations such as disabling MFA or revoking Tri-Secret Secure keys.

Protected Operations

Operations that can be protected are divided into the following 3 groups. For each rule in the policy, you select which operations to protect.

Group Operation Description
Administrative Operations MODIFY_MULTI_PARTY_APPROVAL Changes to MPA policies, rules, and application/removal to accounts (required for all policies). Also covers creation, modification, and deletion of SAML2 security integrations
Administrative Operations DISABLE_MULTI_FACTOR_AUTHENTICATION Disabling MFA and resetting user passwords
Administrative Operations MODIFY_TRI_SECRET_SECURE Enabling/disabling Tri-Secret Secure keys
Administrative Operations MODIFY_PRIVILEGED_ROLE_GRANTS Granting/revoking administrator roles
Administrative Operations MODIFY_CORTEX_GUARDRAILS Modifying Cortex AI guardrails
Administrative Operations MODIFY_DATA_RETENTION_TIME Changing Time Travel retention period
Policy Operations MODIFY_NETWORK_POLICY Modifying active network policies and network rules, changing assignments to accounts/users
Policy Operations MODIFY_SESSION_POLICY Changing session policy settings and assignments
Policy Operations MODIFY_AUTHENTICATION_POLICY Changing authentication policy settings and assignments
Policy Operations MODIFY_PASSWORD_POLICY Changing password policy settings and assignments
Security Integration Operations MODIFY_OAUTH_INTEGRATION Modifying OAuth integrations
Security Integration Operations MODIFY_EXTERNAL_OAUTH_INTEGRATION Modifying External OAuth integrations
Security Integration Operations MODIFY_SCIM_INTEGRATION Modifying SCIM integrations

The reason MODIFY_MULTI_PARTY_APPROVAL also protects SAML2 security integrations is that if SSO settings are modified, the attacker could manipulate who can be authenticated as an approver.

Note: Protection for MODIFY_TRI_SECRET_SECURE requires Business Critical Edition or higher. The edition requirements for the MPA feature itself are not explicitly stated in the documentation as of August 2026.

Approval Flow

When you attempt to execute a protected operation, the flow proceeds in the following 4 steps.

  1. When the requester executes the SQL for a protected operation, it is blocked with an MPA_APPROVAL_REQUIRED error and a request_id is returned
  2. When the requester submits a business justification using SYSTEM$UPDATE_MULTI_PARTY_APPROVAL_JUSTIFICATION(), the request becomes PENDING and the approver is notified
  3. The approver reviews the request in Snowsight and votes to approve or reject. Once the required number of approvals is reached, the status becomes APPROVED
  4. When the requester re-executes the exact same SQL statement that was originally blocked, it matches the approved request and is executed (within 3 days of approval)

The request status transitions through PENDING / APPROVED / EXECUTED / REJECTED / CANCELLED / EXPIRED. If even one approver rejects the request, it immediately becomes REJECTED.

Note that there are 2 patterns for becoming EXPIRED.

  • When the required number of approvals is not reached within the expiration period (request_duration_days) while still in PENDING status
  • When the request becomes APPROVED but the re-execution is not performed within the 3-day replay window

It does not mean that "once approved, re-execution can be performed at any time."

Policy Components

An MPA policy is a schema-level object with a YAML-format definition that can contain multiple rules. The configuration items for each rule are as follows.

Item Required/Optional Default Range
name (rule name) Required - -
operations (protected operations) Required - 1 or more (cannot be empty)
approvers.users (approvers) Required - -
required_approvals (required number of approvals) Optional 2 1–20. Must be less than or equal to the number of approvers in the list
request_duration_days (request expiration) Optional 3 days Maximum 14 days
self_approval_allowed (allow self-approval) Optional true true / false

Note: All policies must have at least one rule that includes MODIFY_MULTI_PARTY_APPROVAL in operations. This is a self-protecting rule designed to prevent a compromised administrator from unilaterally disabling or modifying MPA itself. Also, a single operation can only be included in one rule within the same policy.

Note: self_approval_allowed defaults to true. If the requester is included in the approver list, they can approve their own request and have it counted toward the required number of approvals. Specifying self_approval_allowed: false prevents the requester's own vote from being counted toward the approval count. On the other hand, setting required_approvals to 2 or more while leaving it true still prevents solo execution, but the requester's own vote is included in the approval count. If you require the four-eyes principle, which clearly separates requesters from approvers, it is appropriate to explicitly set self_approval_allowed: false and configure approvers to be different users from the requester.

Approver Requirements

There are conditions for users who can be designated as approvers.

  • Must be a local Snowflake user or a SCIM-managed user (service users are not allowed)
  • Must be enrolled in MFA
  • Must have a verified email address

No additional privileges are required for the approval operation itself, and granting ACCOUNTADMIN to approvers is not a mandatory requirement for MPA. From a least-privilege perspective, it is desirable not to grant approvers unnecessarily strong privileges.

Additionally, users designated as approvers are protected, and login name changes or deprovisioning (deletion) via SCIM is blocked.

Prerequisites

  • ACCOUNTADMIN role must be used to configure and manage MPA policies
  • Approvers must be users with MFA enrollment and verified email addresses (granting ACCOUNTADMIN is not required)
  • In this verification, we use 2 users: KAWABATA_ADMIN (using ACCOUNTADMIN) who executes protected operations, and APPROVER_ADMIN as the approver, plus a dedicated verification user as the network policy assignment target
  • Verification is performed in an environment after the GA on August 4, 2026

Verification Environment

  • Verification period: August 5, 2026 – August 11, 2026
  • Snowflake trial account, Enterprise edition
  • Verification user configuration:
    • KAWABATA_ADMIN: Requester who executes protected operations (using ACCOUNTADMIN)
    • APPROVER_ADMIN: Approver (MFA enrolled, email verified)
    • MPA_TEST_USER: Dedicated verification user as the network policy assignment target (not used for login)

Preparation

Creating and Activating a Verification Network Policy

We will use MODIFY_NETWORK_POLICY for verifying protected operations. What is important here is that the protection scope of MODIFY_NETWORK_POLICY is defined as "modifying active network policies and network rules, and changing assignments to accounts or users." A network policy does not become effective just by being created; it only becomes active when assigned to an account or user, so changes to a policy not assigned anywhere may not be blocked by MPA.

Therefore, we create a dedicated verification user who is not used for login, assign the policy to that user to create an active state. We avoid assigning at the account level due to the risk of lockout.

USE ROLE ACCOUNTADMIN;

-- Dedicated verification user for assignment target (not used for login)
CREATE USER mpa_test_user
  COMMENT = 'MPA verification: network policy assignment target';

-- Verification network policy (no practical restrictions are added since all IPs are allowed)
CREATE NETWORK POLICY mpa_test_network_policy
  ALLOWED_IP_LIST = ('0.0.0.0/0')
  COMMENT = 'MPA verification test policy';

-- Assign to the dedicated verification user to make it active
ALTER USER mpa_test_user SET NETWORK_POLICY = mpa_test_network_policy;

2026-08-05_09h27_47

Note: Assigning a network policy to a user itself is also within the protection scope of MODIFY_NETWORK_POLICY. If you attempt the assignment after enabling MPA, approval will be required, so complete the assignment before enabling MPA.

Note: Even for a dedicated verification user, creating it with DISABLED = TRUE as shown below eliminates the possibility of unintended login at the configuration level, making it safer (this verification was conducted without DISABLED).

CREATE USER mpa_test_user
  DISABLED = TRUE
  COMMENT = 'MPA verification: network policy assignment target; login disabled';

Creating the MPA Policy

Prepare a database and schema for storing the policy, then create the MPA policy. We define 2 rules.

  • self_protection_rule: A required rule that protects changes to the MPA configuration itself
  • network_policy_rule: A verification rule that protects network policy changes

Only a user different from the requester (APPROVER_ADMIN) is set as the approver, and self_approval_allowed: false is explicitly specified. This means KAWABATA_ADMIN cannot approve their own request, and APPROVER_ADMIN's review is always required.

CREATE DATABASE IF NOT EXISTS security_db;
CREATE SCHEMA IF NOT EXISTS security_db.policies;

CREATE MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy
AS $$
description: 'MPA verification policy'
rules:
  - name: self_protection_rule
    description: 'Protect MPA configuration changes'
    operations: [MODIFY_MULTI_PARTY_APPROVAL]
    approvers:
      users: ['APPROVER_ADMIN']
    required_approvals: 1
    self_approval_allowed: false
  - name: network_policy_rule
    description: 'Protect network policy changes'
    operations: [MODIFY_NETWORK_POLICY]
    approvers:
      users: ['APPROVER_ADMIN']
    required_approvals: 1
    self_approval_allowed: false
$$;

2026-08-11_21h05_27

Note: To keep the verification simple, we are using 1 approver + required_approvals: 1, but the official best practice recommends 2 or more for all rules. In production, it is desirable to list multiple approvers, with a combination of required_approvals: 2 or more + self_approval_allowed: false (required_approvals must be less than or equal to the number of approvers in the list).

Let's also check the behavior when attempting to create a policy without defining a rule that includes MODIFY_MULTI_PARTY_APPROVAL.

CREATE MULTI PARTY APPROVAL POLICY security_db.policies.mpa_invalid_policy
AS $$
rules:
  - name: network_policy_only_rule
    operations: [MODIFY_NETWORK_POLICY]
    approvers:
      users: ['APPROVER_ADMIN']
$$;

2026-08-11_21h07_10

Applying the Policy to the Account (Activation)

Apply the created policy to the account using ALTER ACCOUNT. Since this is the initial application before MPA is enabled, this operation itself is not expected to be blocked (replacement or removal after activation becomes a protected operation under MODIFY_MULTI_PARTY_APPROVAL).

ALTER ACCOUNT SET MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy;

2026-08-11_21h13_53

When operating from Snowsight, you can create and activate (Activate) a policy from Governance & Security » Requests & approvals » Multi-party configuration.

2026-08-11_21h15_45

Trying Out the Basic Flow

Confirming That Protected Operations Are Blocked

As the requester (KAWABATA_ADMIN), let's try to execute a change to the active network policy.

ALTER NETWORK POLICY mpa_test_network_policy SET ALLOWED_IP_LIST = ('0.0.0.0/0', '10.0.0.0/8');

2026-08-11_21h43_22

According to the documentation, an error in the following format is returned, and the SQL for registering the justification and for cancellation is provided directly.

Blocked by Multi-party Approval. A request has been created. To proceed, add a justification: "select SYSTEM$UPDATE_MULTI_PARTY_APPROVAL_JUSTIFICATION('94ceb31d-4ee0-4a14-b470-f5036eac52cb', '<reason>');". To cancel: "select SYSTEM$CAST_MULTI_PARTY_APPROVAL_VOTE('94ceb31d-4ee0-4a14-b470-f5036eac52cb', 'REJECT');". Expires: August 14, 2026 at 12:42:56 PM UTC. Request-ID: '94ceb31d-4ee0-4a14-b470-f5036eac52cb'

Submitting the Justification

Using the request_id included in the error message, submit the business reason for the operation. This transitions the request to PENDING and notifies the approver.

SELECT SYSTEM$UPDATE_MULTI_PARTY_APPROVAL_JUSTIFICATION(
  '<request_id>',
  'MPA verification: adding 10.0.0.0/8 to the allowed IP list of the test network policy.'
);

2026-08-11_21h46_06

While the request is in PENDING status, the justification can be updated any number of times. The requester can check their own request status from Snowsight under Governance & Security » Requests & approvals » Pending » Created by me.

2026-08-11_21h46_54

Approval by the Approver

Log in to Snowsight as the approver (APPROVER_ADMIN) and open Governance & Security » Requests & approvals » Pending » Sent to me to see the pending approval request.

2026-08-11_21h48_18

Opening the request allows you to review the target operation, requester, and justification, then choose Approve or Reject. Here we choose Approve.

2026-08-11_21h49_47

Since required_approvals is set to 1, 1 vote of approval transitions the request to APPROVED.

Re-executing the Original SQL

Return to the requester (KAWABATA_ADMIN) and re-execute the SQL that was originally blocked. It matches the approved request and this time executes successfully.

ALTER NETWORK POLICY mpa_test_network_policy SET ALLOWED_IP_LIST = ('0.0.0.0/0', '10.0.0.0/8');

2026-08-11_21h51_28

After approval, only the exact same statement as the SQL that was blocked when the approval request was created can be executed. SQL with changed target objects or settings will not match the approved request and will be treated as a new operation. Let's actually verify this by executing an ALTER with a partial change.

ALTER NETWORK POLICY mpa_test_network_policy SET ALLOWED_IP_LIST = ('0.0.0.0/0', '10.0.0.0/9');

2026-08-11_21h52_39

Note: Re-execution must be performed within 3 days of approval. If the deadline passes, the request becomes EXPIRED and you must start over from a new request. Once execution is complete, the request becomes EXECUTED (a terminal state).

Checking Abnormal Scenarios

Rejection by the Approver (REJECTED)

Create another request for a network policy change, submit a justification, and this time have the approver Reject it. A comment is required for rejection.

2026-08-11_21h54_44

If even one approver rejects the request, it immediately becomes REJECTED and is terminated.

Cancellation by the Requester (CANCELLED)

The requester can cancel their own request in PENDING status by voting REJECT using SYSTEM$CAST_MULTI_PARTY_APPROVAL_VOTE. In this case only, the comment can be omitted. Approved, rejected, or expired requests cannot be cancelled.

SELECT SYSTEM$CAST_MULTI_PARTY_APPROVAL_VOTE(
  '<request_id>',
  'REJECT'
);

2026-08-11_21h58_28

Self-approval Behavior (Optional Additional Verification)

Since self_approval_allowed defaults to true, if the requester is included in the approver list, they can approve their own request. To verify this behavior, let's replace the policy with one where the requester is added to the approvers for the network_policy_rule only and self_approval_allowed is reverted to the default (true).

Note: This configuration is exclusively for verifying self-approval behavior. Since the requester can complete the entire process through approval on their own, the four-eyes principle cannot be achieved.

The key point is that replacing the policy itself is a protected operation under MODIFY_MULTI_PARTY_APPROVAL, so this change also requires APPROVER_ADMIN's approval. This also serves as a confirmation that the self-protecting rule is functioning.

ALTER MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy
AS $$
description: 'MPA verification policy (self approval test)'
rules:
  - name: self_protection_rule
    description: 'Protect MPA configuration changes'
    operations: [MODIFY_MULTI_PARTY_APPROVAL]
    approvers:
      users: ['APPROVER_ADMIN']
    required_approvals: 1
    self_approval_allowed: false
  - name: network_policy_rule
    description: 'Protect network policy changes (self approval test)'
    operations: [MODIFY_NETWORK_POLICY]
    approvers:
      users: ['KAWABATA_ADMIN', 'APPROVER_ADMIN']
    required_approvals: 1
$$;

2026-08-11_22h05_50

After the replacement, KAWABATA_ADMIN created a request for a network policy change and registered a justification using SYSTEM$UPDATE_MULTI_PARTY_APPROVAL_JUSTIFICATION. In this verification environment, re-execution of the original SQL succeeded without voting Approve in the Snowsight approval screen.

2026-08-11_22h16_15

Note: According to the flow in the official documentation, registering the justification only transitions the request to PENDING, and even when self-approval is allowed, the requester themselves must vote Approve in Snowsight and the request must become APPROVED before re-executing the original SQL. Since the behavior observed in this verification — "re-execution succeeds without voting" — differs from this description, it cannot be concluded as the general specification for when self-approval is permitted. The same behavior can also occur if an approved request for the same SQL remains within the 3-day replay window, so please verify in your own account when trying this.

Note: In actual operations, a combination of self_approval_allowed: false and required_approvals: 2 or more is recommended. A configuration that allows self-approval does not provide protection against the compromise of a single administrator account.

After confirming the self-approval behavior, revert to the safe policy definition (both rules with self_approval_allowed: false). This ALTER itself is also a protected operation under MODIFY_MULTI_PARTY_APPROVAL, so APPROVER_ADMIN's approval is required.

-- After the self-approval test, revert to the safe policy definition
-- This ALTER itself is also subject to MODIFY_MULTI_PARTY_APPROVAL approval
ALTER MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy
AS $$
description: 'MPA verification policy'
rules:
  - name: self_protection_rule
    description: 'Protect MPA configuration changes'
    operations: [MODIFY_MULTI_PARTY_APPROVAL]
    approvers:
      users: ['APPROVER_ADMIN']
    required_approvals: 1
    self_approval_allowed: false
  - name: network_policy_rule
    description: 'Protect network policy changes'
    operations: [MODIFY_NETWORK_POLICY]
    approvers:
      users: ['APPROVER_ADMIN']
    required_approvals: 1
    self_approval_allowed: false
$$;

How to Check Policies and Requests

SHOW / DESCRIBE Commands

Policy lists and definitions can be confirmed using SQL.

-- List of policies
SHOW MULTI PARTY APPROVAL POLICIES;

-- Policy currently applied to the account
SHOW MULTI PARTY APPROVAL POLICIES ON ACCOUNT;

-- Checking the policy definition (full YAML)
DESC MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy;

2026-08-11_22h19_19

2026-08-11_22h19_44

2026-08-11_22h20_10

Auditing with Account Usage Views

The history of approval requests can be confirmed using Account Usage views. Since you can trace who requested which operation at what time and who voted, this can also be used for audit purposes.

SELECT
  request_id,
  requester_user_name,
  operation,
  status,
  request_justification,
  required_approvals_count,
  approvers,
  created_time,
  resolved_time
FROM snowflake.account_usage.multi_party_approval_requests
ORDER BY created_time DESC;

2026-08-11_22h20_49

The change history of the policy itself can be confirmed using the MULTI_PARTY_APPROVAL_POLICIES view.

SELECT name, database, schema, policy_definition, created, last_altered, deleted
FROM snowflake.account_usage.multi_party_approval_policies;

2026-08-11_22h21_41

Note: Both views have a latency of up to 120 minutes. They may not be reflected immediately after verification.

Limitations and Notes

Here is a summary of the limitations and notes confirmed through verification and official documentation.

Limitations and Notes
  • Approvers must be local Snowflake users or SCIM-managed users, with MFA enrollment and email address verification required (service users are not allowed). Granting ACCOUNTADMIN is not required
  • Approver voting is performed from an active session in Snowsight
  • Re-execution after approval must be performed within 3 days, using the exact same SQL statement as when it was blocked
  • Cancellation by the requester is only possible for requests in PENDING status
  • A single operation can only be included in one rule within the same policy. Also, required_approvals must be less than or equal to the number of approvers in the list
  • self_approval_allowed defaults to true. Explicitly setting it to false prevents the requester's own vote from being counted toward the approval count. Setting required_approvals to 2 or more while leaving it true still prevents solo execution, but the requester's own vote is included in the approval count
  • Account Usage view latency is up to 120 minutes
  • If the policy is changed, PENDING requests are automatically re-evaluated (reconciled) against the new rule configuration
  • In cases of deadlock, such as all approvers becoming unavailable, the response involves filing a formal ticket with Snowflake Support (break-glass). It is recommended to have multiple ACCOUNTADMIN users assigned and to periodically review the approver list

Closing Thoughts

With Multi-party Approval, the control of "important operations must always be reviewed by 2 people" — which until now could only be enforced through operational rules — can now be enforced as a Snowflake feature. However, it is important to note that self_approval_allowed defaults to true, and the recommended configuration to keep in mind is self_approval_allowed: false + required_approvals: 2 or more + approvers separated from the requester. As a countermeasure against a single ACCOUNTADMIN acting alone or being compromised, it seems best to start by protecting the self-protection rule + MFA disabling + network policy changes.

I hope this article is helpful in some way!


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

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

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


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

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

Snowflakeの詳細を見る

Share this article