web-dev-qa-db-ja.com

スキーマ内のすべてのテーブルのすべてを許可すると、ユーザーはテーブルを表示できなくなります

新しいデータベースを作成し、このデータベースにアクセスするための新しいユーザーを作成する非常に単純なスクリプトがあります。これはデフォルトのpostgresユーザーによって実行されます。データベースとスキーマへのアクセスをユーザーに許可した後、新しく作成されたユーザーは、psqlで_\dt_を使用してテーブルを表示できません。これまでに試した内容を示すスクリプトの一部を以下に示します。

_CREATE USER api WITH ENCRYPTED PASSWORD 'password';

ALTER DEFAULT PRIVILEGES 
    FOR USER api
    IN SCHEMA public
    GRANT ALL ON ALL TABLES TO api;


DROP DATABASE IF EXISTS new_db;
CREATE DATABASE new_db;


CREATE TABLE addresses (
    address_id INTEGER,
    address_line_1 VARCHAR(50) NOT NULL,
    address_line_2 VARCHAR(50),
    city VARCHAR(50) NOT NULL,
    state VARCHAR(2) NOT NULL,
    zipcode VARCHAR(12) NOT NULL,
    PRIMARY KEY (address_id)
);

-- Create more tables....

-- Added these in for good measure at the end:
GRANT all PRIVILEGES on DATABASE new_db to api;
GRANT ALL ON DATABASE new_db TO api;
GRANT ALL ON SCHEMA public to api;
GRANT ALL ON ALL TABLES IN SCHEMA public TO api;
_

これを実行した後、_\dt_は、postgresユーザーとしてログインすると、psqlのすべてのテーブルを表示します。 _\dt_は、apiユーザーとしてログインすると_Did not find any relations._を表示します。

Postgresユーザーで_\dn+_を実行すると、次の情報が得られます。

_  Name  |  Owner   |   Access privileges   |      Description       
--------+----------+-----------------------+------------------------
 public | postgres | postgres=UC/postgres +| standard public schema
        |          | =UC/postgres         +| 
        |          | api=UC/postgres       | 
_

バージョン情報:PostgreSQL 10.5 (Ubuntu 10.5-2.pgdg16.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609, 64-bit

その他SOこれまでに遭遇した質問:

私は無数のSO質問を見て、提案されたすべてを試しましたが、それでもまだ運がありません。他に確認または試行できることはありますか?私の直感は、明らかな何かが欠けているということです。

4
ChrisM

グループを作成します。つまり、ROLENOLOGINを使用します。

CREATE ROLE api_group NOLOGIN;

データベースを作成(または必要に応じて最初にドロップ)します。次に、そのデータベースに接続します。

CREATE DATABASE new_db;
\c new_db

グループにデフォルトの権限を追加します。以下のコードは、postgresロールがapi_groupにオブジェクト付与ALLを作成するかどうかを示しています。 ALLの代わりに、より具体的にすることができます(例:SELECT、INSERT、USAGEなど)。

ALTER DEFAULT PRIVILEGES FOR ROLE postgres ALL ON TABLES TO api_group ;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres ALL  ON SEQUENCES TO api_group ;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ALL  ON FUNCTIONS TO api_group ;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ALL  ON TYPES TO api_group ;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ALL  ON SCHEMAS TO api_group ;

これで、postgresユーザーを使用して新しいオブジェクトを作成できます。

CREATE TABLE addresses (
    address_id INTEGER,
    address_line_1 VARCHAR(50) NOT NULL,
    address_line_2 VARCHAR(50),
    city VARCHAR(50) NOT NULL,
    state VARCHAR(2) NOT NULL,
    zipcode VARCHAR(12) NOT NULL,
    PRIMARY KEY (address_id)
);

-- Create more objects....

セットアップの準備が整いました。すべてのオブジェクトを作成した後でも、新しいユーザーを追加する場合は(言う)apiは、ユーザーにすべての権限を付与します。 INHERITキーワードは、それがメンバーであるロールの特権を継承するためのものです。以下のコードは、api_groupのメンバーとして2人のユーザーを作成します。

CREATE ROLE api INHERIT WITH ENCRYPTED PASSWORD 'pwd' IN ROLE api_group;
CREATE ROLE another_api INHERIT WITH ENCRYPTED PASSWORD 'pwd' IN ROLE api_group;

ドキュメントの推奨セクション。

2
Sahap Asci

あなたが与えるステップに従うと、作成されたテーブルは「api」ロールに表示されます。ただし、データベースを作成した後ではなく、テーブルを作成する前にデータベースに変更しなかったため、テーブルはデータベース「new_db」にありません。また、テーブルを作成した後で、テーブルを作成する前に、そのロールに変更しなかったため、テーブルは「api」によって所有されていません。テーブルは、最初に接続したのと同じデータベース(おそらく「postgres」)にあり、その中に表示されているため、「postgres」ロールが所有しています。

alter default privilegesは、「api」によって作成されたテーブルに適用されるため、何も実行しませんが、「api」としてテーブルを作成していません。また、テーブルの所有者はデフォルトで自分のテーブルに対する権限をすでに持っているため、とにかく何もしません。

"postgres"としてログインしたときにテーブルが表示されても、 "api"としてログインしたときに表示されない場合は、notが各ユーザーと同じデータベースにログインしているためと考えられます。データベース「new_db」にロール「postgres」としてログインした場合、テーブルがないため、テーブルは表示されません。データベース「postgres」にロール「api」としてログインすると、表示されます。

1
jjanes