PostgreSQL / 認証と認可
PostgreSQLでロールとロール属性を管理する
はじめに
PostgreSQLは、データベースクラスター内の認証、認可、およびオブジェクト所有権を実装するために様々なメカニズムを使用します。これらの中心となるのは、ロールの概念です。
PostgreSQLのロールは、ユーザーとグループのアイデアを単一の柔軟なエンティティに組み合わせたものです。それらは、ユーザーがデータベースシステム内で採用するペルソナであり、認証システムが接続を許可または拒否するエンティティであり、あらゆる範囲の権限管理ルールの対象となります。
このガイドでは、ロールとは何か、そしてPostgreSQLデータベースクラスター内でそれらを管理する方法について説明します。より具体的には、ロール属性に関連するロール管理について説明します。ロールがより大きな全体像にどのように適合するかについてのより広範な概要については、認証と認可の入門ガイドをご覧ください。特定のデータベースオブジェクトに対するロール権限を変更する方法については、ロール付与に関するガイドをご覧ください。
ロールとは?
PostgreSQLにおいて、ロールとは、特定の機能、権限、「所有」エンティティのセットをグループ化したものです。「ユーザー」と「グループ」を別々の概念として持つ代わりに、PostgreSQLはこれらの両方のアイデアをロールで表現します。ロールは現実世界の個人に対応することもできますし、他のロールがメンバーになれる特定のアクセスを持つグループとして機能することもできます。
ロールは、認証および認可ポリシーが誰に適用されるかを決定するPostgreSQL内のアンカーポイントです。普遍的に適用されないポリシーはすべて、誰を制限し、誰を許可するかを定義するために、アイデンティティの概念を必要とします。PostgreSQLでは、このアイデンティティはロールによって表現されます。
PostgreSQLの認証システムにはいくつかの異なるコンポーネントがあり、それぞれがロールに結び付けられています。データベースクラスターへの最初の接続で使用するためには、ロールはまずLOGIN
属性が設定されている必要があります。認証ルール自体は、pg_hba.conf
というホストベースの構成ファイルで定義されます。各ルールは、個々のロールにスコープ設定できる認証方法を定義します。パスワード認証用に構成されたロールには、システムが提供されたユーザーパスワードを検証できるように、パスワード属性が設定されている必要があります。
認可の観点から見ると、ロールはデータベースクラスターレベルで定義されており、PostgreSQLでは、これはデータベース間で共有されることを意味します。ロールがデータベースにまたがるため、認可システムは各ロールが各データベースエンティティに対して持つアクセスレベルを制御します。ロールは人のグループを表すことができるため、アクセスの設定には非常に柔軟性があります。
ロールは、PostgreSQLにおけるオブジェクト所有権の概念にとっても不可欠です。たとえば、各データベースとテーブルには、所有者として設定されたロールがちょうど1つあります。superuser
を除き、所有者ロールは実際のオブジェクトを変更または削除できる唯一のロールです。
要するに、ロールはほとんどの実用的なデータベース操作の中核をなします。その柔軟性により、ユーザー識別子としてもユーザークラスとしても機能します。データベースクラスター内のすべての操作は、ロールの権限と照合され、データベースクラスターへの各接続の成功は、認証されるロールによって決定されます。多くのコア操作においてその重要性があるため、ロール管理をしっかり理解することが重要です。
ロール属性
ロール属性は、ロール自体に付与されるフラグで、データベースクラスターレベルでのコア権限の一部を決定します。これらは、ロールが最初に作成されるときに設定することも、適切な属性(この場合はSUPERUSER
またはCREATEROLE
)を持つロールによっていつでも変更することもできます。
ロールに適用できる属性には以下が含まれます。
LOGIN
: ユーザーがこのロールを使用してデータベースクラスターに最初に接続できるようにします。CREATE USER
コマンドは自動的にこの属性を追加しますが、CREATE ROLE
コマンドは追加しません。SUPERUSER
: ロールがログイン権限を除くすべての権限チェックをバイパスできるようにします。SUPERUSER
属性を持つロールは、他のSUPERUSER
ロールのみが作成できます。CREATEDB
: ロールが新しいデータベースを作成できるようにします。CREATEROLE
: ロールが他のロールを作成、変更、削除できるようにします。この属性は、ロールがロールメンバーシップを割り当てたり変更したりすることも許可します。例外として、CREATEROLE
属性を持つロールは、SUPERUSER
属性も持っていない限り、SUPERUSER
ロールを変更することはできません。REPLICATION
: ロールがストリーミングレプリケーションを開始できるようにします。この属性を持つロールは、LOGIN
属性も持っている必要があります。PASSWORD
:password
またはmd5
認証メカニズムで使用されるパスワードをロールに割り当てます。この属性は、属性キーワードの直後に引用符で囲まれたパスワードを引数として取ります。INHERIT
: ロールがメンバーであるロールの権限を継承するかどうかを決定します。INHERIT
がない場合、メンバーはSET ROLE
を使用して他のロールに変更することで、排他的な権限にアクセスする必要があります。この属性は、新しいロールにデフォルトで設定されます。
ロール属性の詳細については、PostgreSQLのロール属性とCREATE ROLE
コマンドに関するドキュメントを参照してください。
superuser
ロールとは?
上記で簡単に触れたように、superuser
と呼ばれる特別な権限は、データベースクラスターへの無制限の管理アクセスを許可します。これはLinuxおよびUnixライクなオペレーティングシステムにおけるroot
アカウントに似ていますが、データベースレベルでのものです。
各データベースクラスターには、常に少なくとも1つのsuperuser
権限を持つロールが存在しなければなりません。最初のsuperuser
アカウントは、インストールプロセス中に作成されます。最初のsuperuser
アカウントの名前はインストールプロセスによって異なる場合がありますが、ほとんどの場合、このアカウントはpostgres
と呼ばれます。
superuser
権限を持つアカウントを使用して日常業務を行うことは推奨されません。これは、破壊的なアクションの可能性があり、また広範囲なアクセスを持つアカウントが侵害される可能性を最小限に抑えるためでもあります。代わりに、ほとんどの場合、ユーザーは作業している特定の機能やデータオブジェクト専用のアカウントを使用し、より強力なアクセスが必要な場合にのみsuperuser
アカウントを使用すべきです。
既存のロール属性の確認
ロール属性とは何か、そしてどのような種類の権限を許可するのかについて大まかな理解が得られたので、PostgreSQL全体でロールに適用されている属性を見つける方法を学ぶ必要があります。このセクションでは、ロール全般に設定されている属性と、特に現在のロールに設定されている属性を見つけるのに役立ついくつかのコマンドを示します。
すべてのデータベースロールとその属性のリスト表示
システム全体でロールに適用されている属性を確認する方法はいくつかあります。
psql
コマンドラインクライアントを使用している場合、クエリなしでロール属性情報を取得できる便利なメタコマンドを利用できます。
\du
メタコマンドは、すべてのロールとその属性を表示します。
\du
List of rolesRole name | Attributes | Member of-----------+------------------------------------------------------------+-----------postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
この場合、postgres
ロールは、このデータベースクラスター用に構成されたsuperuser
権限を持つデフォルトのロールです。
ロールをリスト表示する同等のSQL(psql
起動時に-E
または--echo-hidden
フラグを渡すことで検出可能)は次のとおりです。
SELECT r.rolname, r.rolsuper, r.rolinherit,r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,r.rolconnlimit, r.rolvaliduntil,ARRAY(SELECT b.rolnameFROM pg_catalog.pg_auth_members mJOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)WHERE m.member = r.oid) as memberof, r.rolreplication, r.rolbypassrlsFROM pg_catalog.pg_roles rWHERE r.rolname !~ '^pg_'ORDER BY 1;
ロール属性情報を提供する同様のクエリ(ロールメンバーシップコンポーネントなし)は以下の通りです。ここでは、読みやすさのためにpsql
メタコマンド\x on
を使用して結果を垂直に出力しています。
-- turn on vertical display\x onSELECT * FROM pg_roles WHERE rolname !~ '^pg_';-- turn off vertical display\x off
-[ RECORD 1 ]--+---------rolname | postgresrolsuper | trolinherit | trolcreaterole | trolcreatedb | trolcanlogin | trolreplication | trolconnlimit | -1rolpassword | ********rolvaliduntil |rolbypassrls | trolconfig |oid | 10
superuser
属性を持つロールのみを表示したい場合は、明示的にリストを要求できます。
SELECT rolname FROM pg_roles WHERE rolsuper;
rolname----------postgres(1 row)
または、すべてのユーザーとそのsuperuser
ステータスをリスト表示して、より全体像を把握することもできます。
SELECT usename,usesuper FROM pg_user;
usename | usesuper----------+----------postgres | tuser1 | f(2 rows)
同じ情報は、PostgreSQLの「(時には曖昧な)ユーザー」のオーバーレイではなく、その「ロール」パラダイムを使用して、この少し長いクエリで取得できます。
SELECT rolname,rolsuper FROM pg_roles WHERE rolname !~ '^pg_';
rolname | rolsuper----------+----------postgres | tuser1 | f(2 rows)
自身の属性のリスト表示
現在使用しているロールの属性を確認したい場合は、出力を簡単にフィルタリングできます。
psql
メタコマンドを使用する場合、現在の接続ロールに置き換えられるUSER
変数を使用できます。psql
はコロン(:
)を使用して変数を補間します。
\du :USER
List of rolesRole name | Attributes | Member of-----------+------------------------------------------------------------+-----------postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
すべての可能なロール属性の値を示すリストを取得するには、ロール名をPostgreSQL関数CURRENT_ROLE
によって返される値と比較するクエリを使用します。ここでも、読みやすさのために垂直出力を使用しています。
-- First, turn on vertical output\x onSELECT * FROM pg_roles WHERE rolename = CURRENT_ROLE;-- Change back to normal output\x off
-[ RECORD 1 ]--+---------rolname | postgresrolsuper | trolinherit | trolcreaterole | trolcreatedb | trolcanlogin | trolreplication | trolconnlimit | -1rolpassword | ********rolvaliduntil |rolbypassrls | trolconfig |oid | 10
現在のロールにsuperuser
権限があるかどうかだけを確認するには、次のように入力します。
SHOW is_superuser;
is_superuser--------------on(1 row)
ロール管理権限があるかどうかの確認
ロールを作成、変更、または削除するには、superuser
またはCREATEROLE
権限を持っている必要があります。
システム内でどのロールがロール管理権限を持っているかを確認するには、次のように入力します。
SELECT rolname as "Users who can manage roles" FROM pg_roles WHERE rolsuper OR rolcreaterole;
Users who can manage roles----------------------------postgres(1 rows)
現在のロールにロール管理権限があるかどうかだけを知りたい場合は、代わりに以下を使用できます。
SELECT 'Yes' AS "Can I manage roles?" FROM pg_roles WHERE rolname = :'USER' AND (rolsuper OR rolcreaterole);
Can I manage roles?---------------------Yes(1 row)
ロールの作成
ロール管理権限があることを確認したら、PostgreSQL内でロールの作成、変更、削除を開始できます。
ロール属性を設定する1つのオプションは、ロールを作成する際にそれらを宣言することです。これにより、ロールの初期条件を設定できますが、後でアクセスレベルを変更したい場合は、いつでも変更できます。基本的な構文に慣れるために、使用するCREATE ROLE
コマンドに関する詳細情報を参照してください。
ロールを作成する方法の一つはコマンドラインからです。PostgreSQLには、データベースクラスター内にLOGIN
権限を持つロールを作成するcreateuser
コマンドが含まれています。
一般的な構文は次のとおりです。
createuser <options> <rolename>
例えば、admin
という名前のロールをsuperuser
権限で作成し、パスワードを尋ねるには、次のように入力します。
createuser --superuser admin
その後、pg_hba.conf
ファイルに記載されている認証方法に従って、admin
アカウントを使用してログインできるようになります。
SQL
を使用してロールを作成する場合、一般的な構文は次のようになります。
CREATE ROLE <role>;
属性は、ロール名の後にWITH
を使用して指定することで定義できます。
CREATE ROLE <role> WITH <options>;
例えば、パスワードsecretpassword
でログインできるuser1
という名前のロールを作成するには、次のように入力します。
CREATE ROLE "user1" WITH LOGIN PASSWORD 'secretpassword';
代わりに、superuser
権限を持つロール(このコマンドを正常に実行するには、あなたもsuperuser
である必要があります)で、ログインができないロール(ユーザーはこのロールに変更するためにSET ROLE
を使用する必要があります)を作成するには、次のように入力できます。
CREATE ROLE "user2" WITH SUPERUSER;
既存のロールの変更
既存のロールの属性を変更するには、代わりにALTER ROLE
コマンドを使用できます。ロールの作成と同様に、現在のロールもsuperuser
またはCREATEROLE
のいずれかの権限を持っている必要があります。これらの権限を持たないユーザーは、自身のパスワードを変更するためにのみALTER ROLE
コマンドを使用できます。
ロールを変更することで、作成後にロールに割り当てられた属性を変更できます。ロール作成セクションで述べたのと同じ属性をALTER ROLE
構文で使用できます。1つの違いは、各属性タイプにNO
プレフィックスを追加することで否定できることです。たとえば、ロールがデータベースクラスターにログインできるようにするには、LOGIN
属性を付与します。その機能を削除するには、NOLOGIN
を指定してロールを変更します。
ALTER ROLE
コマンドは、明示的に指定された属性のみを変更します。言い換えれば、ALTER ROLE
コマンドは属性への変更を指定するのであって、新しい属性の完全なセットを指定するわけではありません。
user2
ロールがデータベースクラスターにログインできるようにするには、次のように入力します。
ALTER ROLE "user2" WITH LOGIN;
これはログインを有効にしますが、許可される認証方法は依然としてpg_hba.conf
ファイルによって制御されることに注意してください。
もしuser2
にログイン、ロール作成、データベース作成を許可したい場合は、それら3つの属性をスペースで区切って指定できます。
ALTER ROLE "user2" WITH LOGIN CREATEROLE CREATEDB;
ロールからsuperuser
ステータスを取り消すには(このコマンドは別のsuperuser
ロールを使用してのみ実行できます)、次のように入力します。
ALTER ROLE "user2" WITH NOSUPERUSER;
ロールのパスワードを変更するには、以下を入力します(すべてのロールは、CREATEROLE
やsuperuser
権限に関係なく、自身のロールに対してこのコマンドを実行できるはずです)。
ALTER ROLE <role> WITH PASSWORD '<password>';
上記のコマンドは機能しますが、可能であれば、パスワードの変更にはpsql
のメタコマンドを使用することをお勧めします。psql
コマンドは自動的にパスワードを要求し、サーバーに送信する前に暗号化します。これにより、ログに機密データが漏れるのを防ぐことができます。
psql
でロールのパスワードを変更するには、次のように入力します。
-- To change your own password\password-- To change the password for another role\password <role>
ALTER ROLE
コマンドを使用してロール名を変更することもできます。
ALTER ROLE <role> RENAME TO <newrole>
現在のセッションロールは名前変更できないことに注意してください。
ロールの削除
既存のロールの削除は、以前のコマンドと同様のパターンに従います。繰り返しになりますが、これらのコマンドを実行するにはCREATEROLE
またはsuperuser
の権限を持っている必要があります。
複雑な要因の一つとして、データベース内のオブジェクトによって参照されているロールは削除できないという点があります。これは、そのロールが所有するオブジェクトをすべて削除または所有権を移転する必要があることを意味します。その後、そのロールがデータベースオブジェクトに対して持つ追加の権限もすべて取り消す必要があります。
権限を適切に再割り当ておよび削除する方法の詳細な説明は、Database Administrators Stack ExchangeサイトのErwin Brandstetter氏によって提供されています(How to appropriately reassign and drop privileges)。以下の手順も同じプロセスを使用します。
まず、REASSIGNED OWNED
コマンドを使用して、ロールが所有するすべてのオブジェクトを再割り当てできます。たとえば、user2
ロールを削除する準備をしている場合、次のように入力してそのオブジェクトをpostgres
ロールに割り当てることができます。
REASSIGN OWNED BY "user2" TO "postgres";
オブジェクトがpostgres
によって所有されるようになったので、DROP OWNED
コマンドを使用して、付与されていた他のすべての権限を取り消すことができます。このコマンドは、私たちが所有するオブジェクトも削除しますが、先ほどpostgres
ロールにそれらを転送したばかりなので、user2
ロールはもはや所有するオブジェクトを持っていません。このため、このコマンドはロールの追加権限のみを取り消します。
DROP OWNED BY "user2";
上記のDROP OWNED
ショートカットを使用しない場合、ロールが権限を持つすべての個別のオブジェクトまたはオブジェクトタイプに対してREVOKE ALL PRIVILEGES
を実行する必要があります。
関連するすべての権限を取り消したら、次のように入力してロールを削除できます。
DROP ROLE "user2";
psql
を使用したログイン
新しいロールを設定し、pg_hba.conf
ファイルを使用して認証の詳細を設定したら、新しいロールを使用してデータベースクラスターにログインできます。psql
コマンドラインクライアントは、これを行う簡単な方法を提供します。
デフォルトでは、psql
は、オペレーティングシステムのユーザー名と一致するロールを使用して接続したいと仮定します。したがって、コンピューターにjohn
としてログインしている場合、psql
は、john
という名前のロールを使用してデータベースに接続しようとすると仮定します。
この動作を上書きするには、-U
または--username=
オプションを渡します。たとえば、kerry
というロールにログインしたい場合は、次のように入力します。
psql -U kerry
psql
コマンドの成功は、kerry
ロールの存在、接続しようとしているサーバーのアクセシビリティ、およびサーバーで定義されている認証ルールに依存します。
セッション中に別のロールに変更する
場合によっては、アクセス権を持つ別のロールの権限とアイデンティティを一時的に採用したいことがあります。たとえば、現在のロールにINHERIT
属性がない場合に、自分がメンバーであるロールの権限を取得したい場合に、これが必要になります。
これがどのように機能するかを理解するには、PostgreSQLがアクティブなロールを分類するために使用する用語を知る必要があります。
- セッションロール: セッションロールとは、PostgreSQLデータベースクラスターへの初期接続時にログインしたロールのことです。これにより、初期の権限が設定され、システムへのアクセスが決定されます。このロールは
LOGIN
属性を持っている必要があります。 - 現在のロール: 対照的に、現在のロールとは、現在あなたが行動しているロールのことです。現在のロールに関連付けられた権限は、直接設定されたものであろうと、他のロールから継承されたものであろうと、実行を許可されるアクションとアクセスできるオブジェクトを決定します。
セッションロールと現在のロールの値を確認するには、次のように入力します。
SELECT SESSION_USER, CURRENT_USER;
current_user | session_user--------------+--------------postgres | postgres(1 row)
セッションロールを変更する唯一の方法は、別のロールを使用して新しい接続を開始することですが、SET ROLE
コマンドを使用して現在のロールを変更できます。SET ROLE
コマンドは、一時的に別のロールとして行動するために使用されます。このコマンドには、オプションで以下の修飾子も指定できます。
SESSION
: デフォルト設定。これにより、SET ROLE
コマンドはデータベースセッション全体に影響します。LOCAL
: この修飾子を使用すると、コマンドは現在のトランザクションに対してのみロールを変更します。
現在のロールをuser2
ロールに変更するには(セッションの残りの間)、次のように入力します。
SET ROLE "user2";
セッションロールと現在のロールの値を確認すると、現在のロールの値が変更されていることがわかります。
SELECT SESSION_USER, CURRENT_USER;
current_user | session_user--------------+--------------user2 | postgres(1 row)
すべての操作は、今後はuser2
ロールをコンテキストとして使用します。
以前使用していたセッションロールに戻るには、次のように入力します。
SET ROLE NONE;
同じ結果を達成する別の方法は以下の通りです。
RESET ROLE;
まとめ
PostgreSQLのロール、ロール属性、グラント、および認証のシステムは、管理者が権限とデータベースアクセスを効果的に管理できる柔軟なシステムを構築します。このガイドでは、ロールが正確には何であるか、そしてそれらが幅広いユースケースをどのように包含するかを説明しました。また、ロールの作成、変更、削除、およびそれらのグローバルな機能を決定するロール属性の管理方法についても説明しました。これらのアイデンティティを管理する方法を理解することは、データベースを保護し、正当なユーザーに利用可能なアクセスを提供するために不可欠です。
よくある質問
PostgreSQLでロールのパスワードを変更するには、ALTER
ステートメントをPASSWORD
と共に使用できます。構文は次のようになります。
ALTER ROLE <role> WITH PASSWORD '<password>';
または、psql
メタコマンドを次のように使用することもできます。
- To change your own password\password-- To change the password for another role\password <role>
現在のロールの属性を見つけるには、USER
変数を伴うpsql
メタコマンドを使用できます。この変数は現在の接続ロールに置き換えられます。
基本的な構文と結果は次のようになります。
\du :USER
List of rolesRole name | Attributes | Member of-----------+------------------------------------------------------------+-----------postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
ロールがユーザー権限を付与したりロールを作成したりできるかどうかを確認するには、次のSQLステートメントを使用します。
SELECT rolname as "Users who can manage roles" FROM pg_roles WHERE rolsuper OR rolcreaterole;
ご自身のユーザーがこれらの権限を持っているかどうかを確認するには、次のステートメントを使用します。
SELECT 'Yes' AS "Can I manage roles?" FROM pg_roles WHERE rolname = :'USER' AND (rolsuper OR rolcreaterole);
REPLICATION
はPostgreSQLのロール属性で、ロールがストリーミングレプリケーションを開始できるようにします。
この属性を持つロールは、LOGIN
属性も持っている必要があります。
PostgreSQLでロールを作成するには、CREATE ROLE
コマンドを使用します。
基本的な構文は次のようになります。
CREATE ROLE <role>;
属性付きの場合:
CREATE ROLE <role> WITH <options>;