psqlでロールとデータベースを管理する方法|postgresユーザーへの切り替えと権限付与の基本

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtipsデーターベース管理 > psqlでロールとデータベースを管理する方法|postgresユーザーへの切り替えと権限付与の基本
「PostgreSQLにアプリ用のユーザーを作ったのに、テーブルを操作しようとするとpermission deniedになる」
「psqlで\duコマンドを打っても、どのロールに何の権限があるのかよく分からない」

PostgreSQLのロール管理は、MySQLのユーザー管理とは設計思想が違うため、初めて触ると戸惑いやすいポイントが多いです。

この記事では、Linux上のPostgreSQLサーバーでpostgresユーザーへの切り替え・psqlへの接続・ロール作成・権限付与・権限確認・よくあるエラー対処を一通り解説します。RHEL 9系 / Rocky Linux 9 / Ubuntu 24.04 LTSで動作確認した手順です。

この記事のポイント

・psql接続は「su - postgres → psql」の2ステップが基本
・CREATE ROLE 名前 WITH LOGIN PASSWORD でアプリ用ロールを作る
・権限付与はCONNECT→USAGE→テーブル権限の3段階で行う
・PostgreSQL 15以降はpublicスキーマのデフォルトCREATE権限が変わった


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

PostgreSQLのロールとユーザーは同じもの

PostgreSQLには「ユーザー」と「ロール」の2つの概念がありますが、内部的にはどちらも同じROLEオブジェクトです。違いはログイン権限(WITH LOGIN)を持つかどうかだけです。

CREATE ROLE name:ログイン不可のロール(グループロールとして使う)
CREATE ROLE name WITH LOGIN:ログイン可能なロール(実質的なユーザー)
CREATE USER name:WITH LOGINつきのCREATE ROLEと同義(歴史的互換コマンド)

古いコマンドのCREATE USERも動きますが、PostgreSQLの公式ドキュメントはCREATE ROLEに統一する方向で記述しています。現場でもCREATE ROLE ... WITH LOGINを使う習慣をつけておくと、後からロールをグループとして再利用しやすくなります。

postgresユーザーへの切り替えとpsqlへの接続

PostgreSQLをインストールすると、OSユーザーpostgresとデータベースロールpostgresが自動的に作成されます。初期設定や管理操作は、このOSユーザー経由でpsqlに入るのが基本です。

1. su - postgres でOSユーザーを切り替える

rootまたはsudo権限のあるユーザーで以下を実行します。

# OSユーザーをpostgresに切り替える su - postgres # sudoが使える環境はこちらでも可 sudo -i -u postgres

su --は「ログインシェルとして切り替える」意味で、環境変数(HOMEやPATH)がpostgresユーザーのものに切り替わります。-を省略するとPATHが引き継がれず、psql: command not foundになるケースがあるため注意してください。

2. psqlコマンドで接続する

# postgresOSユーザーからの場合(引数なしで接続可) psql # ユーザー名・DB名を明示して接続する psql -U postgres -d postgres # ホスト・ポートを指定してTCP接続する psql -U postgres -h 127.0.0.1 -p 5432 -d postgres

引数なしのpsqlは「OSユーザー名と同名のロールで、同名のデータベースに接続する」動作をします。postgresOSユーザーから実行すれば、ロールpostgresでデータベースpostgresに接続されます。

3. 基本メタコマンド(\l・\du・\c・\q)

psqlのプロンプト(postgres=#)に入ったら、まず以下のメタコマンドを覚えてください。

\l:データベース一覧を表示
\du:ロール一覧を表示
\c dbname:接続するデータベースを切り替える
\dn:スキーマ一覧を表示
\dt:現在のDBのテーブル一覧を表示
\q:psqlを終了する

ロールの作成と削除

1. CREATE ROLEでロールを作成する

以下は、アプリケーション用のロールwebappを作成する例です。

-- ログイン可能なロール(パスワード付き) CREATE ROLE webapp WITH LOGIN PASSWORD 'StrongPass123!'; -- ログイン不可のグループロール CREATE ROLE readonly_group; -- 既存ロールをグループロールのメンバーに追加 GRANT readonly_group TO webapp;

2. \duでロール一覧を確認する

作成後は\duで状態を確認します。以下は実際の出力例です。

postgres=# \du List of roles Role name | Attributes | Member of ----------------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} readonly_group | Cannot login | {} webapp | | {readonly_group}

postgresロールがスーパーユーザー権限を持ち、webappのAttributes列が空欄(ログイン可・一般権限)でreadonly_groupのメンバーになっていることが確認できます。

ロールのログイン可否をSQL側で確認したい場合はpg_rolesビューを使います。

SELECT rolname, rolcanlogin, rolsuper FROM pg_roles ORDER BY rolname;

3. DROP ROLEでロールを削除する

-- ロールを削除する(オブジェクトを所有している場合はエラー) DROP ROLE webapp; -- 存在チェック付き(スクリプト向け) DROP ROLE IF EXISTS webapp;

ロールがテーブルやデータベースを所有している場合、先にREASSIGN OWNED BY webapp TO postgres;で所有権を別ロールに移してから削除します。

データベースの作成とオーナー設定

1. CREATE DATABASEでデータベースを作成する

-- 基本的な作成(オーナーはpostgres) CREATE DATABASE myappdb; -- オーナーを指定して作成する CREATE DATABASE myappdb OWNER webapp; -- 文字コードとロケールを指定して作成する(日本語環境向け) CREATE DATABASE myappdb OWNER webapp ENCODING 'UTF8' LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8' TEMPLATE template0;

日本語データを扱う場合、LC_COLLATELC_CTYPEja_JP.UTF-8を指定し、TEMPLATE template0でクリーンなベースから作成するのが定石です。template1(デフォルト)はすでにロケール設定が焼き込まれているため、異なるロケールを指定するとエラーになります。

2. オーナーを後から変更する

ALTER DATABASE myappdb OWNER TO webapp;

\lコマンドでOwner列を確認して変更が反映されているかチェックします。

GRANT・REVOKEで権限を付与・剥奪する

PostgreSQLの権限付与は3段階の階層構造で行います。この順番を守らないとpermission deniedエラーになります。

1. 段階的なGRANTの手順(3ステップ)

-- Step 1: データベースへの接続権限 GRANT CONNECT ON DATABASE myappdb TO webapp; -- Step 2: スキーマの使用権限(\c myappdb でDBに切り替えてから実行) \c myappdb GRANT USAGE ON SCHEMA public TO webapp; -- Step 3: 既存テーブルへの権限 GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO webapp; -- 今後追加されるテーブルへのデフォルト権限 ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO webapp; -- シーケンス(SERIAL/BIGSERIALの自動採番)への権限 GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO webapp; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO webapp;

Step 1だけ実行してStep 2を忘れるケースが最も多い失敗パターンです。GRANT CONNECTはDB接続を許可するだけで、スキーマ内のオブジェクトを操作するには別途GRANT USAGE ON SCHEMAが必要です。

2. PostgreSQL 15以降の注意点

PostgreSQL 15から、publicスキーマへのデフォルトのCREATE権限が一般ロールに付与されなくなりました。PostgreSQL 14以前の設定をそのまま持ち込むと、アプリがテーブルを作成しようとしてエラーになります。

-- PostgreSQL 15以降: publicスキーマのCREATE権限を明示的に付与 GRANT CREATE ON SCHEMA public TO webapp;

3. REVOKEで権限を剥奪する

-- テーブルへの書き込み権限を剥奪 REVOKE INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public FROM webapp; -- データベース接続権限を剥奪 REVOKE CONNECT ON DATABASE myappdb FROM webapp;

よくあるエラーと対処法

「permission denied for schema public」が出たとき

このエラーはStep 2(GRANT USAGE ON SCHEMA public)を実行していないことが原因です。対象のデータベースに切り替えてからGRANT USAGEを実行してください。

\c myappdb GRANT USAGE ON SCHEMA public TO webapp;

PostgreSQL 15以降でCREATEも必要な場合は上記に加えてGRANT CREATE ON SCHEMA public TO webapp;を実行します。

「role "xxx" does not exist」が出たとき

ロール名の大文字・小文字の扱いに注意が必要です。PostgreSQLはSQL識別子を小文字に正規化するため、CREATE ROLE WebAppと書くと実際はwebappという名前で作成されます。ダブルクォートで囲むと大文字が保持されますが、参照時にも必ずダブルクォートが必要になり運用が煩雑になります。

原則としてロール名は小文字で統一するのが運用上の鉄則です。

パスワードを変更したい(\passwordコマンド)

-- 対話的にパスワードを変更(コマンド履歴に平文が残らない) \password webapp -- SQLで直接変更する場合 ALTER ROLE webapp WITH PASSWORD 'NewStrongPass456!';

\passwordコマンドはpsql内で対話的にパスワードを入力できるため、コマンド履歴にパスワードが残りません。本番環境では\passwordを使う習慣をつけておきましょう。

本記事のまとめ

やりたいこと コマンド
postgresユーザーに切り替える su - postgres
psqlに接続する psql -U postgres -d postgres
ロール一覧を表示する \du
データベース一覧を表示する \l
ログイン可能なロールを作成する CREATE ROLE 名前 WITH LOGIN PASSWORD '...';
データベースを作成する CREATE DATABASE dbname OWNER ロール名;
DB接続権限を付与する GRANT CONNECT ON DATABASE dbname TO ロール名;
スキーマ使用権限を付与する GRANT USAGE ON SCHEMA public TO ロール名;
全テーブルへの権限を付与する GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO ロール名;
パスワードを変更する \password ロール名
ロールを削除する DROP ROLE IF EXISTS ロール名;
psqlのロール管理で一番つまずくのは「GRANT CONNECTだけ付けてGRANT USAGEを忘れる」というパターンです。3段階のGRANT手順を一度手順書に落とし、アプリDBをセットアップするたびに使い回すと現場でのミスが激減します。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアがPostgreSQLのロール管理を含むサーバー構築の実践スキルを教えます。
Linux Master Pro Seminar の詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。