PostgreSQL: PostgreSQLのユーザー、ロール、権限管理
最終更新:2026-08-26
1. 学習目標
- CREATE ROLE / CREATE USER(PGではUSER = LOGINロール)
- GRANT / REVOKE権限管理
- 権限階層: データベース / スキーマ / テーブル / カラム / 関数 / シーケンス
- DEFAULT PRIVILEGES
- 行レベルセキュリティポリシー(RLS / Row Security Policies、PGの機能)
- SCHEMA権限制御
- ロール継承(INHERIT / NOINHERIT)
- システムビュー: pg_roles / pg_auth_members
2. ストーリー
CharlieはSaaS ECプラットフォームのDBAで、5つのチームのデータ��ース権限を設定する必要があります。
| チーム | 必要な権限 |
|---|---|
| dev(開発) | 全ビジネステーブルの読み��き、テストテーブル作成 |
| analytics(分析) | 全ビジネステーブル読み取り専用、マテリアライズドビュー作成 |
| ops(運用) | ユーザー管理、データベース監視 |
| audit(監査) | 監査ログのみ読み取り、ビジネスデータ不可 |
| app(アプリケーションサービス) | ビジネステーブル読み書き、DDL不可 |
Charlieはロール継承とRLSを使用して最小権限の原則を実装します。
3. 概念: ロールとユーザー
(1) CREATE ROLE と CREATE USER
| コマンド | LOGIN権限 | 同等の形式 |
|---|---|---|
CREATE ROLE r1; |
なし(ログイン不可) | — |
CREATE USER u1; |
あり(ログイン可能) | CREATE ROLE u1 LOGIN; |
PGではユーザーとロールは同じ概念です。USERはLOGIN属性を持つROLEに過ぎません。
(2) ロール属性の概要
| 属性 | 説明 | 作成構文 |
|---|---|---|
| LOGIN | データベースへの接続を許可 | LOGIN / NOLOGIN |
| SUPERUSER | スーパーユーザー、すべての権限をバイパス | SUPERUSER |
| CREATEDB | データベース作成可能 | CREATEDB |
| CREATEROLE | ロールの作成/管理可能 | CREATEROLE |
| INHERIT | 所属ロールの権限を自動継承 | INHERIT(デフォルト) |
| NOINHERIT | 自動継承しない。SET ROLEが必要 | NOINHERIT |
| PASSWORD | パスワード設定 | PASSWORD 'xxx' |
| VALID UNTIL | パスワード有効期限 | VALID UNTIL 'timestamp' |
▶ サンプル: ロールとユーザーの作成
-- グループロール(ログイン不可)
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team NOINHERIT;
CREATE ROLE audit_team NOINHERIT;
-- ログインユーザー
-- ⚠️ 本番環境ではパスワードをハードコードせず、環境変数やシークレット管理を使用してください
CREATE USER alice_dev PASSWORD 'SecureP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'SecureP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'SecureP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'SecureP@ss4' IN ROLE ops_team INHERIT;
Output:
CREATE TABLE
▶ サンプル: ロール属性の変更
-- opsチームリーダーにCREATEDB権限を追加
ALTER ROLE diana_ops CREATEDB;
-- パスワード有効期限を設定
ALTER ROLE charlie_analyst VALID UNTIL '2025-12-31';
-- ロール名を変更
ALTER ROLE dev_team RENAME TO engineering_team;
-- 一時的にログインを無効化
ALTER ROLE bob_dev NOLOGIN;
Output:
CREATE TABLE
4. 概念: GRANT / REVOKE権限
(1) 権限階層
flowchart TD
A[データベース<br/>CONNECT / CREATE / TEMP] --> B[スキーマ<br/>CREATE / USAGE]
B --> C[テーブル<br/>SELECT / INSERT / UPDATE / DELETE / TRUNCATE / REFERENCES / TRIGGER]
C --> D[カラム<br/>SELECT / INSERT / UPDATE / REFERENCES]
B --> E[関数<br/>EXECUTE]
B --> F[シーケンス<br/>USAGE / SELECT / UPDATE]
A --> G[ロール<br/>MEMBER / SET]
style A fill:#e1f5fe
style B fill:#bbdefb
style C fill:#c8e6c9
style D fill:#fff9c4
(2) 一般的な権限キーワード
| オブジェクト | 付与可能な権限 | 説明 |
|---|---|---|
| DATABASE | CONNECT, CREATE, TEMP | 接続、スキーマ作成、一時テーブル |
| SCHEMA | CREATE, USAGE | オブジェクト作成、オブジェクトアクセス |
| TABLE | SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER | 完全なCRUD + 外部キー参照 |
| COLUMN | SELECT, INSERT, UPDATE, REFERENCES | カラムレベル制御 |
| FUNCTION | EXECUTE | 関数呼び出し |
| SEQUENCE | USAGE, SELECT, UPDATE | シーケンス使用 |
▶ サンプル: GRANTテーブルレベル権限
-- Devチーム: ビジネステーブルに対する完全CRUD
GRANT SELECT, INSERT, UPDATE, DELETE ON products TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON customers TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON order_items TO dev_team;
-- Analyticsチーム: 読み取り専用
GRANT SELECT ON products TO analytics_team;
GRANT SELECT ON orders TO analytics_team;
GRANT SELECT ON customers TO analytics_team;
-- Auditチーム: 監査ログのみ
GRANT SELECT ON price_audit_log TO audit_team;
GRANT SELECT ON ddl_audit_log TO audit_team;
Output:
INSERT 0 1
▶ サンプル: GRANTスキーマおよびデータベース権限
-- Devチームが開発スキーマでオブジェクト作成可能
GRANT CREATE, USAGE ON SCHEMA dev TO dev_team;
-- Analyticsチームがpublicスキーマを使用可能(作成不可)
GRANT USAGE ON SCHEMA public TO analytics_team;
-- Analyticsが自身のスキーマでマテリアライズドビュー作成を許可
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
-- アプリサービスがデータベースに接続
GRANT CONNECT ON DATABASE shop_db TO app_service;
Output:
CREATE TABLE
▶ サンプル: REVOKE権限
-- DevチームからproductsのDELETEを取り消し
REVOKE DELETE ON products FROM dev_team;
-- テーブルから全権限を取り消し
REVOKE ALL PRIVILEGES ON orders FROM public;
-- スキーマ作成権限を取り消し
REVOKE CREATE ON SCHEMA dev FROM dev_team;
-- カスケード: 権限と依存する付与を取り消し
REVOKE SELECT ON products FROM analytics_team CASCADE;
Output:
DELETE 2
(3) GRANT ALL と GRANT SELECT ALL TABLES
| コマンド | 効果 |
|---|---|
GRANT ALL ON t TO r; |
テーブルtの全権限を付与 |
GRANT ALL ON SCHEMA s TO r; |
スキーマsの全権限を付与 |
GRANT SELECT ON ALL TABLES IN SCHEMA s TO r; |
スキーマsの全テーブルにSELECTを付与 |
GRANT USAGE ON ALL SEQUENCES IN SCHEMA s TO r; |
全シーケンスにUSAGEを付与 |
5. 概念: DEFAULT PRIVILEGES
(1) デフォルト権限が必要な理由
単純なGRANTは既に存在するオブジェクトにのみ影響します。将来作成されるテーブルには自動的に権限が付与されません。DEFAULT PRIVILEGESがこれを解決します。
| コマンド | 効果 |
|---|---|
ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON TABLES TO r; |
s内の新規テーブルに自動付与 |
ALTER DEFAULT PRIVILEGES FOR ROLE owner GRANT ... |
特定の作成者向けデフォルト権限 |
▶ サンプル: デフォルト権限の設定
-- publicスキーマの将来の全テーブルをanalytics_teamが読み取り可能に
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO analytics_team;
-- app_serviceが作成する将来の全テーブルをdev_teamが書き込み可能に
ALTER DEFAULT PRIVILEGES FOR ROLE app_service IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO dev_team;
-- publicスキーマの将来の全シーケンス
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO dev_team;
-- 将来の全関数
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT EXECUTE ON FUNCTIONS TO analytics_team;
Output:
INSERT 0 1
▶ サンプル: 現在のデフォルト権限を表示
SELECT
pg_get_userbyid(defaclrole) AS grantor,
pg_get_userbyid(defaclnamespace) AS namespace_owner,
n.nspname AS schema,
defaclobjtype AS object_type,
defaclacl AS acl
FROM pg_default_acl d
JOIN pg_namespace n ON n.oid = d.defaclnamespace;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
6. 概念: 行レベルセキュリティポリシー(RLS)
(1) RLSの仕組み(PGの機能)
RLSを使用すると行レベルでデータアクセスを制御できます。同じテーブルでも異なるロールからは異なる行が見えます。
| ステップ | コマンド | 説明 |
|---|---|---|
| 1. RLSを有効化 | ALTER TABLE t ENABLE ROW LEVEL SECURITY; |
テーブルで行レベルセキュリティを有効化 |
| 2. ポリシー作成 | CREATE POLICY ... ON t ...; |
行レベルのルールを定義 |
| 3. スーパーユーザーバイパス | — | SUPERUSERはデフォルトでRLSの対象外 |
| 4. テーブル所有者バイパス | — | テーブル所有者はデフォルトで対象外。FORCEで強制 |
(2) ポリシーの種類
| ポリシー種別 | キーワード | 説明 |
|---|---|---|
| SELECT | FOR SELECT |
可視行を制御 |
| INSERT | FOR INSERT |
挿入可能行を制御 |
| UPDATE | FOR UPDATE |
更新可能行を制御(BEFORE/AFTER含む) |
| DELETE | FOR DELETE |
削除可能行を制御 |
| ALL | FOR ALL |
全操作で共有 |
▶ サンプル: RLSを有効化してポリシーを作成
-- ordersテーブルでRLSを有効化
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
-- アナリストは完了注文のみ表示可能
CREATE POLICY pol_analytics_completed
ON orders FOR SELECT
TO analytics_team
USING (order_status = 'completed');
-- Devチームは全行を表示可能
CREATE POLICY pol_dev_all
ON orders FOR ALL
TO dev_team
USING (true)
WITH CHECK (true);
Output:
CREATE TABLE
▶ サンプル: 現在のユーザーに基づくRLS
-- customersテーブルでRLSを有効化
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
-- 各カスタマーサービスユーザーは担当リージョンのみ表示
CREATE POLICY pol_region_access
ON customers FOR SELECT
USING (region = current_setting('app.region', true));
-- テーブル所有者にもRLSを強制
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
Output:
CREATE TABLE
▶ サンプル: INSERT/UPDATEのWITH CHECK
-- 営業チームは自身のリージョンの注文のみ挿入可能
CREATE POLICY pol_sales_insert
ON orders FOR INSERT
TO dev_team
WITH CHECK (region = current_setting('app.region', true));
-- 営業チームは自身のリージョンの注文のみ更新可能
CREATE POLICY pol_sales_update
ON orders FOR UPDATE
TO dev_team
USING (region = current_setting('app.region', true))
WITH CHECK (region = current_setting('app.region', true));
Output:
INSERT 0 1
(3) USING と WITH CHECK
| 句 | 役割 | 適用対象 |
|---|---|---|
| USING | 可視行を絞り込む(SELECT/UPDATE/DELETEのWHERE) | SELECT/UPDATE/DELETE |
| WITH CHECK | 新しい行が許可されるか検証(INSERT/UPDATEの新しい値) | INSERT/UPDATE |
7. 概念: ロール継承とシステムビュー
(1) INHERIT と NOINHERIT
| 属性 | 動作 | シナリオ |
|---|---|---|
| INHERIT(デフォルト) | 所属ロールの権限を自動的に取得 | 通常のユーザー |
| NOINHERIT | 権限を使用するにはSET ROLE rが必要 |
一時的な権限昇格、監査分離 |
▶ サンプル: NOINHERITとSET ROLE
-- NOINHERITで強力なロールを作成
CREATE ROLE admin_role NOINHERIT;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin_role;
-- Dianaはadmin_roleに所属するが管理権限を自動では使用不可
CREATE USER diana PASSWORD 'SecureP@ss5' IN ROLE admin_role NOINHERIT;
-- Dianaは管理権限を使用するために明示的に切り替える必要がある
SET ROLE admin_role;
-- これでDianaは管理操作を実行可能
RESET ROLE;
-- 通常の権限に戻る
Output:
CREATE TABLE
(2) システムビュー
| ビュー | 内容 |
|---|---|
pg_roles |
全ロールとその属性 |
pg_auth_members |
ロールとメンバーの関係 |
information_schema.role_table_grants |
テーブルレベル権限 |
information_schema.role_usage_grants |
スキーマ/関数▶限 |
▶ サンプル: ロールと権限のクエリ
-- 全ロールとその属性を一覧表示
SELECT rolname, rolsuper, rolcreatedb, rolcanlogin, rolinherit
FROM pg_roles
WHERE rolname NOT LIKE 'pg_%'
ORDER BY rolname;
-- ロールメンバーシップを一覧表示
SELECT
r1.rolname AS member,
r2.rolname AS role
FROM pg_auth_members m
JOIN pg_roles r1 ON r1.oid = m.member
JOIN pg_roles r2 ON r2.oid = m.roleid
ORDER BY r2.rolname, r1.rolname;
-- ロールのテーブル権限を確認
SELECT table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'analytics_team'
ORDER BY table_name, privilege_type;
Output:
CREATE TABLE
8. フローチャート: 権限設定の判断
flowchart TD
A[権限を設定] --> B{行レベル制御が必要?}
B -->|はい| C[RLSを有効化<br/>CREATE POLICY]
B -->|いいえ| D{権限の粒度は?}
D -->|テーブル全体| E[GRANT ON TABLE]
D -->|特定のカラム| F[GRANT column_name ON TABLE]
D -->|スキーマ内の全テーブル| G[GRANT ALL TABLES IN SCHEMA]
E --> H{新規テーブルに自動付与が必要?}
G --> H
H -->|はい| I[ALTER DEFAULT PRIVILEGES]
H -->|いいえ| J[手動GRANT]
C --> K{テーブル所有者も制限が必要?}
K -->|はい| L[FORCE ROW LEVEL SECURITY]
K -->|いいえ| M[所有者はデフォルトでRLSをバイパス]
I --> N{ユーザーが一時的な昇格を必要とする?}
J --> N
N -->|はい| O[NOINHERIT + SET ROLE]
N -->|いいえ| P[INHERITがデフォルト]
style C fill:#fff9c4
style I fill:#c8e6c9
style O fill:#ffcdd2
9. 総合サンプル
Charlieが5チーム向けに完全な権限システムを設定します。
-- Step 1: グループロールを作成
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team INHERIT;
CREATE ROLE audit_team NOINHERIT;
CREATE ROLE app_service LOGIN PASSWORD 'AppSecRet!';
-- Step 2: スキーマ権限を付与
GRANT CREATE, USAGE ON SCHEMA public TO dev_team;
GRANT USAGE ON SCHEMA public TO analytics_team;
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
GRANT USAGE ON SCHEMA public TO ops_team;
GRANT USAGE ON SCHEMA audit TO audit_team;
-- Step 3: テーブル権限を付与
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO dev_team;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analytics_team;
GRANT SELECT ON ALL TABLES IN SCHEMA audit TO audit_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON products, orders, order_items, customers TO app_service;
-- Step 4: 将来のテーブルに対するデフォルト権限
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO analytics_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dev_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA audit
GRANT SELECT ON TABLES TO audit_team;
-- Step 5: シーケンスと関数の権限
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO dev_team;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO dev_team;
-- Step 6: RLS - アナリストは完了注文のみ表示
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_analytics_orders
ON orders FOR SELECT
TO analytics_team
USING (order_status = 'completed');
-- Step 7: RLS - 監査チームはauditスキーマのみ表示
ALTER TABLE price_audit_log ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_audit_read
ON price_audit_log FOR SELECT
TO audit_team
USING (true);
-- Step 8: ログインユーザーを作成してロールを割り当て
CREATE USER alice_dev PASSWORD 'DevP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'DevP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'AnlP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'OpsP@ss4' IN ROLE ops_team CREATEROLE;
CREATE USER eve_audit PASSWORD 'AudP@ss5' IN ROLE audit_team;
❓ よくある質問
\dpおよび\du+コマンドを使用します。INHERITロールは所属するロールの権限を自動的に取得することに注意してください。📖 まとめ
- PGではUSER = LOGIN ROLE。ロールが権限管理の中核単位です
- ロール属性: LOGIN/SUPERUSER/CREATEDB/CREATEROLE/INHERITが異なる機能を制御
- GRANT/REVOKEで権限を管理。階層: データベース → スキーマ → テーブル → カラム
- DEFAULT PRIVILEGESで新規作成オブジェクトの自動付与問題を解決
- RLS(PGの機能)で行レベルアクセス制御を実装。USINGは可視行の絞り込み、WITH CHECKは新規行の検証
- INHERITで権限を自動継承。NOINHERITでは一時的な昇格にSET ROLEが必要
- pg_roles / pg_auth_members / information_schemaビューで権限設定をクエリ
- 最小権限の原則: オンデマンドで付与し、過剰な権限付与を避ける
📝 練習問題
-
⭐ ロール
readonlyとユーザーreport_userを作成し、readonlyにpublicスキー��の全テーブルへのSELECTを付与し、新規作成テーブルにも自動付与されるようにデフォルト権限を設定してください。 -
⭐⭐
ordersテーブルでRLSを有効化し、ポリシーを作成してください。sales_teamは自身のリージョンの注文のみ表示可能(region = current_setting('app.region'))。audit_teamはorder_status = 'completed'の注文のみ表示可能。 -
⭐⭐⭐ 完全な権限システ��を設計してください。3つのグループロール(
backend_dev、data_analyst、db_admin)を作成し、それぞれ異なるレベルの権限(スキーマ/テーブル/カラム/関数/シーケンス)を付与し、DEFAULT PRIVILEGESを設定し、salaryカラムを別途付与(アナリストは見られない)、pg_rolesとinformation_schemaを使用して設定結果をクエリして検証してください。