Что конкретно делает GRANT USAGE SCHEMA?
Я впервые пытаюсь создать базу данных Postgres, так что это, вероятно, глупый вопрос. Я назначил базовые разрешения только для чтения роли db, которая должна обращаться к базе данных из моих сценариев php, и у меня возникло любопытство: если я выполню
GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;
есть ли необходимость выполнить также
GRANT USAGE ON SCHEMA schema TO role;
?
Из документации:
ИСПОЛЬЗОВАНИЕ: Для схем разрешает доступ к объектам, содержащимся в указанной схеме (при условии, что соблюдаются и собственные требования к привилегиям объектов). По сути, это позволяет получателю "искать" объекты в схеме.
Я думаю, что если я могу выбирать или манипулировать любыми данными, содержащимися в схеме, я могу получить доступ к любым объектам самой схемы. Я ошибся? Если нет, то что GRANT USAGE ON SCHEMA
используется для? И что именно означает документация, когда "предполагается, что собственные требования к привилегиям объектов также выполнены"?
4 ответа
GRANT
ы на разные объекты раздельные. GRANT
в базе данных не GRANT
права на схему внутри. вывести так, GRANT
Использование схемы не дает прав на таблицы внутри.
Если у вас есть права на SELECT
из таблицы, но не вправе видеть его в схеме, которая его содержит, тогда вы не сможете получить доступ к таблице.
Проверка прав проводится в следующем порядке:
Do you have `USAGE` on the schema?
No: Reject access.
Yes: Do you also have the appropriate rights on the table?
No: Reject access.
Yes: Check column privileges.
Ваша путаница может возникнуть из-за того, что public
схема имеет значение по умолчанию GRANT
всех прав на роль public
, членом которой является каждый пользователь / группа. Так что все уже используют эту схему.
Фаза:
(при условии, что собственные требования к привилегиям объектов также выполнены)
Говорит, что вы должны иметь USAGE
на схеме, чтобы использовать объекты внутри нее, но имея USAGE
если схема не является самодостаточной для использования объектов в схеме, вы также должны иметь права на сами объекты.
Это как дерево каталогов. Если вы создаете каталог somedir
с файлом somefile
затем установите его так, чтобы только ваш собственный пользователь мог получить доступ к каталогу или файлу (режим rwx------
на реж, режим rw-------
на файл), тогда никто другой не может перечислить каталог, чтобы увидеть, что файл существует.
Если вы должны были предоставить права на чтение для файла (режим rw-r--r--
) но не меняйте права доступа к каталогу, это не имеет значения. Никто не мог увидеть файл для того, чтобы прочитать его, потому что у них нет прав перечислять каталог.
Если вы вместо этого установите rwx-r-xr-x
в каталоге, установив его так, чтобы люди могли просматривать и просматривать каталог, но не изменяя права доступа к файлу, люди могли перечислять файл, но не могли читать его, потому что у них не было доступа к файлу.
Вам нужно установить оба разрешения, чтобы люди могли реально просматривать файл.
То же самое в Pg. Вам нужны обе схемы USAGE
права и права объекта на выполнение действия над объектом, как SELECT
со стола.
(Аналогия немного падает в том, что PostgreSQL еще не имеет защиты на уровне строк, поэтому пользователь все еще может "увидеть", что таблица существует в схеме, SELECT
из pg_class
непосредственно. Они никак не могут взаимодействовать с ним, так что это просто часть списка, которая не совсем одинакова.)
Для производственной системы вы можете использовать эту конфигурацию:
--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT CONNECT ON DATABASE nova TO user;
--ACCESS SCHEMA
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO user;
--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL ON ALL TABLES IN SCHEMA public TO admin ;
Ну, это мое окончательное решение для простой базы данных для Linux:
# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
# administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
# strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB
#-------------------------------------------------------------------------------
//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//
cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf
# change all `md5` with `scram-sha-256`
# save and exit
//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//
sudo -u postgres psql
# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE
create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL
# Create all tables and objects, and after that:
\connect $DB postgres
revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;
grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;
grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on tables to $ROLE_LOCAL;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on sequences to $ROLE_LOCAL;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on functions to $ROLE_LOCAL;
alter default privileges for role $ROLE_REMOTE in schema public
grant select, insert, update, delete on tables to $ROLE_REMOTE;
alter default privileges for role $ROLE_REMOTE in schema public
grant usage, select on sequences to $ROLE_REMOTE;
alter default privileges for role $ROLE_REMOTE in schema public
grant execute on functions to $ROLE_REMOTE;
# CTRL+D
Мне удалось выполнить операции с базой данных только после назначения пользователя
GRANT ALL PRIVILEGES ON DATABASE chat_db to chat_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA security_user TO chat_user;
GRANT USAGE ON SCHEMA security_user TO chat_user;
GRANT ALL PRIVILEGES ON TABLE web_history_migration TO chat_user;
ALTER SCHEMA security_user OWNER TO chat_user;
так как я использовал там FlywayDB.
хотя, возможно, этого было бы достаточно:
ALTER SCHEMA security_user OWNER TO chat_user;