開発環境から持ち込んだテスト用アカウント、退職者のロール、目的不明のサービスユーザー——Linuxサーバーでセルフホスト運用しているPostgreSQLでは、気づかないうちにロールが積み上がります。
この記事では、
pg_rolesシステムカタログを使ってPostgreSQLの接続ユーザーを一覧表示し、ログイン権限・パスワード有効期限・所属グループをまとめて棚卸しする方法を解説します。Rocky Linux 9.4(PostgreSQL 16)とUbuntu 24.04 LTSで動作確認済みです。この記事のポイント
・ pg_roles で全ロールを一覧表示し、rolcanlogin でログイン可否を確認できる
・ rolvaliduntil でパスワード有効期限の切れそうなアカウントを事前に検知できる
・ pg_auth_members を JOIN すれば所属グループもまとめて確認できる
・ 棚卸し用の総合クエリ1本で「誰が・いつまで・どのグループか」を把握できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
pg_rolesとは何か?PostgreSQLのロール管理の仕組み
PostgreSQLでは「ユーザー」と「グループ」の区別がなく、すべてがロール(role)として管理されます。ログインできるロールがいわゆる「ユーザー」、複数ロールをまとめる役割を持つロールが「グループ」です。pg_rolesは、PostgreSQLが内部で管理しているすべてのロール情報を参照できるシステムビューです。スーパーユーザー以外の一般ユーザーでも参照可能です(パスワードハッシュはマスクされます)。棚卸しに使う主な列を整理しておきます。
| 列名 | 説明 |
|---|---|
rolname |
ロール名 |
rolsuper |
スーパーユーザー権限を持つか(true/false) |
rolcreaterole |
新しいロールを作成できるか(true/false) |
rolcreatedb |
データベースを作成できるか(true/false) |
rolcanlogin |
直接ログイン(接続)できるか。trueが「ユーザー」に相当する |
rolconnlimit |
同時接続数の上限(-1は無制限) |
rolvaliduntil |
パスワード有効期限。NULLは無期限 |
pg_rolesで接続ユーザー一覧を確認する基本手順
1. psqlでPostgreSQLに接続する
まずpsqlでデータベースに接続します。ロール情報はどのデータベースに接続しても参照できます。# PostgreSQLに接続(postgresユーザーに切り替えてから実行) $ sudo -u postgres psql # または別の管理ユーザーで直接接続 $ psql -h localhost -U dbadmin -d mydb
2. pg_rolesの全ロールを一覧表示する
psqlの\duメタコマンドも使えますが、列を自由に選んでフィルタリングするにはSQLが便利です。SELECT rolname, rolcanlogin, rolsuper, rolcreatedb, rolcreaterole, rolconnlimit, rolvaliduntil FROM pg_roles ORDER BY rolcanlogin DESC, rolname;
rolname | rolcanlogin | rolsuper | rolcreatedb | rolcreaterole | rolconnlimit | rolvaliduntil ------------------------+-------------+----------+-------------+---------------+--------------+---------------------- appuser | t | f | f | f | 10 | 2026-12-31 23:59:59+09 dbadmin | t | f | t | t | -1 | postgres | t | t | t | t | -1 | replicator | t | f | f | f | 5 | testuser | t | f | f | f | -1 | 2025-03-01 00:00:00+09 pg_checkpoint | f | f | f | f | -1 | pg_database_owner | f | f | f | f | -1 | pg_monitor | f | f | f | f | -1 | pg_read_all_data | f | f | f | f | -1 | pg_signal_backend | f | f | f | f | -1 | (10 rows)
pg_で始まる行はPostgreSQL内部の定義済みロールです。棚卸しの対象はpg_以外のロールになります。3. ログインできるユーザーだけに絞り込む
rolcanlogin = trueのロールだけが実際に接続できる「ユーザー」です。SELECT rolname, rolsuper, rolcreatedb, rolconnlimit, rolvaliduntil FROM pg_roles WHERE rolcanlogin = true AND rolname NOT LIKE 'pg\_%' ORDER BY rolname;
rolname | rolsuper | rolcreatedb | rolconnlimit | rolvaliduntil ------------+----------+-------------+--------------+---------------------- appuser | f | f | 10 | 2026-12-31 23:59:59+09 dbadmin | f | t | -1 | postgres | t | t | -1 | replicator | f | f | 5 | testuser | f | f | -1 | 2025-03-01 00:00:00+09 (5 rows)
testuserの有効期限(2025-03-01)がすでに切れています。こうした失効アカウントを早期に発見できるのが棚卸しの目的です。有効期限と所属グループを確認する実践クエリ
1. パスワード有効期限が近いユーザーを抽出する
rolvaliduntilがNULLでないかつ30日以内に期限切れになるロールだけを抽出するクエリです。SELECT rolname, rolvaliduntil, rolvaliduntil - NOW() AS days_remaining FROM pg_roles WHERE rolcanlogin = true AND rolvaliduntil IS NOT NULL AND rolvaliduntil < NOW() + INTERVAL '30 days' ORDER BY rolvaliduntil;
rolname | rolvaliduntil | days_remaining -----------+----------------------+--------------------------- testuser | 2025-03-01 00:00:00+09 | -554 days -09:23:15.291 appuser | 2026-12-31 23:59:59+09 | 115 days 14:36:44.709 (2 rows)
days_remainingがマイナスのロールはすでに失効しています。testuserはログイン不可の状態ですが、ロール自体は残ったままです。2. 所属グループ(ロールメンバーシップ)を確認する
PostgreSQLではGRANT グループロール TO ユーザーロールでグループに所属させます。この情報はpg_auth_membersテーブルに格納されています。SELECT r.rolname AS member, g.rolname AS group_role, m.admin_option FROM pg_auth_members m JOIN pg_roles r ON m.member = r.oid JOIN pg_roles g ON m.roleid = g.oid ORDER BY r.rolname, g.rolname;
member | group_role | admin_option ------------+------------------+-------------- appuser | readonly_group | f dbadmin | readonly_group | f dbadmin | readwrite_group | t replicator | pg_monitor | f (4 rows)
admin_option = tのロールは、そのグループロールを他のロールに付与できる権限を持っています。意図せずadmin_optionが付いていないか確認しておきましょう。3. 棚卸し用の総合クエリ
ロール名・ログイン可否・スーパーユーザー・有効期限・所属グループをまとめて1回のSQLで確認できる総合クエリです。SELECT r.rolname, CASE WHEN r.rolsuper THEN 'SUPER' ELSE '' END AS super, CASE WHEN r.rolcanlogin THEN 'YES' ELSE 'NO' END AS can_login, r.rolconnlimit, COALESCE(r.rolvaliduntil::text, '無期限') AS valid_until, COALESCE( STRING_AGG(g.rolname, ', ' ORDER BY g.rolname), '(なし)' ) AS member_of FROM pg_roles r LEFT JOIN pg_auth_members m ON r.oid = m.member LEFT JOIN pg_roles g ON m.roleid = g.oid WHERE r.rolname NOT LIKE 'pg\_%' GROUP BY r.rolname, r.rolsuper, r.rolcanlogin, r.rolconnlimit, r.rolvaliduntil ORDER BY r.rolcanlogin DESC, r.rolname;
rolname | super | can_login | rolconnlimit | valid_until | member_of ------------+-------+-----------+--------------+------------------------------+----------------------- appuser | | YES | 10 | 2026-12-31 23:59:59+09 | readonly_group dbadmin | | YES | -1 | 無期限 | readonly_group, readwrite_group postgres | SUPER | YES | -1 | 無期限 | (なし) replicator | | YES | 5 | 無期限 | pg_monitor testuser | | YES | -1 | 2025-03-01 00:00:00+09 | (なし) readonly_group | | NO | -1 | 無期限 | (なし) readwrite_group | | NO | -1 | 無期限 | (なし) (7 rows)
棚卸し結果の見方と現場Tips
棚卸しで確認すべきポイントを整理します。・スーパーユーザーは最小限に:
super = SUPERのロールは何でもできます。postgres以外にスーパーユーザーがいる場合は、必要な理由を確認してください。・失効アカウントは削除または無効化:
rolvaliduntilが過去日のロールはパスワード認証が拒否されますが、ロールとしては存在し続けます。アクセスしてこないと油断せず、DROP ROLEで整理しましょう。・接続数上限を設定していないロールを把握:
rolconnlimit = -1は無制限です。アプリケーションユーザーは適切な上限(例: 10~50)を設定しておくと、接続数爆発による障害を防げます。・admin_optionの付与は意図的か確認:
pg_auth_membersのadmin_option = tは強い権限です。意図せず付与されている場合はREVOKE ADMIN OPTION FOR グループ FROM ユーザーで剥奪します。psqlの
\duコマンドも同様の情報を表示しますが、フィルタリングや有効期限の日数計算が必要な場合はSQLクエリに切り替えるのが現場の実態です。PostgreSQLを含むLinuxサーバーの実務的な運用スキルをまとめて習得したい場合は、Linux Master Pro Seminar(2日間ハンズオン)も選択肢のひとつです。データベース運用を含むLinuxサーバー管理の「型」を体系的に学べます。
トラブルシュート|よくあるエラーと対処法
「ERROR: permission denied for table pg_authid」が出る
pg_rolesは全ロールが参照可能なビューですが、pg_authid(パスワードハッシュを含む元テーブル)はスーパーユーザーのみが参照できます。-- NG: 一般ユーザーには permission denied SELECT * FROM pg_authid; -- OK: pg_roles は一般ユーザーも参照可能 SELECT * FROM pg_roles;
pg_authidを参照してください。rolvaliduntilがNULLなのにログインできない
有効期限(rolvaliduntil)以外の要因でログインが拒否されるケースがあります。・pg_hba.conf の設定:接続元IPやデータベース名が
pg_hba.confの許可ルールに合致しているか確認してください。・rolcanlogin = false:グループロールとして作成されたロールは
rolcanlogin = falseです。ALTER ROLE ロール名 LOGIN;でログイン権限を付与できます。・接続数上限超過:
rolconnlimitで設定した上限を超えると「FATAL: too many connections」になります。STRING_AGGで「function string_agg does not exist」が出る
STRING_AGGはPostgreSQL 9.0以降の関数です。非常に古い環境(PostgreSQL 8.x系)では使えません。その場合はARRAY_AGGで代替するか、JOINしたままグルーピングせずに複数行で確認してください。本記事のまとめ
pg_rolesシステムカタログを使ったPostgreSQL接続ユーザーの棚卸し方法をまとめます。| やりたいこと | コマンド・クエリ |
|---|---|
| 全ロールを一覧表示する | SELECT rolname, rolcanlogin, rolsuper FROM pg_roles ORDER BY rolcanlogin DESC; |
| ログインユーザーだけ絞り込む | SELECT rolname FROM pg_roles WHERE rolcanlogin = true AND rolname NOT LIKE 'pg\_%'; |
| 有効期限切れが近いユーザーを検知する | SELECT rolname, rolvaliduntil FROM pg_roles WHERE rolvaliduntil < NOW() + INTERVAL '30 days'; |
| 所属グループを確認する | SELECT r.rolname, g.rolname FROM pg_auth_members m JOIN pg_roles r ON m.member = r.oid JOIN pg_roles g ON m.roleid = g.oid; |
| 棚卸し総合クエリ(ロール+期限+グループ) | SELECT r.rolname, ... STRING_AGG(g.rolname, ...) FROM pg_roles r LEFT JOIN pg_auth_members m ... GROUP BY ...; |
| psqlのメタコマンドで確認する | \du |
pg_rolesにpg_auth_membersをJOINする総合クエリを定期的に実行して結果を保存する習慣をつけると、ロールの変化を追跡しやすくなります。失効アカウントはパスワード認証は弾かれますがロールとして残り続けるため、定期的にDROP ROLEで整理することが大切です。
PostgreSQLのロール管理を「現場の型」として体系的に学びませんか?
クエリで確認する方法は分かりました。でも「どの権限を誰に付与すべきか」「有効期限をどう運用ルール化するか」を自信を持って答えられますか?
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:MySQLのテーブル一覧を出してデータベースを棚卸しする方法|SHOW TABLESでサイズ・行数・ストレージエンジンを確認する
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます