は、権限を個人ではなく役割に付与し、人には役割を割り当てるという考え方です。異動や退職のたびに個別の権限を触らずに済みます。EP.7 で扱ったように で本番相当のデータが簡単に増える環境では、権限の設計が実質的な情報管理の要になります。
原則は単純ですが、運用すると必ず複雑になります。権限は増えるだけで減らないからです。この回は、絡まる前に何を決めておくかを扱います。
1. 権限が絡まる仕組み
最初はきれいに始まります。分析担当は読み取り、開発担当は書き込み。ところが例外が発生します。「この人だけこの表も見たい」「この処理だけ書き込みが要る」。
- 1例外的な要望が来る
- 2急ぎなので、その人に直接権限を付ける
- 3同じような要望が別の人から来る。同じ対応をする
- 4半年後、誰が何を見られるか誰も説明できない
4番目に到達すると、外すこともできなくなります。誰かの業務が止まるかもしれないからです。結果、権限は増え続けます。厄介なのは、この過程の各ステップがどれも合理的である点です。急ぎの要望に応えるのは正しく、業務を止めないよう慎重になるのも正しい。正しい判断の積み重ねで、説明できない状態に到達します。
個別対応そのものが悪いのではなく、個別対応が記録されないことが問題です。少なくとも「誰に・何を・なぜ・いつまで」を残せば、後から棚卸しできます。期限を書くだけでも効きます。
2. 階層で考える
のロールは階層を持てます。上位のロールは下位のロールが持つ権限を継承します。この性質を使うと、権限の重複を減らせます。
| 層 | 役割 | 持つ権限 |
|---|---|---|
| 機能ロール(職務) | 分析担当、開発担当など | 人に割り当てるのはここ |
| アクセスロール(対象) | この表を読める、あの表に書ける | 実際の権限を持つ |
人に割り当てるロールと、実際の権限を持つロールを分けるのが要点です。こうすると、権限の付け替えは下の層だけで済み、人への割り当てを触らずに済みます。
-- 下の層: 対象ごとの権限を持つロールCREATE ROLE ar_analytics_read;GRANT USAGE ON DATABASE prod TO ROLE ar_analytics_read;GRANT USAGE ON SCHEMA prod.analytics TO ROLE ar_analytics_read;GRANT SELECT ON ALL TABLES IN SCHEMA prod.analytics TO ROLE ar_analytics_read;-- 今後作られる表にも自動的に適用するGRANT SELECT ON FUTURE TABLES IN SCHEMA prod.analytics TO ROLE ar_analytics_read;
-- 上の層: 人に割り当てる職務ロールCREATE ROLE fr_analyst;GRANT ROLE ar_analytics_read TO ROLE fr_analyst;GRANT USAGE ON WAREHOUSE wh_analytics TO ROLE fr_analyst;
-- 人には職務ロールだけを割り当てるGRANT ROLE fr_analyst TO USER yamada;`FUTURE TABLES` の指定が実務では効きます。これがないと、新しい表を作るたびに権限を付け直すことになり、必ず漏れます。「新しく作った表が見えない」という問い合わせの多くは、ここが原因です。
3. 最小限から始める
設計の話をすると細かく分けたくなりますが、最初から細かく作ると破綻します。管理する対象が増え、しかもその大半は使われません。
- 職務ロールは少数から — 分析、開発、運用の3つ程度で始める
- アクセスロールは対象の単位で — スキーマ単位が扱いやすい
- 例外は作らず、まず役割を見直す — 例外が続くなら、それは新しい職務
- 分けるのは、実際に困ってから — 想像で分けない
3番目が判断の要点です。同じ例外が3回来たら、それは例外ではなく役割です。個別対応を積むのではなく、新しい職務ロールとして定義したほうが、結果的に管理が楽になります。逆に、1回しか来ていない要望のために役割を作ると、使われないロールが増えるだけになります。回数を判断材料にすると、この両方を避けられます。
4. 誰が何を見られるかを点検する
設計しても、時間が経てば実態はずれます。定期的に点検する必要があります。幸い、権限の付与状況は SQL で参照できます。
-- 現在有効な権限の付与状況SELECT grantee_name AS 付与先ロール, privilege AS 権限, granted_on AS 対象種別, table_catalog || '.' || COALESCE(table_schema, '') || '.' || COALESCE(name, '') AS 対象, created_on AS 付与日FROM snowflake.account_usage.grants_to_rolesWHERE deleted_on IS NULL AND granted_on IN ('TABLE', 'VIEW', 'SCHEMA')ORDER BY 付与先ロール, 対象;-- 過去90日間、一度も使われていないロールWITH used AS ( SELECT DISTINCT role_name FROM snowflake.account_usage.query_history WHERE start_time >= DATEADD(day, -90, CURRENT_TIMESTAMP()))SELECT r.name AS ロール, r.created_on AS 作成日, DATEDIFF(day, r.created_on, CURRENT_DATE()) AS 経過日数FROM snowflake.account_usage.roles rLEFT JOIN used u ON u.role_name = r.nameWHERE r.deleted_on IS NULL AND u.role_name IS NULLORDER BY r.created_on;90日間一度も使われていないロールは、削除の候補です。ただしまれにしか動かない重要な処理が使っている可能性があるため、いきなり消さず、対象者に確認してから外してください。
いきなり削除せず、割り当てを外して様子を見るほうが安全です。問題が出れば戻せます。この手順を踏むと、権限の整理に対する心理的な抵抗が下がります。
5. 見せる範囲を列や行で絞る
表そのものへの権限だけでなく、列や行の単位で見せる範囲を変えたい場面があります。個人情報を含む列を、一部の役割にだけ見せるといったケースです。
実現方法は複数あり、ビューを用意するという素朴な方法でも成立します。ただし、ビューを増やすとどのビューが正なのかが分からなくなるという別の問題が生まれます。
| 方法 | 利点 | 注意点 |
|---|---|---|
| 用途別のビューを作る | 仕組みが単純で分かりやすい | ビューが増え、どれが正かが曖昧になる |
| 列に加工を適用する | 元の表を1つに保てる | 設定の存在が見えにくい |
| 行を条件で絞る | 同じ表で人ごとに違う範囲を返せる | 条件の管理が必要 |
どの方法でも共通して重要なのは、設定の存在が見えることです。「この列はある役割からは加工されて見える」という事実が、コードにも文書にも残っていないと、数値が合わない原因として延々調査されることになります。見ている人によって違う値が返る、という状況は再現性がないため調査が極端に難しくなります。データ基盤トラブル事件簿 EP.06 で扱った「数字が合わない」の原因として、この種の設定が潜んでいることがあります。
6. 決めておくこと
最後に、最初に決めておくと後が楽になる項目を挙げます。
- 1命名規則 — 職務ロールと権限ロールが名前で区別できること
- 2新しい表への既定の扱い — 自動で権限が付くようにしておく
- 3例外を出すときの記録 — 誰に・何を・なぜ・いつまで
- 4棚卸しの頻度 — 四半期に一度でも、決めておけば実施される
- 5機微な列の扱い方針 — どの方法で絞るかを統一する
3番目の「いつまで」が最も効きます。期限があれば、棚卸しのときに判断できます。期限がなければ、その権限は永久に残ります。これは EP.7 で扱った複製の管理と同じ構造で、作るときに終わりを決めておくというだけの話です。作る側にとっては一手間ですが、後から判断する人にとっては決定的な情報になります。
権限は増えるだけで減らないという前提で設計する。人に割り当てるロールと権限を持つロールを分け、新しい表には自動で権限が付くようにする。最初は少数から始め、同じ例外が繰り返されたら新しい役割として定義する。定期的に使われていないロールを洗い出し、外す前に無効化で試す。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。