データベースのユーザーと権限
MySQLとPostgreSQLでアプリケーションごとに専用ユーザーを作成し、最小限の権限を付与して、余分な権限が許可されていないことを確認する方法を説明します。
更新日 2026年8月23日
root や postgres として動作するアプリケーションは、最初の脆弱性でマシン上のすべてのデータベースを攻撃者に引き渡してしまいます。自分のスキーマにのみ権限を持つ専用ユーザーであれば、被害を 1 つのプロジェクトに限定できます。
MySQL と MariaDB
ここでのユーザーは「名前とホスト」のペアであり、これが混乱の主な原因です。
CREATE USER 'shop'@'localhost' IDENTIFIED BY 'long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'shop'@'localhost';
FLUSH PRIVILEGES;
'shop'@'localhost' と 'shop'@'%' は、異なるパスワードを持つ別々のユーザーです。必要がない限り、ホスト % のレコードは作成しないでください。任意のアドレスからのログインを許可してしまいます。
構造に対する権限が必要なのはマイグレーションのときだけです。
GRANT CREATE, ALTER, DROP, INDEX, REFERENCES ON shop.* TO 'shop_migrate'@'localhost';
アプリケーション用のロールとマイグレーション用のロールを分離するのが良い習慣です。そうすれば、通常のクエリでは物理的にテーブルを削除できません。
確認:
SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'shop'@'localhost';
パスワードの変更と削除:
ALTER USER 'shop'@'localhost' IDENTIFIED BY 'new-password';
DROP USER 'shop'@'localhost';
PostgreSQL
ロールと、データベースおよびスキーマに対する権限:
CREATE ROLE shop WITH LOGIN PASSWORD 'long-random-password';
CREATE DATABASE shop OWNER shop;
REVOKE ALL ON DATABASE shop FROM PUBLIC;
読み取り専用ロール(レポート、分析、監視パネル)の場合:
CREATE ROLE reader WITH LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE shop TO reader;
GRANT USAGE ON SCHEMA public TO reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO reader;
最後の行は必須です。これがないと、権限を付与した後に作成されたテーブルをロールが認識できず、1 か月後にはレポートが新しいデータで壊れてしまいます。
確認:
\du
\l
\dp
必ず制限すべきこと
- どのアプリケーションロールもスーパーユーザーではありません。
- 各プロジェクトには専用のデータベースと専用のユーザーがあります。
- パスワードは長くランダムで、プロジェクトごとに異なります。
- 外部からのログインは、必要なアドレスのみに許可します — リモートアクセス。
- MySQL には匿名ユーザーもテストデータベースもありません。
mariadb-secure-installationがこれを行います。
よくある間違い
| 症状 | 原因 |
|---|---|
正しいパスワードなのに Access denied | 別のホストルールが一致した。たとえば ''@'localhost' |
権限を付与したのに SELECT が動作しない | PostgreSQL に USAGE ON SCHEMA がない |
| 新しいテーブルがロールから見えない | DEFAULT PRIVILEGES が設定されていない |
| 失敗したマイグレーション中にアプリケーションがすべて削除した | アプリケーションロールに DROP 権限があった |
| パスワードがコマンド履歴に表示される | パスワードはファイルから設定し、~/.mysql_history を消去する |
データベースのパスワードはコードではなく、
600権限のサービス環境ファイルに保存してください。漏洩した場合は、プロジェクト全体を再構築するのではなく、1 行を変更して再起動するだけですみます。