Snowsightの実行ボタンを押した瞬間、赤い帯で SQL access control error: Insufficient privileges to operate on ... が表示されます。あの瞬間の脱力感は、何度経験しても慣れません。ただ、このエラーは見た目ほど厄介ではありません。文面の operate on の直後 に必要なオブジェクトとアクションが書かれているので、そこを起点に権限を辿り直せば、たいていは数分で抜け出せます。
この記事では、エラー画面から検索でたどり着いた前提で、原因の本質、切り分けSQL、ケース別の修正、再発防止までをまとめます。コピペで使える GRANT 文も添えています。

結論:エラーの本質は「現在のロール × 対象オブジェクト × アクション」の不一致
まず腹落ちさせたいのは、Snowflakeの権限は ロールに紐づく という点です。ユーザー個人に直接権限が付くわけではありません。実行中のロールが対象オブジェクトに対して該当アクションの権限を持っていなければ、即座にこのエラーになります。
つまり、追うべき変数は三つだけです。「いま何のロールで動いているか」「対象オブジェクトは何か」「動詞は何か(SELECT?CREATE?MODIFY?)」。エラー文の operate on の後ろを読めば、後ろ二つは即座にわかります。残るは現在ロールの確認です。
ちなみに同じ権限まわりでも、テーブル名自体が見えない場合は Object does not exist or not authorized エラーの正体|Snowflakeでテーブルが見えない時の最短デバッグ 側のパターンに近いです。エラー文を読み分けて入口を間違えないようにしたいところです。
切り分けに使う確認SQL一式
調査は、上から順に流すだけで足ります。現場ではこの順番で投げて、どの行で「あれ?」となるかを見ています。
-- 1. 現在ロールとセカンダリロール
SELECT CURRENT_ROLE(), CURRENT_SECONDARY_ROLES();
-- 2. 自分が持っているロール一覧
SHOW ROLES;
SHOW GRANTS TO USER my_user;
-- 3. 現在ロールに付与されている権限の棚卸し
SHOW GRANTS TO ROLE my_role;
-- 4. 対象オブジェクトに対して付与されている権限を逆引き
SHOW GRANTS ON TABLE my_db.my_schema.orders;
-- 5. データベース・スキーマのUSAGEが通っているかを直撃確認
SHOW GRANTS ON DATABASE my_db;
SHOW GRANTS ON SCHEMA my_db.my_schema;
-- 6. ユーザーのデフォルトロールを確認(セッション開始時の挙動と一致しているか)
DESC USER my_user;
慣れてくると、operate on の直後の動詞を読んで必要権限を逆引きできるようになります。たとえば「to alter this table」とあれば OWNERSHIP か MODIFY、ストアドプロシージャ実行で出ているなら USAGE、といった具合です。
ケース別の解決パターン
切り分けSQLの結果を見ながら、当てはまるケースに飛んでください。だいたい五つの型に収束します。
ケース1: ロールにそもそもオブジェクト権限がない
もっとも素直なケースです。SHOW GRANTS TO ROLE を流しても対象テーブルが出てきません。アクションに応じて必要な権限を付与します。
-- 読み取りだけ必要なら
GRANT SELECT ON TABLE my_db.my_schema.orders TO ROLE analyst_role;
-- 書き込みも必要なら
GRANT INSERT, UPDATE, DELETE ON TABLE my_db.my_schema.orders TO ROLE etl_role;
-- スキーマ配下の全テーブルに一括付与
GRANT SELECT ON ALL TABLES IN SCHEMA my_db.my_schema TO ROLE analyst_role;
ケース2: USAGE の連鎖が切れている
テーブルへの SELECT は付いているのに、エラーが消えません。これは典型的な落とし穴です。Snowflakeでは データベース → スキーマ → オブジェクト という階層のすべてに USAGE が通っていないと、下層オブジェクトに触れません。
GRANT USAGE ON DATABASE my_db TO ROLE analyst_role;
GRANT USAGE ON SCHEMA my_db.my_schema TO ROLE analyst_role;
GRANT USAGE ON WAREHOUSE compute_wh TO ROLE analyst_role;
ウェアハウスの USAGE 漏れも同じ顔をして出てきます。クエリを実行するには計算リソースの利用権限が要る、という当たり前を見落とすと長く溶けてしまいます。
ケース3: USE ROLE を忘れている
権限自体は付与済みなのに、セッションがデフォルトロール(PUBLIC など)のまま動いていることがあります。これは SELECT CURRENT_ROLE() を一発撃てば判明します。
USE ROLE analyst_role;
USE WAREHOUSE compute_wh;
USE DATABASE my_db;
USE SCHEMA my_schema;
Snowsight右上のロール切替UIをクリックして変えても直ります。BIツールや Snowflakeにログインできない時の対処法|MFA・IP・SSO切り分け完全ガイド で扱ったような外部接続経由の場合は、接続文字列やプロファイル設定にロールが明示されているかも確認したいところです。
ケース4: Future Grants の漏れ
「昨日まで動いていたのに、新しく作ったテーブルだけエラー」というパターンです。既存オブジェクトには GRANT ON ALL で一括付与済みでも、後から作成されたオブジェクトには権限が継承されません。これを埋めるのが FUTURE GRANTS です。
-- スキーマ配下に今後作られる全テーブルへ自動付与
GRANT SELECT ON FUTURE TABLES IN SCHEMA my_db.my_schema TO ROLE analyst_role;
-- ビューやステージも同様に
GRANT SELECT ON FUTURE VIEWS IN SCHEMA my_db.my_schema TO ROLE analyst_role;
ケース5: ロール継承(親子関係)の確認漏れ
カスタムロール設計では、業務ロールにアクセスロールをぶら下げる構造をとることが多いです。子ロールに権限を付けても、親ロールに継承されていなければ実行ユーザーは使えません。
-- accessロールをbusinessロールに継承させる
GRANT ROLE access_orders_read TO ROLE analyst_business;
-- 継承ツリーを確認
SHOW GRANTS OF ROLE access_orders_read;

エラー対象オブジェクト × 必要権限のチェックリスト
動詞から必要権限を逆引きできる早見表です。エラー文の operate on 直後と並べて読むと、撃つべき GRANT がすぐ決まります。
| 対象オブジェクト | やりたい操作 | 最低限必要な権限 |
|---|---|---|
| DATABASE / SCHEMA | 配下を参照する | USAGE |
| WAREHOUSE | クエリ実行 | USAGE(または OPERATE) |
| TABLE | SELECT | SELECT + 上位の USAGE |
| TABLE | INSERT / UPDATE / DELETE / TRUNCATE | 該当アクション + USAGE |
| TABLE | ALTER / DROP | OWNERSHIP もしくは MODIFY |
| VIEW | SELECT | SELECT + 参照先テーブルの権限ではなく所有者経由 |
| STAGE | PUT / GET / COPY | READ / WRITE + USAGE |
| PROCEDURE / FUNCTION | 呼び出し | USAGE |
| TASK | 実行/有効化 | OPERATE + USAGE |
| MASKING / ROW ACCESS POLICY | 適用 | APPLY |
マスキングや行レベル制御の権限まわりは Snowflake列レベル・行レベルセキュリティ入門|ポリシーの作り方 で詳しく扱っているので、APPLY 権限で詰まったらそちらも合わせて確認したいところです。
再発防止の習慣
同じ轍を踏まないためにやっておきたいことが、いくつかあります。一度仕組みにしてしまえば、エラーの発生頻度は目に見えて下がります。
まずロール命名規約を決めておきましょう。ACCESS_ / BUSINESS_ / FUNCTIONAL_ のような接頭辞で役割を分け、アクセスロールに権限を集約、業務ロールへ継承させる構造にすると、追加付与が漏れにくくなります。命名の指針は Snowflake命名規則ベストプラクティス|ウェアハウス・ユーザー・ロール にまとめてあります。
続いて Future Grants の設定をスキーマ作成時にセットで仕込みます。新規テーブル作成のたびに GRANT を撃つ運用は確実に破綻します。最初の CREATE SCHEMA 直後に Future を打っておけば、その後の手当ては不要になります。
定期的な棚卸しも効きます。SHOW GRANTS TO ROLE を月次でダンプして差分管理する、あるいは Snowflake監査ログ入門|Account UsageとInformation Schemaの違いをやさしく解説 のように ACCOUNT_USAGE.GRANTS_TO_ROLES から定期SQLで監視するのも有効です。誰が何を持っているかを可視化しておくと、付与漏れも過剰付与も先に潰せます。
FAQ
Q1. ACCOUNTADMIN で実行しているのに同じエラーが出ます
稀ではありますが、USE ROLE ACCOUNTADMIN を打ったつもりでセッションが切り替わっていない、あるいは OWNERSHIP を他ロールに移譲済みのオブジェクトで発生します。SELECT CURRENT_ROLE() で実際の状態を確認し、所有者は SHOW GRANTS ON の出力で見極めましょう。
Q2. SELECT は通るのに INSERT だけ弾かれます
権限はアクション単位で個別管理されます。SELECT と INSERT は別物なので、書き込み側を改めて付与する必要があります。GRANT INSERT ON TABLE ... TO ROLE ... を一行追加すれば抜けられます。
Q3. ビュー経由のSELECTでエラーになります
ビューは 所有者の権限 で参照先テーブルを読みに行く設計なので、ビュー所有ロールが参照先テーブルへの SELECT を持っているかをチェックします。ビューに対する SELECT が利用者ロールに付いているかも併せて確認しましょう。
Q4. Future Grants を設定したのに新テーブルで権限がありません
FUTURE TABLES IN SCHEMA と FUTURE TABLES IN DATABASE の両方が設定されていると、スキーマ側が優先されて期待と異なる挙動になることがあります。スキーマ単位で揃えるのが安全です。設定状況は SHOW FUTURE GRANTS IN SCHEMA my_db.my_schema で確認できます。
Q5. ストアドプロシージャ内だけエラーになります
プロシージャの実行権限モード(EXECUTE AS CALLER か EXECUTE AS OWNER)で必要な権限の持ち主が変わります。CALLERなら呼び出しユーザーのロール、OWNERならプロシージャ所有ロールに必要権限が要ります。DESC PROCEDURE で実行モードを確認するのが先です。
まとめ
「Insufficient privileges to operate on」は、原因の所在が常に文面の中にある親切なエラーです。operate on の直後を読み、現在ロール・対象オブジェクト・アクションの三点を突き合わせましょう。USAGE連鎖、Future Grants、ロール継承の三つを意識下に置いておけば、ほとんどのパターンは短時間で抜けられます。
参考リンク
- GRANT <privileges> – Snowflake公式ドキュメント
- SHOW GRANTS – Snowflake公式ドキュメント
- アクセス制御の概要 – Snowflake公式ドキュメント
- アクセス制御の権限 – Snowflake公式ドキュメント
関連記事
- Object does not exist or not authorized エラーの正体|Snowflakeでテーブルが見えない時の最短デバッグ – 似て非なる「見えない」系エラーの切り分け
- Snowflake命名規則ベストプラクティス|ウェアハウス・ユーザー・ロール – ロール設計の出発点
- Snowflake監査ログ入門|Account UsageとInformation Schemaの違いをやさしく解説 – 権限の棚卸しに使うビュー群
- Snowflake列レベル・行レベルセキュリティ入門|ポリシーの作り方 – APPLY権限が絡むエラーの参考に
- Snowflakeにログインできない時の対処法|MFA・IP・SSO切り分け完全ガイド – 接続段階で詰まる場合はこちら


