メンバとして属しているロールが持つ権限を継承する
ロールが別のロールのメンバ資格を付与されている場合、別のロールが持つ権限を継承することができます。ここでは PostgreSQL でメンバとして属しているロールの権限を継承する方法について解説します。
(Last modified: )
メンバとなったロールの権限を自動で継承するかどうか
ロールが作成された時に INHERIT が指定されていると、そのロールが別のロールのメンバとなった時にそのロールが持つ権限を自動で継承します。
CREATE ROLE コマンドの書式は抜粋すると次のようになっていました。
CREATE ROLE name [ [ WITH ] option [ ... ] ] option: INHERIT | NOINHERIT | LOGIN | NOLOGIN | [ ENCRYPTED ] PASSWORD 'password'
INHERIT を指定した場合は権限を継承し、 NOINHERIT を指定した場合は権限を自動では継承しません。この設定を省略した場合には INHERIT が設定されたものと見なされますので明示的に指定せずに作成されたロールはメンバとなったロールの権限を継承します。
また作成済みのロールに対しては ALTER ROLE コマンドで変更することもできます。
ALTER ROLE role_name [ WITH ] option [ ... ] option: INHERIT | NOINHERIT
※ CREATE ROLE コマンドについての詳細は「ロールを作成する(CREATE ROLE)」、 ALTER ROLE コマンドについての詳細は「ロールの属性を変更する(ALTER ROLE)」を参照されてください。
-- --
それでは実際に試してみます。次の 3 つのロールを作成しました。 admin ロールはグループとして利用するロールで kuma と neko はユーザーとして利用するロールです。
create role admin noinherit;
create role inu inherit login password 'dog';
create role neko noinherit login password 'cat';
admin ロールと neko ロールは noinherit を指定しています。 inu ロールは inherit を指定しています(省略しても同じです)。 psql メタコマンドの \du コマンドで確認してみると admin ロールと neko ロールは 継承なし と表示されています。
次に admin ロールのメンバ資格を inu ロールと neko ロールに付与します。次のように実行してください。
grant admin to inu,neko;
それでは admin ロールに mydb データベースの public スキーマの中に作成された staff テーブルに対して SELECT の権限を追加します。
grant select on staff to admin;
admin ロールに対して権限が追加されました。確認のために psql メタコマンドの \dp コマンドを実行してみます。
\dp
アクセス権限のところをみると admin=r/postgres と表示されており、 admin ロールに r(SELECT) の権限が追加されていることが確認できます。
inu ロールと neko ロールはどちらも admin ロールのメンバですが、 inu ロールはロール作成時に INHERIT が指定されており権限を継承しています。その為、 inu ロールもこの時点で staff テーブルに対して SELECT 権限を持っています。それに対して neko ロールは作成時に NOINHERIT が指定されておりメンバとなっているロールの権限を継承しません。その為、 staff テーブルには何も権限がありません。
それでは確認してみます。 inu ロールで PostgreSQL の mydb データベースに接続し、 staff テーブルに対して SELECT コマンドを実行してみます。
select * from staff;
staff テーブルからデータを取得することができました。
次に neko ロールで PostgreSQL の mydb データベースに接続し、 staff テーブルに対して SELECT コマンドを実行してみます。
select * from staff;
ERROR: テーブル staff へのアクセスが拒否されました とエラーが表示されてデータの取得に失敗しました。
このようにロール作成時に INHERIT か NOINHERIT のどちらを指定するかで、他のロールのメンバになった時に自動で権限を継承するかどうかが決まります。
※ なお自動で権限を継承しない場合でも、 SET ROLE コマンドを使うことでメンバとなっているロールに一時的に変更し、そのロールの権限を使用することができます。詳しくは次のページで解説します。
間接的にメンバとなったロールの権限
ロールA が別の ロールB のメンバになったあと、ロールB がさらに別の ロールC のメンバになると ロールA は ロールC の間接的なメンバとなります。この時、 ロールA が INHERIT が設定されており、さらに ロールB も INHERIT が設定されていた場合には ロールA は ロールB だけでなく ロールC が持っている権限を自動で継承します。
では実際に試してみます。現在 admin ロールは NOINHERIT が設定されています。また inu ロールは INHERIT が設定されており admin ロールのメンバです。ここで新しく wheel ロールを作成し、 admin ロールにメンバ資格を付与します。
create role wheel;
grant wheel to admin;
これで admin ロールは wheel ロールの直接的なメンバとなり、 inu ロールは wheel ロールの間接的なメンバとなります。ただ admin ロールは NOINHERIT が設定されているため、 wheel ロールが持つ権限は admin ロールや inu ロールには継承されません。
実際に wheel ロールに mydb データベースの public スキーマの中に作成された staff テーブルに対して INSERT の権限を追加してみます。
grant insert on staff to wheel;
wheel ロールに対して権限が追加されました。確認のために psql メタコマンドの \dp コマンドを実行してみます。
\dp
アクセス権限のところをみると wheel=a/postgres と表示されており、 wheel ロールに a(INSERT) の権限が追加されていることが確認できます。
それでは確認してみます。 inu ロールで PostgreSQL の mydb データベースに接続し、 staff テーブルに対して INSERT コマンドを実行してみます。
insert into staff values(4, 'Watanabe');
ERROR: テーブル staff へのアクセスが拒否されました とエラーが表示されて INSERT コマンドの実行に失敗しました。現在 inu ロールには wheel ロールが持つ権限が継承されていないためです。
では admin ロールの属性を変更して NOINHERIT を INHERIT へ変更します。スーパーユーザーのロールで次のように実行してください。
alter role admin with inherit;
admin ロールが INHERIT へ変更となりました。この結果、 wheel ロールの権限を admin ロールが継承するようになり、さらに間接的に wheel ロールのメンバである inu ロールも wheel ロールの権限を継承することになりました。
それではあらためて inu ロールで PostgreSQL の mydb データベースに接続し、 staff テーブルに対して INSERT コマンドを実行してみます。
insert into staff values(4, 'Watanabe');
今度はデータの追加に成功しました。このように間接的なメンバであっても、自分のロールおよび直接的にメンバとなっているロールが INHERIT に設定されていれば権限を自動で継承します。
-- --
メンバとして属しているロールの権限を継承する方法について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。