DATABASE vs SCHEMAでユーザーのデフォルト特権を管理する方法


48

私は、SQLite3からPostgreSQL 9.3にかなりシンプルな内部データベース駆動型アプリケーションを移行し、DBのアクセス許可を強化したいと思っています。

アプリケーションは現在、データを更新するコマンドで構成されています。そして、それをクエリするもの。当然、他の方法でデータベースを維持する必要もあります(新しいテーブル、ビュー、トリガーなどを作成します)。

このアプリケーションは、最初はサーバーでホストされる唯一のアプリケーションですが、将来的に他のデータベースを備えたサーバーでホストされる可能性があると仮定して、それが必要になった場合に後でスクランブルする必要はありません未来。

これらはかなり一般的な一連の要件になると思いますが、この種のユーザー/特権の分離を使用して、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

私はそこの何かが欠落している間に推測しているCREATE DATABASECREATE SCHEMA、適用するために何かSCHEMAをしますかDATABASE

(物事がより高度になるにつれて、、TRIGGERSストアドプロシージャ、VIEWSおよびおそらく他のオブジェクトにも同様の制限を適用するための質問があります)。

これに関するまともなガイド、チュートリアル、またはビデオシリーズはどこにありますか?


2
あなたの問題は(少なくともその一部)public疑似ロールにあると思います。他のすべてのロール(ユーザー、グループ-これらはすべて同じ)がメンバーであるロールと考えることができます。たとえば、から特権を削除してくださいREVOKE CREATE ON SCHEMA hostdb FROM public。データベースレベルの権限を取り消すと、データベースレベルの一部の権限のみが無効になり、スキーマやテーブルには影響しません。
-dezso

@dezso:スキーマのデフォルト権限に関して誤解があるかもしれません。デフォルトのスキーマのみpublicが、の特権を伴いますPUBLIC。それ以外には、新しいスキーマに対するデフォルトの特権はありません。したがって、これは実証されたユースケースには影響しません。私の答えの章をご覧ください。
アーウィンブランドステッター

回答:


86

これに関するまともなガイド、チュートリアル、またはビデオシリーズはどこにありますか?

あなたは見つけることのすべてを手動で。以下のリンク。
確かに、この問題は些細なことではなく、時には混乱を招くこともありません。ユースケースのレシピを次に示します。

レシピ

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';

あなたはまた、データベースとロールを管理することができ、より強力な管理が必要な場合は、追加的な役割属性CREATEDBCREATEROLE上記を。

各ロールを次に高いレベルに付与し、すべてのレベルが少なくとも次の低いレベルからの特権セットを「継承」するようにします(カスケード)。

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

スキーマに名前を付けていますschmahostdb混乱することはありません)。任意の名前を選択してください。必要に応じて作る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およびおそらく他のオブジェクトに適用するための質問もあります。

ビューは特別です。1つの場合:

...(ただしALL TABLES、ビューと外部テーブルを含むと見なされることに注意してください)。

そしてのための更新可能なビュー

ビューに対して挿入、更新、または削除を実行するユーザーには、ビューに対する対応する挿入、更新、または削除の権限が必要であることに注意してください。さらに、ビューの所有者は基礎となるベースリレーションに関連する権限を持っている必要がありますが、更新を実行するユーザーは基礎となるベースリレーションに対する権限を必要としません(セクション38.5を参照 )。

トリガーも特別です。TRIGGERテーブルに対する特権が必要であり、かつ:

しかし、私たちはすでにこの質問の範囲を過度に拡大しています...

重要な注意事項

所有権

schma_admin(単独で)テーブルのドロップと変更を許可する場合は、ロールがすべてのオブジェクトを所有するようにします。ドキュメント:

オブジェクトを削除する権利、または何らかの方法でその定義を変更する権利は、付与可能な特権として扱われません。それは所有者に固有のものであり、付与または取り消すことはできません。(ただし、オブジェクトを所有するロールのメンバーシップを付与または取り消すことで、同様の効果を得ることができます。以下を参照してください。)所有者には、オブジェクトに対するすべての付与オプションも暗黙的にあります。

ALTER TABLE some_tbl OWNER TO schma_admin;

またはschma_admin、最初にロールを持つすべてのオブジェクトを作成し、所有者を明示的に設定する必要はありません。また、デフォルトの特権を簡素化します。これにより、1つのロールに対してのみ設定する必要があります。

既存のオブジェクト

デフォルトの特権は、新しく作成されたオブジェクトと、それらが作成された特定のロールにのみ適用されます。既存のオブジェクトのアクセス許可も調整する必要があります。

DEFAULT PRIVILEGESスーパーユーザーなど、設定されていないロールを持つオブジェクトを作成する場合も同じですpostgres。所有権をschma_admin手動で再割り当てし、手動で権限を設定DEFAULT PRIVILEGESします-またはpostgres同様に設定します(正しいDBに接続している間に!):

ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ...  -- etc.

デフォルトの特権

ALTER DEFAULT PRIVILEGESコマンドの重要な側面が欠落していました。特に指定がない限り、現在の役割に適用されます。

デフォルトの特権は、現在のデータベースにのみ適用されます。したがって、DBクラスター内の他のデータベースに干渉することはありません。ドキュメント:

現在のデータベースで作成されたすべてのオブジェクト

また、and だけでなくandにもデフォルトの権限を設定することできますが、これらは必要ない場合があります。FUNCTIONSTYPESTABLESSEQUENCES

のデフォルト権限 PUBLIC

与えられるデフォルトの特権PUBLICは初歩的なものであり、一部の人によって過大評価されています。ドキュメント:

PostgreSQLは、一部のタイプのオブジェクトに対するデフォルトの権限をに付与します PUBLICデフォルトでは、テーブル、列、スキーマ、またはテーブルスペースに対する権限は付与さPUBLICれていません。他のタイプの場合、デフォルトの権限が付与されたためにPUBLIC、以下の通りである。CONNECTそしてCREATE TEMP TABLEデータベース用; EXECUTE機能の特権; およびUSAGE 言語の特権。

大胆な強調鉱山。通常、上記の1つのコマンドですべてをカバーできます。

REVOKE ALL ON DATABASE hostdb FROM public;

特に、PUBLIC新しいスキーマに対してデフォルトの権限は付与されていません。「public」という名前のデフォルトのスキーマがのALL権限で始まるのは混乱するかもしれませんPUBLIC。これは、新しく作成されたデータベースを簡単に開始できる便利な機能です。他のスキーマには一切影響しません。あなたはできるテンプレートデータベースでこれらの権限を取り消すtemplate1、このクラスタ内のすべての新しく作成されたデータベースはそれらなしで起動し、:

\connect template1
REVOKE ALL ON SCHEMA public FROM public;

特権 TEMP

hostdbfromのすべての特権を取り消したため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この場合は、必ず特権を取り消してください。

関連する


新しく作成されたスーパーユーザーにデフォルトの管理者権限を追加する方法を探していたので、すべてのテーブルに追加の権限を与える必要はありません。私はこれを見つけました。そしてthis...宇宙船のための命令のような表情をして
デニスMatafonov

@DenisMatafonov:スーパーユーザーはすべての特権を自動的に持っています。ケースの詳細から新しい質問を始めることをお勧めします。コメントは場所ではありません。コンテキストの関連する質問/回答にいつでもリンクできます。
アーウィンブランドステッター

はい、スーパーユーザーはすべてのアクセス権を持っていますが、デフォルトの特権を一般化することはできません。スキーマ内のロールにデフォルトの特権を設定し、スキーマ内にテーブルを作成するときに、それらのデフォルトをロールのすべてのメンバーに適用すると本当にいいでしょう。たとえば、「エンジニアリングチームの誰でもこのスキーマで作成されたテーブルが、レポートチームの誰でも読めることを確認してください」と言います。要するに、テーブル作成ロールのメンバーにそのデフォルト権限を継承させたいのです。
コンビ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.