新しく作成されたオブジェクトについて、ユーザーが許可拒否エラーを受け取りました。スキーマで新しく作成されたオブジェクトにアクセスするために必要な許可をユーザーに付与するにはどうすればよいですか?
簡単な説明
スキーマで新しく作成されたオブジェクトにユーザーがアクセスするには、スーパーユーザーがオブジェクトに権限を付与する必要があります。
スキーマで新しく作成されたオブジェクトにユーザーがアクセスできない場合、次のエラーが表示されることがあります。
ERROR: permission denied for relation “objectname”.
このエラーは、アクセス権が付与された時点でスキーマに存在する現在のオブジェクトにのみアクセス権が付与された場合に発生します。デフォルトでは、スキーマの下に今後作成されるオブジェクトに対するアクセス権は自動的に付与されません。
この問題を解決するには、ALTER DEFAULT PRIVILEGES コマンドを使用してユーザーにアクセス権限を付与します。
解決方法
スキーマの現在のテーブルと将来のテーブルに許可を付与するには、スーパーユーザーとして次の操作を実行します。
1. スキーマに対する使用アクセス権と、現在スキーマの下に存在するすべてのテーブルに対する SELECT アクセス権を付与するには、次のコマンドを実行します。
注: newtestschema はスキーマの名前に置き換え、newtestuser をユーザーの名前に置き換えてください。
grant usage on schema newtestschema to newtestuser;
grant select on all tables in schema newtestschema to newtestuser;
2. スキーマの下に今後作成されるテーブルの SELECT アクセス権をユーザーに付与するには、次のコマンドを実行します。注: awsuser をスキーマの下でオブジェクトを今後作成するときに使用するユーザー名に、newtestschema をスキーマ名に、newtestuser を今後のオブジェクトにアクセスする必要のあるユーザー名に、それぞれ置き換えてください、
alter default privileges for user awsuser in schema newtestschema grant select on tables to newtestuser;
注: デフォルト権限は新しいオブジェクトにのみ適用されます。ALTER DEFAULT PRIVILEGES を実行しても、既存のオブジェクトに対する権限は変更されません。
3. ユーザーにデフォルトの権限が付与されていることを確認するには、スーパーユーザーとして次のクエリを実行します。
select pg_get_userbyid(d.defacluser) as user,
n.nspname as schema,
case d.defaclobjtype when 'r' then 'tables' when 'f' then 'functions' end
as object_type,
array_to_string(d.defaclacl, ' + ') as default_privileges
from pg_catalog.pg_default_acl d
left join pg_catalog.pg_namespace n on n.oid = d.defaclnamespace;
アクセス権がある場合は、default_privileges 列にユーザーのエントリが表示されます。
これで、スーパーユーザーがスキーマの下に新しいオブジェクトを作成すると、そのユーザーはテーブルに対する SELECT アクセス権を持つようになります。
例
次の例は、この設定から始まります。
- newtestuser という名前のユーザー。スーパーユーザーではありません。
- newtestschema という名前のスキーマと、いくつかのレコードを含むスキーマの下に newtesttable1 という名前のテーブルが 1 つ。
awsuser という名前のスーパーユーザー。次のコマンド例を使用して、newtestschema スキーマと、現在そのスキーマの下に存在するすべてのテーブルの newtestuser にアクセス権を付与します。
grant usage on schema newtestschema to newtestuser;
grant select on all tables in schema newtestschema to newtestuser;
前述のコマンドは、newtestschema の下にある現在のテーブルに対する SELECT アクセス権を newtestuser に付与します。現在、newtestschema の下には newtesttable1 テーブルのみが存在します。newtestuser は newtesttable1 テーブルにアクセスできます。
次に、awsuser は newtestschema の下に newtesttable2 という名前の別のテーブルを作成します。newtestuser が newtestschema.newtesttable2 というテーブルに対して SELECT クエリを実行すると、次のエラーが表示されます。
ERROR: permission denied for relation newtesttable2.
このエラーを解決するために、awsuser は次の操作を実行します。
1. 次のコマンド例を実行して、newtesttable2 というテーブルに対するアクセス権を付与します。
grant select on table newtestschema.newtesttable2 to newtestuser;
2. 次のコマンド例を実行して、awsuser が newtestschema の下に今後作成するすべてのテーブルに対するアクセス権を newtestuser に付与します。
alter default privileges for user awsuser in schema newtestschema grant select on tables to newtestuser;
これで、awsuser が newtestschema の下に newtesttable3 という名前の新しいテーブルをもう 1 つ作成すると、newtestuser は newtesttable3 に対する SELECT アクセス権を持つようになります。
3. newtestuser にデフォルトの権限が付与されていることを確認するために、awsuser は次のクエリを実行します。
select pg_get_userbyid(d.defacluser) as user,
n.nspname as schema,
case d.defaclobjtype when 'r' then 'tables' when 'f' then 'functions' end
as object_type,
array_to_string(d.defaclacl, ' + ') as default_privileges
from pg_catalog.pg_default_acl d
left join pg_catalog.pg_namespace n on n.oid = d.defaclnamespace;
前述のクエリの出力は次のようになります。
user | schema | object_type | default_privileges
awsuser | newtestschema | tables | newtestuser=r/awsuser
出力は、awsuser が newtestschema で awsuser によって作成されたすべての新しいテーブルについて、newtestuser に SELECT 権限を付与していることを示しています。
関連情報
PG_DEFAULT_ACL