PostgreSQLデータベースの作成を自動化し、データベースユーザーの作成も自動化するアプリがあります。このデータベースユーザーは、クライアントに渡されて使用されるため、セキュリティ上の目的で制限付きアクセスが許可されます。 使用しているバージョンはPostgres 9.6です
CREATE USER %USERSETUP% WITH
LOGIN PASSWORD '%USERSETUPPASS%'
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
INHERIT
NOREPLICATION
CONNECTION LIMIT -1;
ALTER DEFAULT PRIVILEGES IN SCHEMA %SCHEMA% GRANT INSERT, SELECT, UPDATE, DELETE, REFERENCES ON TABLES TO %USERSETUP%;
さて、私のテストは作成されたデータベースにも行き、クエリスクリプトを使用してテーブル名を取得し、各テーブル内の列名を取得します(おまけとして、列のデータ型も取得)
これらの権限のため、ユーザーはinformation_schemaを使用できません。また、SYSTEM CATALOGでクエリスクリプトのみをリクエストしています
テーブル名に使用するスクリプトは機能します。
SELECT tablename FROM pg_catalog.pg_tables where schemaname = '{schema}'
そして、これはテーブル名をリストとして返します:
ビジネス、場所、人、顧客など...
ただし、次の2つのスクリプトを実行して列名を取得すると、このユーザーがinformation_schemaを照会しようとしているかのように、0が返されます。私はそれが特権のためだと思います:
SELECT c.oid,
n.nspname,
c.relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ 'schemaaryzdhyqoi'
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3;
また
SELECT c.oid,
n.nspname,
c.relname, t.*
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
CROSS JOIN LATERAL (
SELECT a.attname,
pg_catalog.format_type(a.atttypid, a.atttypmod),
(
SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid
AND d.adnum = a.attnum
AND a.atthasdef
),
a.attnotnull, a.attnum,
(
SELECT c.collname
FROM
pg_catalog.pg_collation c,
pg_catalog.pg_type t
WHERE c.oid = a.attcollation
AND t.oid = a.atttypid
AND a.attcollation <> t.typcollation
) AS attcollation
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = c.oid
AND a.attnum > 0
AND NOT a.attisdropped
) AS t
WHERE n.nspname ~ '^(schemaaryzdhyqoi)$' -- YOUR SCHEMA HERE
AND pg_catalog.pg_table_is_visible(c.oid);
質問は次のとおりです:スキーマ内の各テーブル内の列の名前(およびおそらくデータ型)だけにアクセスできるように、制限付きユーザーにアクセス許可を追加するにはどうすればよいですか
列レベルの権限を非常に具体的(かつ狭義)に設定して、権限のないユーザーがデータにアクセスできるようにすることができます。あなたの場合、それは2つのカタログです:pg_attribute
およびpg_type
。
alice
というユーザーがいます。このユーザーは、あなたのユーザーと同様に制限されています。
alice@test=> > SELECT * FROM pg_class LIMIT 1;
ERROR: permission denied for relation pg_class
次のGRANT
ステートメントを発行します。
GRANT SELECT (oid, typname) ON pg_type TO alice;
GRANT SELECT (attrelid, attname, atttypid, attnum) ON TABLE pg_attribute TO alice;
これらの後、alice
は以下を実行できます。例えば:
SELECT attname, typname
FROM pg_attribute JOIN pg_type t ON t.oid = atttypid
WHERE attrelid = 't2'::regclass AND attnum > 0;
attname │ typname
─────────┼─────────
key │ jsonb
value │ jsonb
必要に応じて特権を簡単に拡張できます。