mcpField
C
create-readonly-db-role

create-readonly-db-role

github.com/davidondrejセキュリティ4.2k176 回インストール今日更新
リポジトリ

create-readonly-db-role について

エージェント向けに保護された SELECT 専用のデータベースロールを準備するスキルです。本番環境の変更は人が適用し、機密テーブルの除外と読み取り専用設定の検証を重視します。

主な機能

  1. 01SELECT 専用ロールと権限
  2. 02機密テーブルの除外リスト
  3. 03読み取り専用とタイムアウトの保護
  4. 04人による SQL 変更の適用
  5. 05接続と権限の確認
  6. 06ロールのメンテナンス案内

活用シーン

  1. 01エージェントに限定的なデータベース読み取り権限を付与
  2. 02エージェントのクエリから機密情報や個人情報を除外
  3. 03データベースの書き込み保護を検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davidondrej/skills --skill create-readonly-db-role

インストール後、Claude Code で/create-readonly-db-roleを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yaml

詳細

エージェント用の読み取り専用 DB ロールを作成する

SELECT のみを許可するロールと、保護された接続を用意します。SQL、ロール名、権限付与、拒否リスト、RLS の設定、タイムアウト、接続手順は、実際のシステムに合わせて調整するための例であり、本番環境でそのまま使える設定ではありません。

アクセスモデル

  1. SELECT のみを許可します。 書き込み権限は付与せず、拒否リストを使ってシークレットや PII を除外します。
  2. 現在および将来のテーブルを対象にします。 public 内のすべてのテーブルに SELECT を付与し、デフォルト権限を通じて将来のテーブルにも適用したうえで、拒否リストにあるテーブルの権限を取り消します。auth スキーマには決して権限を付与しないでください。新しく追加された機密テーブルについては、手動で権限を取り消す必要があります。
  3. 緩やかな保護策を設定します。 default_transaction_read_only = on と、ワークロードに適した短い statement_timeout を設定します。

RLS: 適用されるポリシーがないロールでは、テーブルから行が返されないことがあります。セキュリティモデルに合う場合に限り、bypassrls を検討してください。これは行のフィルタリングをスキップしますが、権限付与と拒否リストは引き続き適用されます。

ワークフロー

  1. ロールを確認します: select rolname from pg_roles where rolname = 'agent_reader';。任意の名前を選んでください。すでに存在する場合は、再作成せずに更新します。
  2. 拒否リストを人間と合意します。 エージェントに決して見せてはならないシークレットや PII を含むテーブルを特定します。例として、認証情報、Webhook ペイロード、ID テーブルなどがあります。
  3. SQL をリポジトリに保存します。 たとえば、docs/database/create-agent-reader-role.sql です。変更内容、理由、適用方法、検証方法、元に戻す方法をコメントに記載します。チャットに SQL を記載するだけでは不十分です。
  4. 人間が適用します。エージェントは本番環境の DDL を実行しません。 Supabase では、ファイルの内容を SQL エディターに貼り付け、その後、パスワードが含まれているため、クエリ履歴からクエリを削除します。人間がパスワードマネージャーにパスワードを保管します。
  5. 保護されたシークレットマネージャーまたはローカルの環境設定を通じて接続を設定し、決してコミットしないでください。 Supabase のセッションプーラーでは通常、ポート 5432 で <role>.<project-ref> を使用します。psql がない場合はインストールします(macOS では Homebrew の libpq を使用します)。
  6. 以下の検証項目をすべて実行します。
  7. プロジェクト固有の利用スキルを作成します。 主なテーブル、クエリパターン、読み取り専用アクセス、PII をコミットやドキュメントに決して貼り付けないことを含めます。

SQL テンプレート

-- Example only. Rename the role, timeout, and denylist for your system.

-- 1. role + soft guardrails
create role agent_reader with login password 'REPLACE_ME';
alter role agent_reader set default_transaction_read_only = on;
alter role agent_reader set statement_timeout = '10s';  -- example timeout; change as needed

-- 2. SELECT-only grants, denylist model
grant usage on schema public to agent_reader;
grant select on all tables in schema public to agent_reader;
alter default privileges for role postgres in schema public
  grant select on tables to agent_reader;   -- future tables auto-readable

-- 3. denylist: keep secrets and PII invisible (replace with your own tables)
revoke select on table public.secrets from agent_reader;
revoke select on table public.private_events from agent_reader;

-- 4. only if RLS is enabled, no policy covers this role, and bypass fits your model
alter role agent_reader bypassrls;

元に戻すには:drop owned by agent_reader; drop role agent_reader;

検証

完了を宣言する前に、すべてのチェックに合格する必要があります:

# Load the connection URL from your secret manager or local environment configuration.
psql "<readonly-connection-url>" -X -c "select current_user;"                      # -> agent_reader
psql "<readonly-connection-url>" -X -c "show statement_timeout;"                   # -> matches your chosen timeout
psql "<readonly-connection-url>" -X -c "select count(*) from public.<big_table>;"  # -> real number, NOT 0
psql "<readonly-connection-url>" -X -c "delete from public.<any_table> where false;"
# -> ERROR: read-only transaction (soft guardrail)
psql "<readonly-connection-url>" -X -c "begin; set transaction read write; delete from public.<any_table> where false; rollback;"
# -> ERROR: permission denied (the hard wall)
psql "<readonly-connection-url>" -X -c "select * from public.<denylisted> limit 1;"         # -> ERROR: permission denied
psql "<readonly-connection-url>" -X -c "select * from auth.<identity_table> limit 1;"       # -> ERROR: permission denied

両方の保護を検証します。読み取り専用の保護策が有効な状態では書き込みに失敗し、無効な状態でも permission denied で失敗することを確認します。いずれかのチェックに失敗した場合は、人間を通じて設定を修正し、すべてのチェックを再実行します。

トラブルシューティングとメンテナンス

  • どのテーブルからも行が返されない: RLS ポリシーを確認します。適切な場合に限り、bypassrls を使用します。
  • 書き込みの検証が成功する: 作業を中止します。人間にロールの権限を取り消して設定を修正してもらい、すべてのチェックを再実行します。
  • Supabase の認証に失敗する: プーラーのユーザー名を確認します。通常は <role>.<project-ref> です。
  • 正当なクエリがタイムアウトする: タイムアウトを延長する前に、フィルターや上限を追加します。
  • 機密テーブルが新たに追加された: 拒否リストに revoke select を追加します。
  • パスワードをローテーションする: 人間に alter role agent_reader with password '...' を実行してもらい、保存済みの接続シークレットを更新します。
  • このロールを通じてエージェントに書き込みを決して許可しないでください。本番環境への書き込みは、引き続き人間のみが行います。

コメント