かなり単純な内部データベース駆動型アプリケーションをSQLite3からPostgreSQL 9.3に移行し、DBの権限を厳しくしていきたいと思います。
アプリケーションは現在、データを更新するコマンドで構成されています。 1つはそれを照会します。もちろん、他の方法でデータベースを維持する必要もあります(新しいテーブル、ビュー、トリガーなどを作成する)。
このアプリケーションは最初はサーバーでホストされる唯一のものですが、将来必要になった場合に後でスクランブルする必要はなく、将来的に他のデータベースを持つサーバーでホストされる可能性があるという想定で焼きたいと思います。未来。
これらはかなり一般的な要件のセットになると思いますが、このようなユーザー/権限の分離を使用して、PostgreSQLで新しいデータベースを設定する方法を説明する簡単なチュートリアルを見つけるのに苦労しています。参照は、グループ、ユーザー、ロール、データベース、スキーマ、およびドメインについて続きます。しかし、私はそれらが混乱していると思います。
これが私がこれまでに試したことです(psql
内から 'postgres'として):
CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;
\connect hostdb
CREATE SCHEMA hostdb;
CREATE USER hostdb_admin WITH PASSWORD 'youwish';
CREATE USER hostdb_mgr WITH PASSWORD 'youwish2';
CREATE USER hostdb_usr WITH PASSWORD 'youwish3';
GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin;
GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT ON TABLES TO hostdb_usr;
しかし、意図したセマンティクスが得られません。 hostdb_admin
のみがテーブルを作成(および削除および変更)できるように構成します。 hostdb_mgr
は、デフォルトですべてのテーブルの読み取り、挿入、更新、削除を行うことができます。 hostdb_usr
は、すべてのテーブル(およびビュー)のみを読み取ることができます。
これを試したところ、これらのユーザーのいずれかとしてhostdb
にテーブルを作成できることがわかりました。しかし、ユーザーごとに、明示的なGRANT
を使用しない限り、そのユーザーが作成したテーブルの読み取りまたは変更しかできませんでした。
SCHEMA
をDATABASE
に適用するために、CREATE DATABASE
とCREATE SCHEMA
の間に何か欠けているものがあると思いますか?
(より高度になるにつれて、TRIGGERS
、ストアドプロシージャ、VIEWS
、およびおそらく他のオブジェクトにも同様の制限を適用するための質問が出ます)。
これに関する適切なガイド、チュートリアル、ビデオシリーズはどこにありますか?
これに関する適切なガイド、チュートリアル、ビデオシリーズはどこにありますか?
マニュアルにはすべてが含まれています。以下のリンク。
当然のことながら、問題は些細なことではなく、時には混乱を招きます。ユースケースのレシピは次のとおりです。
hostdb_admin
のみがテーブルを作成(および削除および変更)できるように構成します。hostdb_mgr
は、デフォルトですべてのテーブルの読み取り、挿入、更新、削除を行うことができます。
およびhostdb_usr
は、すべてのテーブル(およびビュー)のみを読み取ることができます。
スーパーユーザーpostgres
として:
CREATE USER schma_admin WITH PASSWORD 'youwish';
-- CREATE USER schma_admin WITH PASSWORD 'youwish' CREATEDB CREATEROLE; -- see below
CREATE USER schma_mgr WITH PASSWORD 'youwish2';
CREATE USER schma_usr WITH PASSWORD 'youwish3';
データベースとロールも管理できるより強力な管理者が必要な場合は、上記の ロール属性CREATEDB
およびCREATEROLE
を追加します。
各ロールを次の上位レベルに付与します。これにより、すべてのレベルが少なくとも次の下位レベルから一連の特権を「継承」します(カスケード)。
GRANT schma_usr TO schma_mgr;
GRANT schma_mgr TO schma_admin;
CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public; -- see notes below!
GRANT CONNECT ON DATABASE hostdb TO schma_usr; -- others inherit
\connect hostdb -- psql syntax
スキーマにschma
という名前を付けています(混乱を招くhostdb
ではありません)。任意の名前を選択してください。 オプションでschma_admin
をスキーマの所有者にします:
CREATE SCHEMA schma AUTHORIZATION schma_admin;
SET search_path = schma; -- see notes
ALTER ROLE schma_admin IN DATABASE hostdb SET search_path = schma; -- not inherited
ALTER ROLE schma_mgr IN DATABASE hostdb SET search_path = schma;
ALTER ROLE schma_usr IN DATABASE hostdb SET search_path = schma;
GRANT USAGE ON SCHEMA schma TO schma_usr;
GRANT CREATE ON SCHEMA schma TO schma_admin;
ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT SELECT ON TABLES TO schma_usr; -- only read
ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO schma_mgr; -- + write, TRUNCATE optional
ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin
GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO schma_mgr; -- SELECT, UPDATE are optional
and drop and alter
については、以下の注を参照してください。
より高度になるにつれて、
TRIGGERS
、ストアドプロシージャ、VIEWS
、およびおそらく他のオブジェクトにも同様の制限を適用するための質問があります。
...(ただし、
ALL TABLES
はビューと外部テーブルを含むと見なされることに注意してください)。
そして 更新可能なビュー :
ビューで挿入、更新、または削除を実行するユーザーには、ビューに対する対応する挿入、更新、または削除の権限が必要です。さらに、ビューの所有者は、基になる基本リレーションに対する適切な特権を持っている必要がありますが、更新を実行するユーザーには、基になる基本リレーションに対する権限は必要ありません( セクション38.5 を参照)。
トリガーも特別です。テーブルに対するTRIGGER
特権が必要です。
しかし、私たちはすでにこの質問の範囲を拡大しています...
schma_admin
(単独)によるテーブルの削除と変更を許可する場合は、ロールをownすべてのオブジェクト。 ドキュメント:
オブジェクトを削除する権利、またはその定義を変更する権利は、付与可能な特権として扱われません。それは所有者に固有であり、付与したり取り消したりすることはできません。 (ただし、オブジェクトを所有するロールのメンバーシップを付与または取り消すことによって、同様の効果を得ることができます。以下を参照してください。)所有者は、オブジェクトのすべての付与オプションも暗黙的に持っています。
ALTER TABLE some_tbl OWNER TO schma_admin;
または最初にschma_admin
の役割を持つすべてのオブジェクトを作成します。所有者を明示的に設定します。また、デフォルトの権限も簡素化され、1つのロールに対してのみ設定する必要があります。
デフォルトの権限は、新しく作成されたオブジェクトと、それらが作成された特定のロールにのみ適用されます。 existingオブジェクトにも権限を適応させる必要があります。
スーパーユーザーpostgres
のように、DEFAULT PRIVILEGES
が設定されていないロールでオブジェクトを作成する場合も同様です。所有権をschma_admin
に再割り当てして、権限を手動で設定するか、postgres
にもDEFAULT PRIVILEGES
を設定します(適切なDBに接続している間):
ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ... -- etc.
ALTER DEFAULT PRIVILEGES
コマンドの重要な側面がありませんでした。特に指定のない限り、現在の役割に適用されます。
デフォルトの権限は現在のデータベースにのみ適用されます。したがって、DBクラスター内の他のデータベースを変更する必要はありません。 ドキュメント:
現在のデータベースで作成されたすべてのオブジェクト
また、mayは、FUNCTIONS
とTYPES
(TABLES
とSEQUENCES
だけでなく)にデフォルトの権限を設定することもできますが、必要ない場合もあります。
PUBLIC
のデフォルトの権限PUBLIC
に付与されたデフォルトの特権は初歩的なものであり、一部では過大評価されています。 ドキュメント:
PostgreSQLは、
PUBLIC
にいくつかのタイプのオブジェクトのデフォルト権限を付与します。 テーブル、列、スキーマ、またはテーブルスペースでは、デフォルトでPUBLIC
に権限は付与されません。その他のタイプの場合、PUBLIC
に付与されるデフォルトの権限は次のとおりです:CONNECT
およびCREATE TEMP TABLE
データベース用。関数に対するEXECUTE
特権。および言語のUSAGE
特権。
大胆な強調鉱山。通常、上記の1つのコマンドですべてをカバーできます。
REVOKE ALL ON DATABASE hostdb FROM public;
特に、新しいスキーマでは、PUBLIC
にデフォルトの権限は付与されません。 「public」という名前のデフォルトのスキーマがALL
のPUBLIC
特権で始まると混乱するかもしれません。これは、新しく作成されたデータベースを簡単に開始できる便利な機能です。他のスキーマには影響しません。あなたcanは、テンプレートデータベースtemplate1
でこれらの権限を取り消し、次に新しく作成されたすべてのデータベースを取り消しますこのクラスターでは、それらなしで開始します。
\connect template1
REVOKE ALL ON SCHEMA public FROM public;
TEMP
hostdb
からPUBLIC
に対するすべての特権を取り消したため、明示的に許可しない限り、通常のユーザーは一時テーブルを作成できません。これを追加するかどうかは次のとおりです。
GRANT TEMP ON DATABASE hostdb TO schma_mgr;
search_path
search_path
を設定することを忘れないでください。クラスター内にデータベースが1つしかない場合は、postgresql.conf
にグローバルデフォルトを設定できます。それ以外の場合(可能性が高い)は、データベースのプロパティとして設定するか、関連するロールまたはその両方の組み合わせに設定します。詳細:
公開スキーマも使用している場合はschma, public
に設定するか、または(可能性は低いですが)$user, schma, public
...
別の方法として、デフォルトのスキーマ「public」を使用することもできます。これは、変更しない限り、search_path
のデフォルト設定で機能するはずです。この場合、PUBLIC
の権限を取り消すことを忘れないでください。