Во-первых, вы должны иметь возможность подключиться к базе данных, чтобы выполнять запросы. Это может быть достигнуто путем
REVOKE CONNECT ON DATABASE your_database FROM PUBLIC;
GRANT CONNECT
ON DATABASE database_name
TO user_name;
Это REVOKE
необходимо, потому что
Ключевое слово PUBLIC указывает, что привилегии должны быть предоставлены всем ролям, включая те, которые могут быть созданы позже. PUBLIC может рассматриваться как неявно определенная группа, которая всегда включает все роли. Любая конкретная роль будет иметь сумму привилегий, предоставленных непосредственно ей, привилегий, предоставленных любой роли, членом которой она в настоящее время является, и привилегий, предоставленных PUBLIC.
Если вы действительно хотите ограничить пользователя инструкциями DML, то вам нужно сделать немного больше:
REVOKE ALL
ON ALL TABLES IN SCHEMA public
FROM PUBLIC;
GRANT SELECT, INSERT, UPDATE, DELETE
ON ALL TABLES IN SCHEMA public
TO user_name;
Предполагается, что у вас будет только одна схема (по умолчанию она называется public).
Как отметил Джек Дуглас, вышесказанное дает привилегии только для уже существующих таблиц. Чтобы добиться того же для будущих таблиц, вы должны определить привилегии по умолчанию :
ALTER DEFAULT PRIVILEGES
FOR ROLE some_role -- Alternatively "FOR USER"
IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO user_name;
Здесь some_role
роль, которая создает таблицы, а user_name
та, которая получает привилегии. Определяя это, вы должны войти в систему как some_role
член или член.
И, наконец, вы должны сделать то же самое для последовательностей (спасибо PlaidFan за указание на это) - здесь USAGE
вам нужна привилегия.
FOR some_role
была ключевая часть, которую мне не хватало, чтобы она работала для моих таблиц, созданных позже. Но мне не нужно было входить в систему какsome_role
, это работало также, если я выполнял запрос в качестве администратора по умолчаниюpostgres
.