IPA情報処理試験キーワード

IPA|情報処理技術者試験

GRANT/REVOKE, ロールの粒度・継承・CASCADEまで。データベース権限設計の考え方を完全ガイド

データベースのセキュリティを確保する上で、ユーザーへの適切な権限付与は避けて通れない重要なタスクです。しかし、新入社員の追加や部署異動のたびに、一人ひとりのユーザーに対してGRANT文を個別に実行するのは非常に手間がかかり、設定ミスの原因にもなりかねません。特に大規模なシステムでは、この権限管理の複雑さが運用上の大きなボトルネックとなります。

この煩雑さを解消し、データベースの権限管理を劇的に効率化する仕組みが「ロール(ROLE)」です。ロールとは、役職や役割ごとに必要となる権限をひとまとめにした“権限セット”のようなものです。ユーザーに直接権限を与える代わりに、この「ロール」を与えることで、誰が・どのデータに・何をして良いのかを、より直感的かつシンプルに管理できるようになります。

この記事では、データベーススペシャリスト試験の合格を目指す方に向けて、GRANTREVOKEの基本から、ロール設計の核心となる「権限の粒度」「ロールの継承」、そして少し複雑な「権限取り消しの順序」までを徹底解説します。身近な例えや図解を交えながら、なぜロールが必要なのか、そしてどう設計すれば良いのかを論リカルに解き明かしていきます。

GRANTとREVOKEの基本│「誰に」「何を」「どうする」をSQLで制御

データベースにおける権限管理の最も基本的な操作が、GRANT(権限を与える)とREVOKE(権限を剥奪する)です。これらは、「誰に」「どのデータに対して」「何を許可するか/しないか」をSQLで明確に定義するための命令です。

GRANT:権限を与える魔法の言葉

GRANTは、指定したユーザーに特定の操作権限を付与します。基本構文は非常にシンプルです。

GRANT <権限の種類> ON <オブジェクト名> TO <ユーザー名>;
  • 権限の種類: SELECT(参照)、INSERT(追加)、UPDATE(更新)、DELETE(削除)などがあります。
  • オブジェクト名: 主にテーブル名を指定します。
  • ユーザー名: 権限を与えたいユーザーのアカウント名を指定します。

例えば、営業部のTanakaさんに顧客リストテーブルの閲覧を許可したい場合は、以下のように記述します。

GRANT SELECT ON 顧客リスト TO Tanaka;

REVOKE:権限を剥奪する命令

REVOKEGRANTの逆で、一度与えた権限を取り消すための命令です。

REVOKE <権限の種類> ON <オブジェクト名> FROM <ユーザー名>;

先ほどTanakaさんに与えた権限を剥奪するには、次のように実行します。

REVOKE SELECT ON 顧客リスト FROM Tanaka;

個別管理の限界と「ロール」の必要性(論理展開)

GRANTREVOKEはシンプルで強力ですが、管理対象のユーザーが増えるほど、その運用は複雑化していきます。

身近な例:オフィスの鍵管理

これをオフィスのセキュリティカードで考えてみましょう。
もし、社員一人ひとりに対して「経理室への入室許可」「営業部室への入室許可」「サーバールームへの入室許可」といった権限を個別に設定していたらどうなるでしょうか。
部署異動があれば、古い部屋の権限を削除し、新しい部屋の権限を追加する作業が必要です。新入社員が10人入ってくれば、10人分のカードにそれぞれ手動で権限を設定しなければなりません。これは非常に手間がかかり、設定ミスも起こりやすくなります。

仕事での具体例:人事異動への対応

例えば、あるシステムで経理部のメンバー5名に「請求データ」テーブルへの全操作権限(SELECT, INSERT, UPDATE, DELETE)が与えられているとします。

GRANT SELECT, INSERT, UPDATE, DELETE ON 請求データ TO user_A;
GRANT SELECT, INSERT, UPDATE, DELETE ON 請求データ TO user_B;
-- ... user_Eまで5人分実行 ...

年度末に2名が他部署へ異動し、新たに3名が経理部に配属された場合、DB管理者は以下の作業に追われます。

  1. 異動する2名から権限をREVOKEする(2ユーザー × 4権限 = 8回の剥奪操作の概念)。
  2. 新メンバー3名に権限をGRANTする(3ユーザー × 4権限 = 12回の付与操作の概念)。

このような個別管理は、管理が煩雑になるだけでなく、誰がどの権限を持っているのか全体像を把握しづらいというセキュリティ上のリスクも生み出します。

この問題を解決するために登場するのが、次にご説明する「ロール(ROLE)」という考え方なのです。

ロール(ROLE)による権限管理│「役割」で考える権限の粒度と効率化

GRANTREVOKEによる個別管理の煩雑さを解決するのが、ロール(ROLE)という概念です。ロールとは、簡単に言えば複数の権限をひとまとめにした「権限パッケージ」であり、業務上の「役割」や「役職」に相当します。

ユーザーに権限を一つずつ付与(GRANT)するのではなく、まず役割(ロール)を作り、そのロールに必要な権限を与えておきます。そして、ユーザーにはその役割(ロール)を与えるのです。

身近な例:セキュリティカードの進化

先ほどのオフィスのセキュリティカードの例で言えば、個別の部屋の鍵を渡すのではなく、「経理部カード」「営業部カード」といった役割ごとのマスターカードを用意するようなものです。
この「経理部カード」自体に「経理室」「役員室」「倉庫」へのアクセス権限が登録されています。新人が経理部に配属されたら、管理者は何も考えず「経理部カード」を渡すだけ。人事異動の際は、古いカードを返却してもらい、新しい部署のカードを渡せば権限の付け替えは完了です。非常にスマートですね。

ロールの基本的な使い方:作成から付与まで

ロールの利用は、以下の3ステップで行います。

  1. ロールの作成: CREATE ROLEで役割(空の権限パッケージ)を作る。
  2. ロールへの権限付与: 作成したロールにGRANTで権限を追加していく。
  3. ユーザーへのロール付与: ロールをユーザーにGRANTで割り当てる。

具体的なコード例

経理部のメンバー(user_C, user_D)のためのロールkeiri_roleを作成し、権限を割り当てる例を見てみましょう。

-- 1. 「keiri_role」という名前のロールを作成
CREATE ROLE keiri_role;

-- 2. keiri_roleに、必要な権限を付与
GRANT SELECT, INSERT, UPDATE ON 請求データ TO keiri_role;
GRANT SELECT ON 顧客マスター TO keiri_role;

-- 3. 経理部のメンバーにkeiri_roleを付与
GRANT keiri_role TO user_C;
GRANT keiri_role TO user_D;

こうすることで、user_Cuser_Dkeiri_roleを通じて、「請求データ」の参照・追加・更新権限と、「顧客マスター」の参照権限を持つことになります。

設計のキモ:「権限の粒度」とは?

ロール設計で最も重要なのが「粒度(りゅうど)」の考え方です。これは、権限をどれくらい細かく、あるいは大雑把に設定するかというレベル感を指します。この粒度の設定を間違えると、ロールのメリットが失われてしまいます。

  • 粒度が粗すぎる例:
    administrator_role(管理者ロール)しか作らず、アルバイトにまでこのロールを与えてしまう。これでは、本来必要のないテーブルまで操作できてしまい、セキュリティ上非常に危険です。
  • 粒度が細かすぎる例:
    select_only_role経理部Aさん専用roleのように、操作単位や個人単位でロールを大量に作ってしまう。これではロールの数が増えすぎて、結局、個人に権限を付与するのと変わらない煩雑な管理に戻ってしまいます。

適切な粒度の考え方

適切な粒度は、実際の業務における「役割」をベースに設計するのが基本です。

【表:適切なロール設計の例】

ロール名 想定される役割 付与される主な権限の例
keiri_role 経理担当者 請求データへの全権限、顧客マスターの参照権限
eigyo_role 営業担当者 自身の担当顧客リストへの全権限、商品マスターの参照権限
manager_role 部門長 配下部門の全テーブルへの参照権限
readonly_role 一般・閲覧者 マスタデータなど、全社公開テーブルへの参照権限のみ

このように、「経理」「営業」といった部署単位や、「マネージャー」「一般」といった役職単位でロールを定義することで、管理のしやすさと安全性のバランスを取ることができます。

ロールの継承で階層構造を表現│マネージャーと一般職の権限設計

ロールの強力な機能の一つが「継承」です。これは、あるロールが持つ権限を、別のロールが丸ごと引き継ぐことができる仕組みです。この継承を使うことで、役職の上下関係のような階層的な権限構造をスマートに表現できます。

マネージャーは、一般職のメンバーができる操作はすべてでき、それに加えて管理職固有の操作もできる、といったケースに最適です。

身近な例:親カードと子カード

再びオフィスのセキュリティカードで考えてみましょう。
「営業部カード」(一般職用)には、「営業部フロア」と「自身の担当エリアの倉庫」への入室権限があるとします。

ここで「営業マネージャーカード」を新たに作る際、個別に権限を設定するのではなく、「営業部カード」の機能を継承させます。
これにより、「営業マネージャーカード」は自動的に「営業部フロア」「倉庫」への入室権限を持つことになります。その上で、マネージャー固有の権限である「全部署の倉庫」や「機密情報室」へのアクセス権を追加で付与するのです。

もし将来、「営業部カード」に「休憩室」へのアクセス権が追加されたら、その権限は自動的に「営業マネージャーカード」にも反映されます。これが継承の大きなメリットです。

【図解:ロールの継承イメージ】

eigyo_role(顧客リストへの権限) → (GRANT/継承) → eigyo_manager_role(売上レポートへの権限 + 継承した権限)

↓ (GRANT/ロール付与)

user_Suzuki (マネージャー)

user_Suzukiは、eigyo_manager_roleを通じて、売上レポートへの権限と、継承したeigyo_roleの権限(顧客リストへの権限)の両方を持ちます。

継承の具体的な使い方(SQLコード例)

eigyo_role(営業担当者)の権限を、eigyo_manager_role(営業マネージャー)に継承させる手順を見ていきましょう。

-- まず、ベースとなる一般職ロールを作成し、権限を付与
CREATE ROLE eigyo_role;
GRANT SELECT, INSERT ON 顧客リスト TO eigyo_role;

-- 次に、上位の管理職ロールを作成
CREATE ROLE eigyo_manager_role;

-- ★★★【継承の実行】eigyo_roleをeigyo_manager_roleにGRANTする★★★
-- これにより、eigyo_manager_roleは顧客リストへのSELECT, INSERT権限を引き継ぐ
GRANT eigyo_role TO eigyo_manager_role;

-- 最後に、マネージャー固有の権限を追加で付与
GRANT SELECT, UPDATE ON 売上レポート TO eigyo_manager_role;


-- --- ユーザーへの割り当て ---
-- 一般職のSatoさんにはeigyo_roleを付与
GRANT eigyo_role TO user_Sato;

-- 管理職のSuzukiさんにはeigyo_manager_roleを付与
GRANT eigyo_manager_role TO user_Suzuki;

この結果、

  • user_Satoは「顧客リスト」の参照・追加ができます。
  • user_Suzukiは、「顧客リスト」の参照・追加(継承した権限)に加え、「売上レポート」の参照・更新(固有の権限)もできるようになります。

継承を利用するメリット

  1. メンテナンス性の向上:
    一般職の権限範囲が変更になった場合、eigyo_roleの権限を修正するだけで、その変更が自動的にeigyo_manager_roleにも反映されます。個別に管理職の権限を見直す必要がなく、修正漏れを防げます。
  2. 権限構造の明確化:
    「マネージャーは担当者の権限を含む」という組織のルールを、そのままデータベースの権限設計に落とし込めます。これにより、権限の全体像が直感的で分かりやすくなります。

権限取り消しの連鎖反応│REVOKEの順序とCASCADEオプションを攻略

権限を付与したら、いつかは取り消す(REVOKE)場面もやってきます。基本的には与えた時と逆の操作をするだけですが、権限が他のユーザーやロールに引き継がれている場合、単純には取り消せないことがあります。ここでは、その「依存関係」と「取り消しの順序」について解説します。

「又貸し」を許可する WITH GRANT OPTION

この問題を理解する鍵となるのがWITH GRANT OPTIONという句です。これは、権限を与える際に「あなたにこの権限を与えます。さらに、あなたはこの権限を他の人に与えても良いですよ」という許可をセットで与えるオプションです。

身近な例:マスターキーと合鍵作成の許可

あなたはビルの管理人だとします。
GRANT SELECT ON ... TO user_A;は、user_Aさんに「マスターキー」を一本渡すようなものです。user_Aさんは部屋に入れますが、そのキーの合鍵は作れません。
一方、WITH GRANT OPTIONを付けると、「マスターキー」と一緒に「このキーの合鍵を作成し、他の人に渡す許可」も与えることになります。

-- DB管理者がuser_Aに、権限の「又貸し」を許可する
GRANT SELECT ON 顧客リスト TO user_A WITH GRANT OPTION;

-- user_Aが、与えられた権限をuser_Bに「又貸し」する
-- (このSQLはuser_Aが実行する)
GRANT SELECT ON 顧客リスト TO user_B;

この結果、DB管理者からuser_Aへ、user_Aからuser_Bへと権限が渡っていく依存関係が生まれます。

【図解:権限の依存関係】

DB管理者user_A (WITH GRANT OPTION)user_B

依存関係がある場合の権限取り消し

さて、ここで問題です。DB管理者がuser_Aさんの権限を取り消そうとしたら、どうなるでしょうか?

-- DB管理者がuser_Aの権限を取り消そうとする
REVOKE SELECT ON 顧客リスト FROM user_A; -- エラーになることがある!

user_Aさんの権限は、user_Bさんに引き継がれています。もしuser_Aさんの権限だけを単純に消してしまうと、user_Bさんの権限の出所が不明確になってしまいます。そのため、多くのデータベースではこのような操作はデフォルトでエラー(またはRESTRICT=制限)となります。

解決策:CASCADE で芋づる式に取り消す

この依存関係を解消し、関連する権限をすべてまとめて取り消すためのオプションがCASCADEです。「カスケード」とは「滝」のことで、その名の通り、上流の権限を取り消すと、そこから派生した下流の権限もすべて連鎖的に(芋づる式に)取り消されます。

-- user_Aの権限と、そこから派生したすべての権限を連鎖的に取り消す
REVOKE SELECT ON 顧客リスト FROM user_A CASCADE;

このSQLを実行すると、user_Aさんだけでなく、user_Aさんから権限をもらっていたuser_BさんのSELECT権限も同時に剥奪されます。これが安全な権限の取り消し方です。

ロールの取り消し順序も同様

この「依存」の考え方は、ロールの継承関係にも当てはまります。
例えば、「eigyo_manager_roleeigyo_roleを継承している」という状況で、ベースとなっているeigyo_roleをいきなり削除(DROP ROLE)しようとしても、依存先があるためエラーになります。

【仕事での具体例】
営業部が廃止になり、eigyo_roleeigyo_manager_roleが不要になったとします。この2つのロールを削除する正しい順序は以下の通りです。

  1. 依存している側eigyo_manager_roleを先に削除する。
    DROP ROLE eigyo_manager_role;
  2. 依存元だったeigyo_roleを削除する。
    DROP ROLE eigyo_role;

あるいは、先に継承関係をREVOKEで断ち切ってから削除する方法もあります。権限を取り消す際は、必ず依存関係の末端から解消していく、と覚えておきましょう。

-IPA|情報処理技術者試験
-