データベースサービスアカウントは、認証用に個別のパスワードまたは証明書を持つユーザーのようなシンプルなものにできます。より高度な利用者は、SET ROLE を使用して権限の範囲を動的に変更できるアカウントを設定することで、ログアウトしたりコンテンツを再読み込みしたりすることなく、プロファイルをすばやく切り替えたい場合があります。
概要
SET ROLE を使用すると、セッション中のサービスアカウントの権限範囲を動的に絞り込めます。これは、有効化されたロールによって付与された権限だけにユーザーの実効権限を制限することで実現されます。この方法には、いくつかの利点があります。
- サービスアカウントには複数のロールを割り当てられますが、特定のクエリに必要なロールだけを有効化できます。
- サービスアカウントが侵害された場合でも、攻撃者が利用できるのは有効なロールの権限のみです。
- タスクごとに個別の認証情報を用意しなくても、1 つのアカウントでロールを切り替えることでさまざまなタスクを実行できます。
- 個々のユーザーを更新する代わりに 1 つのロールを変更するだけで、サービスアカウントの一群全体の権限を更新できます。
- クエリ実行時にどのロールが有効だったかをログで追跡できるため、セキュリティ監査の文脈がより明確になります。
実際には、次のように行います。
- 許可された範囲 (read_only、maintenance など) を表すロールを設計します
- それらをサービスアカウントに付与します
- 接続時に
SET ROLE(または role パラメーター) で有効なロールを選択し、そのセッションで実行できる操作を制限します
サービスロールを設定する
サービスアカウントにロールを付与する
まず、必要な権限 / 設定を持つロールを作成し、それらをサービスアカウントに付与します。
CREATE ROLE read_only_role;
GRANT SELECT ON db1.* TO read_only_role;
CREATE ROLE maint_role;
GRANT SELECT, INSERT, ALTER on db1.* TO maint_role;
GRANT read_only_role, maint_role TO service_user;SET ROLE を使用して権限の境界を定義する
セッションの開始時に、サービスアカウントはどのロールをアクティブにするかを選択します。
-- このセッションでは読み取り専用として動作
SET ROLE read_only_role;または:
-- 付与されたすべてのロールを使用(フルアクセス)
SET ROLE ALL;SET ROLE は現在のユーザーに対してロールを有効化します。実効権限は、有効なすべてのロールの権限と、ユーザーに直接付与された権限を合わせたものです。
すべてのロールを無効化することもできます。
SET ROLE NONE;または、複数のロールをアクティブ化できます。
SET ROLE read_only_role, maint_role;現在有効なロールは system.current_roles で確認できます。
サービスアカウントのデフォルトロールを設定する
サービスアカウントが常に制限されたモードで開始するようにするには、デフォルトロールを設定します。
SET DEFAULT ROLE read_only_role TO service_user;または
SET DEFAULT ROLE ALL EXCEPT maint_role TO service_user;HTTP 経由 / プログラムから SET ROLE を使用する
サービスアカウントが HTTP 経由で接続する場合、SET ROLE; SELECT … を複数ステートメントとして送信することはできません。代わりに、ロールをクエリパラメータとして渡します。
curl "https://host:8123?user=service_user&password=...&role=read_only_role" \
--data-binary "SELECT * FROM db1.table1"?role=… は、ステートメントの前に SET ROLE read_only_role を実行するのと同等です。複数の role パラメータは SET ROLE role 1, role 2 と同様に動作します。
一部のドライバー (例: Python 向け ClickHouse Connect) では、各リクエストとともに送信される role 設定も利用でき、サーバーはそれをセッションロールとして使用します。