read-only-postgres について
設定済みの PostgreSQL データベースに読み取り専用クエリを実行するスキルで、アプリケーションデータの確認に使えます。クエリ検証と実行制限に加え、結果の列単位で個人情報をマスキングできます。
主な機能
- 01複数のデータベース接続を設定
- 02データベース、テーブル、スキーマを一覧表示
- 03検証済みの読み取り専用クエリを実行
- 04結果件数とクエリ時間を制限
- 05指定した個人情報列を結果でマスキング
- 06SSL モードを設定
活用シーン
- 01データを変更せずにアプリのレコードを確認
- 02クエリ前にデータベース構造を調査
- 03レポート用クエリの出力量を制限
- 04クエリ結果の機密列をマスキング
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ jawwadfirdousi/ agent-skills --skill read-only-postgresインストール後、Claude Code で/read-only-postgresを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreconnections.example.jsonrequirements.txtscripts/query.py詳細
PostgreSQL 読み取り専用クエリスキル
設定済みの PostgreSQL データベースに対して、安全な読み取り専用クエリを実行します。
要件
- Python 3.8+
- psycopg2-binary:
pip install -r requirements.txt
セットアップ
スキルディレクトリまたは ~/.config/claude/read-only-postgres-connections.json に connections.json を作成します。
セキュリティ:認証情報が含まれるため、ファイルのアクセス権を 600 に設定してください。
chmod 600 connections.json
{
"databases": [
{
"name": "app-db-dev",
"description": "Primary app database (public schema: users, organizations, orders, order_items, events)",
"host": "localhost",
"port": 5432,
"database": "app_dev",
"user": "app_user",
"password": "app_password",
"sslmode": "disable"
},
{
"name": "app-db-staging",
"description": "Staging database (same schema as primary app)",
"host": "localhost",
"port": 5432,
"database": "app_staging",
"user": "app_user",
"password": "app_password",
"sslmode": "disable"
}
]
}
設定フィールド
| フィールド | 必須 | 説明 |
|---|---|---|
| name | はい | データベースの識別子(大文字と小文字は区別されません) |
| description | はい | このデータベースに含まれるデータ(自動選択に使用) |
| host | はい | データベースのホスト名 |
| port | いいえ | ポート番号(デフォルト:5432) |
| database | はい | データベース名 |
| user | はい | ユーザー名 |
| password | はい | パスワード |
| sslmode | いいえ | SSL モード:disable、allow、prefer(デフォルト)、require、verify-ca、verify-full |
| pii_masking | いいえ | テーブル名をマスク対象の列名の配列に対応付けるオブジェクト |
PII マスキング
任意のデータベース設定に pii_masking フィールドを追加すると、クエリ結果の機密データをマスキングできます。先頭と末尾の文字のみを表示し、中間の文字は * に置き換えられます。
{
"name": "app-db-dev",
"host": "localhost",
"database": "app_dev",
"user": "readonly",
"password": "secret",
"pii_masking": {
"users": ["email", "phone", "first_name", "last_name"],
"orders": ["shipping_address"]
}
}
仕組み:
[email protected]→j************m555-1234→5******4Jo→Jo(2文字以下はマスキングされません)
一致するテーブルをクエリすると、マスキングが自動的に適用されます。マスキングされた列を示す注記がフッターに表示されます。
使用方法
設定済みデータベースの一覧表示
python3 scripts/query.py --list
データベースへのクエリ
python3 scripts/query.py --db app-db-dev --query "SELECT id, email, created_at FROM users LIMIT 10"
テーブルの一覧表示
python3 scripts/query.py --db app-db-dev --tables
スキーマの表示
python3 scripts/query.py --db app-db-dev --schema
結果数の制限
python3 scripts/query.py --db app-db-dev --query "SELECT id, status, total_amount FROM orders" --limit 100
データベースの選択
ユーザーの意図とデータベースの description を照合します。
| ユーザーの質問 | 説明に含まれる語句 |
|---|---|
| ユーザー、アカウントについて | users、accounts |
| 組織、チームについて | organizations、teams |
| 注文、支払いについて | orders、payments |
| イベント、監査ログについて | events、audit、logs |
| 分析またはレポートについて | analytics、reporting |
| バックグラウンドジョブまたはキューについて | jobs、queue、outbox |
明確でない場合は、--list を実行して、どのデータベースを使うかユーザーに確認します。
安全機能
- 読み取り専用セッション:接続では PostgreSQL の
readonly=Trueモードを使用します(主な保護機能) - クエリ検証:SELECT、SHOW、EXPLAIN、WITH クエリのみ許可されます(コメントとリテラルを除去し、DDL/DML キーワード、データ変更を行う CTE、SELECT INTO、シーケンスを変更する関数をブロックします)
- 単一ステートメント:複数のステートメントを含むクエリは拒否されます
- SSL 対応:暗号化接続用の SSL モードを設定できます
- クエリタイムアウト:ステートメントのタイムアウトは30秒に設定されます
- メモリ保護:OOM を防ぐため、クエリごとの行数は最大10,000行です
- 列幅の上限:読みやすい出力にするため、各列の最大幅は100文字です
- 認証情報のサニタイズ:エラーメッセージにパスワードが漏れることはありません
- PII マスキング:クエリ結果の機密データを保護するため、テーブルごとに列のマスキングを設定できます
トラブルシューティング
| エラー | 解決方法 |
|---|---|
| 設定が見つからない | スキルディレクトリに connections.json を作成します |
| 認証に失敗した | 設定のユーザー名とパスワードを確認します |
| 接続がタイムアウトした | ホストとポートを確認し、ファイアウォール/VPN を確認します |
| SSL エラー | ローカルデータベースの場合は "sslmode": "disable" を試します |
| アクセス権の警告 | chmod 600 connections.json を実行します |
終了コード
- 0:成功
- 1:エラー(設定が見つからない、認証失敗、無効なクエリ、データベースエラー)
ワークフロー
--listを実行して、使用可能なデータベースを表示します- ユーザーの意図とデータベースの説明を照合します
--tablesまたは--schemaを実行して、構造を確認します- 適切な LIMIT を指定してクエリを実行します
コメント
Markdown 対応