GRANT — アクセス権限を定義する
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ]table_name
[, ...] | ALL TABLES IN SCHEMAschema_name
[, ...] } TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | INSERT | UPDATE | REFERENCES } (column_name
[, ...] ) [, ...] | ALL [ PRIVILEGES ] (column_name
[, ...] ) } ON [ TABLE ]table_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { SEQUENCEsequence_name
[, ...] | ALL SEQUENCES IN SCHEMAschema_name
[, ...] } TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } ON DATABASEdatabase_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON DOMAINdomain_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPERfdw_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVERserver_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON { FUNCTIONfunction_name
( [ [argmode
] [arg_name
]arg_type
[, ...] ] ) [, ...] | ALL FUNCTIONS IN SCHEMAschema_name
[, ...] } TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGElang_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON LARGE OBJECTloid
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMAschema_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACEtablespace_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON TYPEtype_name
[, ...] TOrole_specification
[, ...] [ WITH GRANT OPTION ] ここでrole_specification
は以下の通りです。 [ GROUP ]role_name
| PUBLIC | CURRENT_USER | SESSION_USER GRANTrole_name
[, ...] TOrole_name
[, ...] [ WITH ADMIN OPTION ]
GRANT
には基本的に2つの種類があります。
1つはデータベースオブジェクト(テーブル、列、ビュー、外部テーブル、シーケンス、データベース、外部データラッパ、外部サーバ、関数、手続き言語、スキーマ、テーブル空間)に対する権限の付与、もう1つはロール内のメンバ資格の付与です。
これらの種類は多くの点で似ていますが、説明は別々に行わなければならない程違いがあります。
この種類のGRANT
コマンドはデータベースオブジェクトの特定の権限を1つ以上のロールに付与します。
既に権限が他のロールに付与されている場合でも、追加として付与されます。
1つ以上のスキーマ内の同じ種類のオブジェクトすべてに対して権限を付与するオプションも存在します。
この機能は現在テーブル、シーケンス、関数のみでサポートされます。
(しかしALL TABLES
にはビューおよび外部テーブルが含まれるとみなされていることに注意してください。)
PUBLIC
キーワードは、今後作成されるロールを含む、全てのロールへの許可を示します。
PUBLIC
は、全てのロールを常に含む、暗黙的に定義されたグループと考えることができます。
個々のロールは全て、ロールに直接許可された権限、ロールが現在属しているロールに許可された権限、そして、PUBLIC
に許可された権限を合わせた権限を持っています。
WITH GRANT OPTION
が指定されると、権限の受領者は、その後、他にその権限を与えることができます。
グラントオプションがない場合、受領者はこれを行うことができません。
グラントオプションはPUBLIC
には与えることができません。
所有者(通常はオブジェクトを作成したユーザ)はデフォルトで全ての権限を保持しているため、オブジェクトの所有者に権限を許可する必要はありません (ただし、オブジェクトの作成者が、安全性のために自らの権限を取り消すことは可能です)。
オブジェクトを削除する権限や何らかの方法でオブジェクトの定義を変更する権限は、付与可能な権限として扱われません。 これらの権限は、所有者固有のものであり、許可したり取り消したりすることはできません。 (しかし、オブジェクトを所有するロール内のメンバ関係を付与したり取り消すことで、同等な効果を得ることができます。 後で説明します。) 所有者は、オブジェクトに対する全てのグラントオプションも暗黙的に保持しています。
PostgreSQLは、一部の種類のオブジェクトに対し、デフォルトの権限をPUBLIC
に付与します。
デフォルトでは、テーブル、列、スキーマ、テーブル空間に関してPUBLIC
に与えられるアクセス権限はありません。
他の種類のオブジェクトでは、PUBLIC
に与えられる権限は次の通りです。
データベースではCONNECT
およびCREATE TEMP TABLE
権限、関数ではEXECUTE
権限、言語ではUSAGE
権限です。
もちろんオブジェクトの所有者はデフォルトで与えられた権限と明示的に与えられた権限の両方をREVOKE
することができます。
(最大限の安全性を得るには、オブジェクトを作成したトランザクションと同じトランザクション内でREVOKE
コマンドを発行してください。
そうすれば、他のユーザがそのオブジェクトを使用できる隙間はなくなります)。
また、これらの初期デフォルト権限の設定はALTER DEFAULT PRIVILEGESコマンドを使用して変更可能です。
設定可能な権限は以下のものです。
指定したテーブル、ビュー、シーケンスの任意の列あるいは指定した列リストに対するSELECTを許可します。
また、COPY TOの使用も許可します。
存在する列の値をUPDATEやDELETEで参照するためにも、この権限は必要です。
シーケンスでは、この権限によってcurrval
関数を使用することができます。
ラージオブジェクトでは、この権限によってオブジェクトを読み取ることができます。
指定したテーブルへの新規の行のINSERTを許可します。
列リストが指定された場合は、これらの列のみをINSERT
コマンド内で設定することができます(従って、その他の列はデフォルト値となります)。
また、COPY FROMの使用も許可します。
指定したテーブルの任意の列あるいは指定した列リストに対するUPDATEを許可します。
(実際には、単純ではないUPDATE
コマンドはすべて、SELECT
権限を同様に必要とします。
どの行を更新すべきかを決めるため、または、列の新しい値を計算するため、またはその両方のため、テーブル列を参照する必要があるからです。)
SELECT ... FOR UPDATE
およびSELECT ... FOR SHARE
も、SELECT
権限に加えて、少なくとも1つの列に対するこの権限を必要とします。
シーケンスでは、この権限によりnextval
およびsetval
関数の使用が許可されます。
ラージオブジェクトでは、この権限によりオブジェクトの書き出しや切り詰めを行うことができます。
指定したテーブルからの行のDELETEを許可します。
(実際には、単純ではないDELETE
コマンドはすべて、SELECT
権限を同様に必要とします。
どの行を削除すべきかを決めるためにテーブルの列を参照する必要があるからです。)
指定したテーブルに対してTRUNCATEを行うことができます。
外部キー制約を作成するには、参照する側と参照される側の両方の列に対して、この権限を持っていなければなりません。 この権限はテーブルのすべての列に付与することも、特定の列のみに付与することもできます。
指定したテーブル上のトリガの作成を許可します (CREATE TRIGGER文を参照してください)。
対象がデータベースの場合は、データベース内での新規スキーマの作成を許可します。
対象がスキーマの場合は、スキーマ内での新規オブジェクトの作成を許可します。 既存のオブジェクトの名前を変更するには、オブジェクトを所有し、かつ、そのオブジェクトが入っているスキーマに対してこの権限を保持していなければなりません。
対象がテーブル空間の場合は、テーブル空間内でのテーブルとインデックス、一時ファイルの作成と、デフォルトのテーブル空間としてこのテーブル空間を持つデータベースの作成を許可します (この権限の取り消しによって既存のデータベースやスキーマの配置が変わることはないことに注意してください)。
ユーザは指定されたデータベースに接続することができます。
この権限は(pg_hba.conf
で組み込まれる制限の検査に加え)接続開始時に検査されます。
指定したデータベースの使用中に一時テーブルを作成することを許可します。
指定された関数、さらにその関数で実装されている任意の演算子の使用を許可します。 これは、関数に適用することができる唯一の権限です (この構文は集約関数についても同じように機能します)。
対象が手続き言語の場合、その言語で関数を作成することを許可します。 これは、手続き言語に適用することができる唯一の権限です。
対象がスキーマの場合、指定したスキーマに含まれるオブジェクトへのアクセスを許可します(オブジェクト自体の権限要件も満たされている必要があります)。 本質的には、この権限によってスキーマ内のオブジェクトを「検索」する権限が認められます。 この権限がなくても、例えばシステムテーブルを問い合わせることでオブジェクト名を知ることは可能です。 また、この権限を取り消した後でも、存在し続けているバックエンドがこうした検索を以前に実行していた文を持っている可能性があります。 このため、これはオブジェクトへのアクセスを防ぐ、完全に安全な方法ではありません。
対象がシーケンスの場合、この権限はcurrval
およびnextval
関数の使用を許可します。
対象が型あるいはドメインの場合、この権限により、テーブル、関数、その他のスキーマオブジェクトの作成の際に、この型またはドメインを使用できるようになります。 (問い合わせにおけるその型の値に対する操作など、一般的な型の「使用」を制御するものではないことに注意してください。 その型に依存したオブジェクトが作成されることを防止するだけです。 この権限の主な目的は、どのユーザが型に依存するものを作成するかを制御することです。 そのようなオブジェクトが作成されると、所有者がその型を後で変更できなくなるかもしれないからです。)
対象が外部データラッパの場合、この権限を与えられると外部データラッパを使用する新しいサーバを作成することができます。
対象がサーバの場合、この権限を与えられると、サーバを使用する外部テーブルの作成を行うことができ、サーバと関連し自身が所有するユーザのユーザマップを作成、変更、削除を行うことができます。
利用可能な全ての権限を一度に付与します。
PRIVILEGES
キーワードはPostgreSQLでは省略可能ですが、厳密なSQLでは必須です。
その他のコマンドの実行に必要な権限は、そのコマンドのリファレンスページにて示されています。
この種類のGRANT
コマンドは、ロール内のメンバ資格を1つ以上の他のロールに付与します。
これによりロールに付与された権限が各メンバに与えられるので、ロール内のメンバ資格は重要です。
WITH ADMIN OPTION
が指定された場合、メンバはロール内のメンバ資格を他に付与することができるようになります。
また同様にロール内のメンバ資格を取り消すこともできるようになります。
アドミンオプションがないと、一般ユーザは他への権限の付与や取り消しを行うことができません。
ロールはそれ自体についてのWITH ADMIN OPTION
を保持しているとはみなされませんが、データベースセッションのユーザがロールにマッチする場合について、ロール内のメンバ資格を付与あるいは取り消しを行うことができます。
データベーススーパーユーザはすべてのロール内のメンバ資格を誰にでも付与したり、取り消したりすることができます。
CREATEROLE
権限を持つロールは、スーパーユーザロール以外の任意のロール内のメンバ資格の付与、取り上げが可能です。
権限の場合と異なり、ロール内のメンバ資格をPUBLIC
に付与することはできません。
また、このコマンド構文では無意味なGROUP
という単語を受け付けないことに注意してください。
アクセス権限を取り消すには、REVOKEコマンドが使用されます。
PostgreSQL 8.1から、ユーザとグループという概念は、ロールと呼ばれる1種類の実体に統合されました。
そのため、付与者がユーザかグループかどうかを識別するためにGROUP
キーワードを使用する必要はなくなりました。
このコマンドではまだGROUP
を使うことはできますが、何の意味もありません。
ユーザは特定の列あるいはテーブル全体に対する権限を持つ場合にSELECT
、INSERT
などを実行することができます。
テーブルレベルの権限を付与してからある列に対する権限を取り消しても、望むことは実現できません。
テーブルレベルの権限は列レベルの操作による影響を受けないからです。
オブジェクトの所有者でもなく、そのオブジェクトに何の権限も持たないユーザが、そのオブジェクトの権限をGRANT
しようとしても、コマンドの実行は直ちに失敗します。
何らかの権限を持っている限り、コマンドの実行は進行しますが、与えることのできる権限は、そのユーザがグラントオプションを持つ権限のみです。
グラントオプションを持っていない場合、GRANT ALL PRIVILEGES
構文は警告メッセージを発します。
一方、その他の構文では、コマンドで名前を指定した権限に関するグラントオプションを持っていない場合に警告メッセージを発します
(原理上、ここまでの説明はオブジェクトの所有者に対しても当てはまりますが、所有者は常に全てのグラントオプションを保持しているものとして扱われるため、こうした状態は決して起こりません)。
データベーススーパーユーザは、オブジェクトに関する権限設定に関係なく、全てのオブジェクトにアクセスできることには注意しなければなりません。
スーパーユーザが持つ権限は、Unixシステムにおけるroot
権限に似ています。
root
と同様、どうしても必要という場合以外は、スーパーユーザとして操作を行わないのが賢明です。
スーパーユーザがGRANT
やREVOKE
の発行を選択した場合、それらのコマンドは対象とするオブジェクトの所有者が発行したかのように実行されます。
特に、こうしたコマンドで与えられる権限は、オブジェクトの所有者によって与えられたものとして表されます。
(ロールのメンバ資格では、メンバ資格は含まれるロール自身が与えたものとして表されます。)
GRANT
およびREVOKE
は、対象のオブジェクトの所有者以外のロールによって実行することもできますが、
オブジェクトを所有するロールのメンバであるか、そのオブジェクトに対しWITH GRANT OPTION
権限を持つロールのメンバでなければなりません。
この場合、その権限は、そのオブジェクトの実際の所有者ロールまたはWITH GRANT OPTION
権限を持つロールによって付与されたものとして記録されます。
例えば、テーブルt1
がロールg1
によって所有され、ロールu1
がロールg1
のメンバであるとします。
この場合、u1
はt1
に関する権限をu2
に付与できます。
しかし、これらの権限はg1
によって直接付与されたものとして現れます。
後でロールg1
の他のメンバがこの権限を取り消すことができます。
GRANT
を実行したロールが、ロールの持つ複数メンバ資格の経路を通して間接的に必要な権限を持つ場合、
どのロールが権限を付与したロールとして記録されるかについては指定されません。
こうした場合、SET ROLE
を使用して、GRANT
を行わせたい特定のロールになることを推奨します。
テーブルへの権限付与によって、SERIAL
列によって関連付けされたシーケンスを含め、そのテーブルで使用されるシーケンスへの権限の拡張は自動的に行われません。
シーケンスへの権限は別途設定しなければなりません。
既存のテーブルおよび列に対する権限についての情報を得るには、以下の例のようにpsqlの\dp
コマンドを使用してください。
=> \dp mytable Access privileges Schema | Name | Type | Access privileges | Column access privileges --------+---------+-------+-----------------------+-------------------------- public | mytable | table | miriam=arwdDxt/miriam | col1: : =r/miriam : miriam_rw=rw/miriam : admin=arw/miriam (1 row)
\dp
で表される項目は、以下のように解釈することができます。
rolename=xxxx -- ロールに与えられた権限 =xxxx -- PUBLICに与えられた権限 r -- SELECT(読み取り(read)) w -- UPDATE(書き込み(write)) a -- INSERT(追加(append)) d -- DELETE D -- TRUNCATE x -- REFERENCES t -- TRIGGER X -- EXECUTE U -- USAGE C -- CREATE c -- CONNECT T -- TEMPORARY arwdDxt -- すべての権限 (テーブル用。他のオブジェクトでは異なります。) * -- 直前の権限に関するグラントオプション /yyyy -- この権限を付与したロール
上記の例は、mytable
テーブルを作成し、次のコマンドを実行した後にmiriam
ユーザに表示されます。
GRANT SELECT ON mytable TO PUBLIC; GRANT SELECT, UPDATE, INSERT ON mytable TO admin; GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;
テーブル以外のオブジェクトでは、その権限を表示することができる他の\d
コマンドがあります。
あるオブジェクトの「アクセス権限」列が空の場合、そのオブジェクトはデフォルトの権限を持っていることを意味します(つまり権限フィールドがNULL)。
所有者に対しては、デフォルト権限として常に全ての権限が含まれていますが、オブジェクトの種類によっては、PUBLIC
の権限が含まれていることがあります。
これについては既に説明した通りです。
オブジェクトに対する最初のGRANT
またはREVOKE
が実行されるとデフォルトの権限がインスタンス化され(例えば{miriam=arwdDxt/miriam}
のように作成されます)、与えられた要求によってこれらを変更します。
同様に、デフォルト以外の権限を持つ列に対してのみ「列アクセス権限」内で項目が表示されます。
(注意:
この目的のために、「デフォルト権限」とはそのオブジェクト種類の組み込みのデフォルト権限を意味します。
ALTER DEFAULT PRIVILEGES
コマンドにより影響をうける権限を持つオブジェクトは常に、このALTER
による影響を含め、明示的な権限項目を持って表示されます。)
所有者が暗黙のうちに持つグラントオプションは、上記のアクセス権限の表示に出力されていない点に注目してください。
*
は、グラントオプションが明示的に誰かに与えられた場合にのみ出力されます。
テーブルfilms
にデータを追加する権限を全てのユーザに与えます。
GRANT INSERT ON films TO PUBLIC;
ビューkinds
における利用可能な全ての権限を、ユーザmanuel
に与えます。
GRANT ALL PRIVILEGES ON kinds TO manuel;
上のコマンドをスーパーユーザやkinds
の所有者が実行した場合は、全ての権限が付与されますが、他のユーザが実行した場合は、そのユーザがグラントオプションを持つ権限のみが付与されることに注意してください。
ロールadmins
内のメンバ資格をユーザjoe
に与えます。
GRANT admins TO joe;
標準SQLでは、ALL PRIVILEGES
内のPRIVILEGES
キーワードは必須です。
標準SQLでは、1つのコマンドで複数のオブジェクトに権限を設定することはサポートしていません。
PostgreSQLでは、オブジェクトの所有者は、自身が持つ権限を取り消すことができます。
例えば、テーブル所有者は自身のINSERT
、UPDATE
、DELETE
、TRUNCATE
権限を取り消すことで、自分にとってそのテーブルが読み取り専用になるよう変更することができます。
これは、標準SQLでは不可能です。
PostgreSQLでは、所有者の権限を、所有者自身により与えられたものとして扱っているため、同様に所有者自身で権限を取り消すことができるようになっています。
標準SQLでは、所有者の権限は仮想的なエンティティ「_SYSTEM」によって与えられたものとして扱っています。
所有者は「_SYSTEM」ではないため、その権限を取り消すことができません。
標準SQLにしたがうと、グラントオプションはPUBLIC
に対して与えることができます。
PostgreSQLではグラントオプションはロールに対して与えることのみをサポートしています。
標準SQLでは、文字セット、照合順序、翻訳といったその他の種類のオブジェクトに対して、USAGE
権限を付与することができます。
標準SQLでは、シーケンスはUSAGE
権限のみを持ちます。
これはPostgreSQLにおけるnextval
関数と等価なNEXT VALUE FOR
式の使用を制御するものです。
シーケンスに関するSELECT
権限とUPDATE
権限はPostgreSQLの拡張です。
シーケンスに関するUSAGE
権限がcurrval
関数にも適用される点もPostgreSQLの拡張です(この関数自体が拡張です)。
データベース、テーブル空間、スキーマ、言語についての権限はPostgreSQLの拡張です。