![[New Feature] Snowflake's Multi-party Approval is Now Generally Available - We Made Approval Flows Mandatory for Critical Operations](https://images.ctfassets.net/ct0aopd36mqt/wp-refcat-img-3610e3c1ff5961bdb7b464e17f8bf06d/90b168b240005ead852ec1d474bb74fb/snowflake-logo-1200x630-1.png?w=3840&fm=webp)
[New Feature] Snowflake's Multi-party Approval is Now Generally Available - We Made Approval Flows Mandatory for Critical Operations
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 make "review and approval by a second approver" mandatory for critical operations.
In this article, we will verify the entire flow from MPA policy creation to the approval flow, abnormal cases such as rejection and cancellation, and auditing in the Account Usage view, using network policy changes as the protected target.
【Update】
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 Multi-party Approval
MPA is a feature that prevents specified critical operations (protected operations) from being executed by a single administrator alone. When you attempt to execute a protected operation, it is temporarily blocked and an approval request is issued. Only after a separate approver reviews and approves it 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, an attacker cannot independently execute fatal operations such as disabling MFA or revoking Tri-Secret Secure keys.
Protected Operations
The operations that can be protected are divided into the following 3 groups. For each policy rule, 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 | Modifying Time Travel retention periods |
| Policy operations | MODIFY_NETWORK_POLICY | Modifying active network policies and network rules, and modifying assignments to accounts/users |
| Policy operations | MODIFY_SESSION_POLICY | Modifying session policy settings and assignments |
| Policy operations | MODIFY_AUTHENTICATION_POLICY | Modifying authentication policy settings and assignments |
| Policy operations | MODIFY_PASSWORD_POLICY | Modifying 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, an attacker could manipulate who can be authenticated as an approver.
Note: Protection of MODIFY_TRI_SECRET_SECURE requires Business Critical Edition or higher. The edition requirements for the MPA feature itself are not specified in the documentation as of August 2026.
Approval Flow
When you attempt to execute a protected operation, the following 4-step flow occurs.
- When the requester executes the SQL for the protected operation, it is blocked with an
MPA_APPROVAL_REQUIREDerror and arequest_idis returned - When the requester submits a business justification using
SYSTEM$UPDATE_MULTI_PARTY_APPROVAL_JUSTIFICATION(), the request becomes PENDING and the approver is notified - The approver reviews the request in Snowsight and votes to approve or reject it. When the required number of approvals is reached, it becomes APPROVED
- When the requester re-executes the exact same SQL statement that was blocked, it matches the approved request and is executed (within 3 days of approval)
The status of a request transitions through PENDING / APPROVED / EXECUTED / REJECTED / CANCELLED / EXPIRED. If even one approver rejects it, the request immediately becomes REJECTED.
Note that there are 2 patterns for becoming EXPIRED.
- When the required number of approvals is not reached within the validity period (request_duration_days) while still PENDING
- When the request becomes APPROVED but the re-execution is not performed within the 3-day replay window
It is not the case that "re-execution can be performed at any time after approval."
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 users in the approvers 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 to prevent a compromised administrator from independently 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 approvers 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, even if you set required_approvals to 2 or more while leaving it as true, you can still prevent solo execution, but the requester's own vote is included in the approval count. For cases where you want to clearly enforce the four-eyes principle (separating requesters and approvers), a configuration of explicitly setting self_approval_allowed: false with approvers being different users from the requester is appropriate.
Approver Requirements
There are conditions for users who can be designated as approvers.
- Must be a local Snowflake user or 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 also desirable not to grant approvers unnecessarily strong privileges.
Also, users designated as approvers are protected, and login name changes or deprovisioning (deletion) via SCIM are blocked.
Prerequisites
- ACCOUNTADMIN role must be used to configure and manage MPA policies
- Approvers must be users with MFA enrolled and email addresses verified (granting ACCOUNTADMIN is not required)
- In this verification, we use 2 users—KAWABATA_ADMIN (using ACCOUNTADMIN) as the requester who executes the 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 network policy assignment target (not used for login)
Preparation
Creating and Activating a Verification Network Policy
We use MODIFY_NETWORK_POLICY to verify 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 modifying assignments to accounts or users." Since a network policy does not become effective simply by being created—it only becomes active when assigned to an account or user—changes to a policy not assigned anywhere may not be blocked by MPA.
Therefore, we create a dedicated verification user that 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 restriction is 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;

Note: Assigning a network policy to a user is itself within the protection scope of MODIFY_NETWORK_POLICY. If you try to make the assignment after MPA is enabled, approval will be required, so complete the assignment before enabling MPA.
Note: Even for a dedicated verification user, creating it with
DISABLED = TRUEas shown below eliminates the possibility of unintended login from the settings themselves, which is safer (this verification was performed 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 policies, then create the MPA policy. Define 2 rules.
- self_protection_rule: A required rule that protects changes to the MPA settings themselves
- network_policy_rule: A verification rule that protects changes to network policies
The approvers are set to only a different user from the requester (APPROVER_ADMIN), and self_approval_allowed: false is explicitly set. This ensures that KAWABATA_ADMIN cannot approve their own requests and that 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
$$;

Note: For simplicity of verification, we use 1 approver + required_approvals: 1, but the official best practices recommend 2 or more for all rules. In production, it is desirable to list multiple approvers with required_approvals: 2 or more + self_approval_allowed: false (required_approvals must be less than or equal to the number of users in the approvers list).
Let's also check what happens if you try 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']
$$;

Applying (Activating) the Policy to the Account
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 is subject to the MODIFY_MULTI_PARTY_APPROVAL protection).
ALTER ACCOUNT SET MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy;

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

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

According to the documentation, an error in the following format is returned, with the SQL for registering a justification and for cancellation provided directly in the message.
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 justification for the operation. This causes the request to become PENDING and the approver is notified.
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.'
);

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

Approval by the Approver
Log in to Snowsight as the approver (APPROVER_ADMIN) and open Governance & Security » Requests & approvals » Pending » Sent to me, where the pending approval request is displayed.

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

Since required_approvals is set to 1, 1 approval vote causes the request to become APPROVED.
Re-executing the Original SQL
Returning to the requester (KAWABATA_ADMIN), re-execute the SQL that was initially 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');

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

Note: Re-execution must be performed within 3 days of approval. If the deadline passes, the request becomes EXPIRED and the process must start over from a new request. Once execution is complete, the request becomes EXECUTED (a terminal state).
Verifying Abnormal Case Behavior
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.

If even one approver rejects, the request immediately becomes REJECTED and terminates.
Cancellation by the Requester (CANCELLED)
The requester can cancel their own request that is in PENDING state by voting REJECT using SYSTEM$CAST_MULTI_PARTY_APPROVAL_VOTE. In this case only, the comment can be omitted. Requests that have been approved, rejected, or expired cannot be cancelled.
SELECT SYSTEM$CAST_MULTI_PARTY_APPROVAL_VOTE(
'<request_id>',
'REJECT'
);

Self-Approval Behavior (Optional Additional Verification)
Since self_approval_allowed defaults to true, if the requester is included in the approvers list, they can approve their own request. To verify this behavior, we replace the policy with one where the requester is added to the approvers for only the network_policy_rule, and self_approval_allowed is reverted to the default (true).
Note: This configuration is only for verifying self-approval behavior. Since the requester can complete through approval on their own, the four-eyes principle cannot be achieved.
The key point is that replacing the policy itself is subject to the MODIFY_MULTI_PARTY_APPROVAL protection, so this change also requires APPROVER_ADMIN's approval. This also serves as 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
$$;

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

Note: In the flow described in the official documentation, registering a justification only transitions the request to PENDING, and even when self-approval is allowed, the requester must vote Approve themselves in Snowsight, and the original SQL can be re-executed only after the request becomes APPROVED. The behavior observed in this verification—"re-execution succeeds without voting"—differs from this description, so it cannot be definitively stated as the general specification when self-approval is permitted. The same behavior may 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 production, 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 a single compromised administrator account.
Once the self-approval behavior verification is complete, revert to the safe policy definition (self_approval_allowed: false for both rules). This ALTER itself is also subject to MODIFY_MULTI_PARTY_APPROVAL protection, 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 checked via SQL.
-- List of policies
SHOW MULTI PARTY APPROVAL POLICIES;
-- Policy currently applied to the account
SHOW MULTI PARTY APPROVAL POLICIES ON ACCOUNT;
-- Check policy definition (full YAML)
DESC MULTI PARTY APPROVAL POLICY security_db.policies.mpa_verification_policy;



Auditing with Account Usage Views
The history of approval requests can be checked in the Account Usage views. Since you can track who requested which operation, when, and who voted, it 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;

The change history of policies themselves can be checked in the MULTI_PARTY_APPROVAL_POLICIES view.
SELECT name, database, schema, policy_definition, created, last_altered, deleted
FROM snowflake.account_usage.multi_party_approval_policies;

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 the 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 votes are cast from an active session in Snowsight
- Re-execution after approval must be performed with the exact same SQL statement that was blocked, within 3 days
- Cancellation by the requester is only possible for requests in PENDING state
- 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 users in the approvers 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. Even if you set required_approvals to 2 or more while leaving it as true, you can still prevent solo execution, but the requester's own vote is included in the approval count
- Account Usage view latency is up to 120 minutes
- When a policy is modified, PENDING requests are automatically re-evaluated (reconciled) against the new rule configuration
- In the event of a deadlock, such as all approvers becoming unavailable, resolution requires a formal ticket to Snowflake Support (break-glass). It is recommended to assign multiple ACCOUNTADMIN users and periodically review the approvers list
Conclusion
With Multi-party Approval, the control of "critical operations must always be reviewed by two people," which previously 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 you need to be mindful of a configuration of self_approval_allowed: false + required_approvals: 2 or more + approvers separated from the requester. As a countermeasure against solo misconduct or compromise of ACCOUNTADMIN, it seems best to start protection with a self-protection rule + disabling MFA + network policy changes.
I hope this article is helpful to someone!
