GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] ) [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) } ON [ TABLE ] table_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { { USAGE | SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] } ON { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] } TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } ON DATABASE database_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER fdw_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVER server_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON { FUNCTION function_name ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) [, ...] | ALL FUNCTIONS IN SCHEMA schema_name [, ...] } TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE lang_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] } ON LARGE OBJECT loid [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespace_name [, ...] TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT role_name [, ...] TO role_name [, ...] [ WITH ADMIN OPTION ]
GRANTには基本的に2つの種類があります。 1つはデータベースオブジェクト(テーブル、列、ビュー、シーケンス、データベース、異種データラッパ、異種サーバ、関数、手続き言語、スキーマ、テーブル空間)に対する権限の付与、もう1つはロール内のメンバ資格の付与です。 これらの種類は多くの点で似ていますが、説明は別々に行わなければならない程違いがあります。
この種類のGRANTコマンドはデータベースオブジェクトの特定の権限を1つ以上のロールに付与します。 既に権限が他のロールに付与されている場合でも、追加として付与されます。
1つ以上のスキーマ内の同じ種類のオブジェクトすべてに対して権限を付与するオプションも存在します。 この機能は現在テーブル、シーケンス、関数のみでサポートされます。 (しかしALL TABLESにはビューが含まれるとみなされていることに注意してください。)
PUBLICキーワードは、今後作成されるロールを含む、全てのロールへの許可を示します。 PUBLICは、全てのロールを常に含む、暗黙的に定義されたグループと考えることができます。 個々のロールは全て、ロールに直接許可された権限、ロールが現在属しているロールに許可された権限、そして、PUBLICに許可された権限を合わせた権限を持っています。
WITH GRANT OPTIONが指定されると、権限の受領者は、その後、他にその権限を与えることができます。 グラントオプションがない場合、受領者はこれを行うことができません。 グラントオプションはPUBLICには与えることができません。
所有者(通常はオブジェクトを作成したユーザ)はデフォルトで全ての権限を保持しているため、オブジェクトの所有者に権限を許可する必要はありません (ただし、オブジェクトの作成者が、安全性を確保するために自らの権限を取り消すことは可能です)。
オブジェクトを削除する権限や何らかの方法でオブジェクトの定義を変更する権限は、付与可能な権限として扱われません。 これらの権限は、所有者固有のものであり、許可したり取り消したりすることはできません。 (しかし、オブジェクトを所有するロール内のメンバ関係を付与したり取り消すことで、同等な効果を入手することができます。 後で説明します。) 所有者は、オブジェクトに対する全てのグラントオプションも暗黙的に保持しています。
オブジェクトの種類によっては、デフォルト権限として、最初からいくつかの権限がPUBLICに付与されていることがあります。 デフォルトでは、テーブル、列、スキーマ、テーブル空間に関してPUBLICに与えられたアクセス権限はありません。PUBLICに与えられるのは、CONNECT権限、データベースのTEMPテーブルの作成権限、関数のEXECUTE権限、言語のUSAGE権限などです。 もちろんオブジェクトの作成者はこれらの権限を取り消すことができます (最大限の安全性を得るため、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で組み込まれる制限の検査に加え)接続開始時に検査されます。
指定したデータベースの使用中に一時テーブルを作成することを許可します。
指定された関数、さらにその関数で実装されている任意の演算子の使用を許可します。 これは、関数に適用することができる唯一の権限です (この構文は集約関数についても同じように機能します)。
手続き言語において、その言語で関数を作成することを許可します。 これは、手続き言語に適用することができる唯一の権限です。
スキーマにおいて、指定したスキーマに含まれるオブジェクトへのアクセスを許可します(オブジェクト自体の権限要件が満たされている場合)。 基本的には、この権限によってスキーマ内のオブジェクトを"検索"する権限も認められます。 この権限がなくても、例えばシステムテーブルを問い合わせることでオブジェクト名は判りますが、SQLを介してアクセスすることができません。 また、この権限を取り除いた後でも、存在し続けているバックエンドがこうした検索を以前に実行していた文を持っている可能性があります。 このため、これはオブジェクトへのアクセスを防ぐ、完全に安全な方法ではありません。
シーケンスにおいて、この権限はcurrval
およびnextval
関数の使用を許可します。
異種データラッパにおいて、この権限を与えられると異種データラッパを使用する新しいサーバを作成することができます。
サーバにおいて、この権限を与えられると、サーバと関連する、自身が所有するユーザのユーザマップを作成、変更、削除を行うことができます。 またこの権限を与えられると、サーバと関連するユーザマップのオプションを問い合わせることができます。
利用可能な全ての権限を一度に付与します。 PRIVILEGESキーワードはPostgreSQLでは省略可能ですが、厳密にはSQLでは必須です。
その他のコマンドの実行に必要な権限は、そのコマンドのリファレンスページにて示されています。
この種類のGRANTコマンドは、1つ以上のロール内のメンバ資格を付与します。 これによりロールに付与された権限を各メンバに伝えますので、ロール内のメンバ資格は重要です。
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"実体によって与えられたものとして扱っています。 そのため、所有者はその権限を取り消すことができません。
標準SQLでは、文字セット、集合、翻訳、ドメインといったその他の種類のオブジェクトに対して、USAGE権限を付与することができます。
データベース、テーブル空間、スキーマ、言語についての権限はPostgreSQLの拡張です。