CREATE POLICY — определение новой политики безопасности на уровне строк для таблицы
CREATE POLICYnameONtable_name[ AS { PERMISSIVE | RESTRICTIVE } ] [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] [ TO {role_name| PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ] [ USING (using_expression) ] [ WITH CHECK (check_expression) ]
Инструкция CREATE POLICY определяет новую политику безопасности на уровне строк для таблицы. Обратите внимание, что для применения созданных политик необходимо включить политику безопасности на уровне строк для таблицы (используя ALTER TABLE ... ENABLE ROW LEVEL
SECURITY) in order for created policies to be applied.
Политика предоставляет разрешение на выборку, вставку, обновление или удаление строк, соответствующих определенному выражению политики. Существующие строки таблицы проверяются на соответствие выражению, указанному в USING,
в то время как новые строки, создаваемые с помощью INSERT
или UPDATE проверяются на соответствие выражению, указанному
в WITH CHECK. Когда USING
выражение возвращает true для данной строки, эта строка видима пользователю, а если возвращается false или null, то строка невидима. Когда WITH CHECK выражение возвращает true для строки,
то эта строка вставляется или обновляется, а если возвращается false или null,
то возникает ошибка.
Для INSERT, UPDATE, и
MERGE инструкций,
WITH CHECK выражения применяются после того, как
BEFORE срабатывают триггеры, и до внесения каких-либо фактических изменений данных. Таким образом, BEFORE ROW триггер может изменять вставляемые данные, что влияет на результат проверки политики безопасности. WITH CHECK выражения применяются
перед любыми другими ограничениями.
Имена политик назначаются для каждой таблицы индивидуально. Следовательно, одно и то же имя политики может использоваться для множества различных таблиц и иметь определение для каждой таблицы, соответствующее этой таблице.
Политики могут применяться к конкретным командам или конкретным ролям. По умолчанию вновь создаваемые политики применяются ко всем командам и ролям, если не указано иное. К одной команде могут применяться несколько политик; подробности см. ниже. Таблица 297 суммирует порядок применения различных типов политик к конкретным командам.
Для политик, которые могут иметь оба USING
и WITH CHECK выражения (ALL
и UPDATE), если ни одно WITH CHECK
выражение не определено, тогда USING выражение будет
использоваться как для определения видимых строк (обычный
USING случай), так и для определения того, какие новые строки разрешено добавить (WITH CHECK регистр).
Если для таблицы включена политика безопасности на уровне строк, но применимые политики отсутствуют, «принимается политика запрета по умолчанию» , вследствие чего ни одна строка не будет доступна для просмотра или обновления.
nameИмя создаваемой политики. Оно должно отличаться от имен любых других политик для данной таблицы.
table_nameИмя таблицы (возможно, дополненное именем схемы), к которой применяется политика.
PERMISSIVEУказывает, что создаваемая политика является разрешающей. Все разрешающие политики, применимые к данному запросу, будут объединены с использованием логического «OR» operator. Создавая разрешающие политики, администраторы могут дополнять набор доступных записей. По умолчанию политики являются разрешающими (PERMISSIVE).
RESTRICTIVEУказывает, что создаваемая политика является ограничивающей. Все ограничивающие политики, применимые к данному запросу, будут объединены с использованием логического «AND» operator. Создавая ограничивающие политики, администраторы могут сократить набор записей, к которым можно получить доступ, так как для каждой записи должны быть соблюдены все ограничивающие политики.
Обратите внимание, что для предоставления доступа к записям должна существовать хотя бы одна разрешающая политика, прежде чем ограничивающие политики можно будет эффективно использовать для сужения этого доступа. Если существуют только ограничивающие политики, то ни одна запись не будет доступна. При наличии сочетания разрешающих и ограничивающих политик запись доступна только в том случае, если выполняется хотя бы одна из разрешающих политик в дополнение ко всем ограничивающим политикам.
команда
Команда, к которой применяется политика. Допустимые варианты:
ALL, SELECT,
INSERT, UPDATE,
и DELETE.
ALL используется по умолчанию.
Ниже приведены подробные сведения о том, как они применяются.
role_name
Роли, к которым применяется политика. Значением по умолчанию является
PUBLIC, что применит политику ко всем ролям.
using_expression
Любое SQL условное выражение (возвращающее
boolean). Условное выражение не может содержать агрегатные или оконные функции. Данное выражение будет добавлено к запросам, обращающимся к таблице, если включена политика безопасности на уровне строк. Строки, для которых выражение возвращает истину (true), будут видимы. Строки, для которых выражение возвращает ложь (false) или значение null, не будут видимы пользователю (в SELECT), и будут недоступны для изменения (в UPDATE
или DELETE). Такие строки подавляются без уведомления; ошибка не возвращается.
check_expression
Любое SQL условное выражение (возвращающее
boolean). Условное выражение не может содержать агрегатные или оконные функции. Данное выражение будет использоваться в
INSERT и UPDATE запросы к таблице, если включена политика безопасности на уровне строк. Будут разрешены только те строки, для которых выражение принимает значение true. Если выражение принимает значение false или null для любой из вставляемых записей или любой из записей, полученных в результате обновления, будет выдана ошибка. Обратите внимание, что check_expression вычисляется на основе предлагаемого нового содержимого строки, а не исходного содержимого.
ALL #
Using ALL для политики означает, что она будет применяться
ко всем командам независимо от их типа. Если
ALL политика существует и определены более специфичные политики,
то как ALL общая политика, так и более
специфичные политики будут применены.
Кроме того, ALL политики будут применяться
как к выборке данных в запросе, так и к их изменению, используя
выражение USING для обоих случаев, если определено только
выражение USING expression has been defined.
Например, если выполняется UPDATE , то
ALL политика будет применяться как к тому, что
UPDATE можно будет выбрать в качестве строк для
обновления (с применением USING выражения),
так и к результирующим обновленным строкам для проверки того, разрешено ли
их добавление в таблицу (с применением WITH CHECK
выражения, если оно определено, и USING выражение
в противном случае). Если INSERT
или UPDATE инструкция пытается добавить в
таблицу строки, не проходящие проверку ALL
выражения WITH CHECK политики, выполнение всей
инструкции будет прервано.
SELECT #
Using SELECT для политики означает, что она будет применяться
к SELECT запросам и во всех случаях, когда
SELECT требуются права доступа к отношению
политика определена. В результате только те записи из
отношения, которые удовлетворяют требованиям SELECT политики, будут
возвращены при выполнении SELECT запроса; при этом запросы,
требующие определенных SELECT прав доступа, такие как
UPDATE, также будут видеть только те записи,
которые разрешены данной SELECT политикой.
Для SELECT политики нельзя определить WITH
CHECK выражение, так как оно применяется только в тех случаях, когда
записи извлекаются из отношения.
INSERT #
Using INSERT для политики означает, что она будет применяться
к INSERT команды и MERGE
команды, содержащие INSERT действия.
Вставка строк, которые не
соответствуют данной политике, приведет к ошибке нарушения политики, и
вся INSERT инструкция будет прервана.
Для INSERT политики нельзя указать
выражение USING выражение, так как она применяется только в тех случаях,
когда записи добавляются в отношение.
Обратите внимание, что INSERT с ON CONFLICT DO
UPDATE проверяет INSERT выражения
WITH CHECK политик только для строк, добавляемых
в отношение через INSERT путь.
UPDATE #
Using UPDATE для политики означает, что она будет применяться
к UPDATE, SELECT FOR UPDATE
и SELECT FOR SHARE инструкции, а также
вспомогательные ON CONFLICT DO UPDATE предложения
INSERT инструкций.
MERGE инструкции, содержащие UPDATE
действия также затрагиваются. Поскольку UPDATE
подразумевает извлечение существующей записи и её замену новой
измененной записью, UPDATE
политики принимают как USING выражение, так и
выражение WITH CHECK выражение.
Данное USING выражение определяет, какие записи
выражение UPDATE инструкция будет видеть для выполнения операций,
в то время как WITH CHECK выражение определяет, какие
измененные строки разрешено сохранять обратно в отношение.
Любые строки, обновленные значения которых не проходят проверку через это
WITH CHECK выражение, вызовут ошибку, и
выполнение всей команды будет прервано. Если указано только USING
предложение, то оно будет использоваться для обоих
USING и WITH CHECK случаев.
Как правило, для выполнения UPDATE инструкции также требуется чтение
данных из столбцов обновляемого отношения (например, в
WHERE предложении или RETURNING
предложении, либо в выражении в правой части
SET предложения). В этом случае
SELECT права доступа также требуются для отношения,
которое обновляется, и соответствующее SELECT или
ALL политики будут применяться в дополнение к
выражение UPDATE политикам. Таким образом, пользователь должен иметь
доступ к обновляемой(-ым) строке(-ам) через SELECT
или ALL политику в дополнение к предоставлению
разрешения на обновление строки (строк) через UPDATE
или ALL политикой.
Когда INSERT команда имеет вспомогательное
ON CONFLICT DO UPDATE предложение, если
UPDATE выполняется данный путь, обновляемая строка
сначала проверяется на соответствие USING выражениям
любых UPDATE политик, а затем новая обновленная строка
проверяется на соответствие WITH CHECK выражениям.
Заметьте, однако, что в отличие от отдельной UPDATE
команды, если существующая строка не проходит
USING выражения, будет выдана ошибка (этот
UPDATE путь никогда не будет незаметно
обойден).
DELETE #
Using DELETE для политики означает, что она будет применяться
к DELETE команды. Только те строки, которые проходят проверку этой
политики, будут видны DELETE команде. Могут
существовать строки, видимые через SELECT которые
недоступны для удаления, если они не соответствуют
USING выражению для
выражение DELETE политикой.
В большинстве случаев DELETE инструкции также требуется чтение
данные из столбцов отношения, из которого выполняется удаление (например,
в WHERE предложении или
RETURNING предложения). В данном случае,
SELECT права также требуются для отношения,
и соответствующее SELECT или
ALL политики будут применяться в дополнение к
выражение DELETE политикам. Таким образом, пользователь должен иметь
доступ к удаляемой строке (строкам) через SELECT
или ALL политику в дополнение к предоставлению
разрешение на удаление строки (строк) посредством DELETE или
ALL политикой.
Для DELETE политики нельзя определить WITH
CHECK выражение, так как оно применяется только в тех случаях, когда
записи удаляются из отношения, вследствие чего нет
новой строки для проверки.
Таблица 297. Политики, применяемые в зависимости от типа команды
| Команда | Политика SELECT/ALL | Политика INSERT/ALL | Политика UPDATE/ALL | Политика DELETE/ALL | |
|---|---|---|---|---|---|
выражение USING | выражение WITH CHECK | выражение USING | выражение WITH CHECK | выражение USING | |
SELECT | Существующая строка | — | — | — | — |
SELECT FOR UPDATE/SHARE | Существующая строка | — | Существующая строка | — | — |
INSERT / MERGE ... THEN INSERT | — | Новая строка | — | — | — |
INSERT ... RETURNING | Новая строка [a] | Новая строка | — | — | — |
UPDATE / MERGE ... THEN UPDATE | Существующие и новые строки [a] | — | Существующая строка | Новая строка | — |
DELETE | Существующая строка [a] | — | — | — | Существующая строка |
ON CONFLICT DO UPDATE | Существующие и новые строки | — | Существующая строка | Новая строка | — |
[a]
Если требуется доступ на чтение к существующей или новой строке (например,
выражение | |||||
Когда к одной и той же команде применяются несколько политик разных типов
(например, SELECT и UPDATE
политики, применяемые к UPDATE команде), пользователь
должен обладать обоими типами прав (например, правом на выборку строк
из отношения, а также правом на их обновление). Таким образом,
выражения одного типа политики объединяются с выражениями
другого типа политики при помощи AND оператора.
Когда к одной и той же команде применяются несколько политик одного типа, должна существовать хотя бы одна PERMISSIVE политика,
предоставляющая доступ к отношению, и все
RESTRICTIVE политики должны быть соблюдены. Таким образом, все
PERMISSIVE выражения политик объединяются с помощью
OR, все RESTRICTIVE выражения
политик объединяются с помощью AND, а результаты объединяются с помощью AND. Если
PERMISSIVE политики отсутствуют, доступ будет запрещен.
Обратите внимание, что при объединении нескольких политик
ALL политики рассматриваются как имеющие тот же тип, что и любой другой тип применяемой политики.
Например, в UPDATE инструкции, требующей одновременно
SELECT и UPDATE прав доступа, если
имеется несколько применимых политик каждого типа, они будут объединены
следующим образом:
выражениеиз ограничивающей политики SELECT/ALL 1 Ивыражениеиз ограничивающей политики SELECT/ALL 2 И ... И (выражениеиз разрешающей политики SELECT/ALL 1 ИЛИвыражениеиз разрешающей политики SELECT/ALL 2 ИЛИ ... ) Ивыражениеиз ограничивающей (RESTRICTIVE) политики UPDATE/ALL 1 ANDвыражениеиз ограничивающей (RESTRICTIVE) политики UPDATE/ALL 2 AND ... AND (выражениеиз разрешающей (PERMISSIVE) политики UPDATE/ALL 1 ORвыражениеиз разрешающей (PERMISSIVE) политики UPDATE/ALL 2 OR ... )
Для создания или изменения политик таблицы необходимо быть её владельцем.
Хотя политики применяются к явным запросам к таблицам в базе данных, они не применяются, когда система выполняет внутренние проверки ссылочной целостности или проверку ограничений. Это означает, что существуют косвенные способы определить факт существования заданного значения. Примером этого может служить попытка вставки дублирующего значения в столбец, являющийся первичным ключом или имеющий ограничение уникальности. Если операция вставки завершается ошибкой, пользователь может сделать вывод, что данное значение уже существует. (В данном примере предполагается, что политика позволяет пользователю вставлять записи, которые ему запрещено просматривать.) Другой пример — ситуация, когда пользователю разрешено выполнять вставку в таблицу, ссылающуюся на другую, скрытую в иных случаях таблицу. Факт существования может быть определен пользователем путем вставки значений в ссылающуюся таблицу, при этом успешное выполнение операции будет указывать на то, что значение существует в ссылочной таблице. Эти проблемы можно решить путем тщательной разработки политик, запрещающих пользователям вставку, удаление или обновление записей, которые могут косвенно указывать на значения, недоступные им иным образом, либо путем использования генерируемых значений (например, суррогатных ключей) вместо ключей, имеющих внешнее значение.
Как правило, система применяет условия фильтрации, наложенные политиками безопасности, до обработки условий, указанных в пользовательских запросах; это позволяет предотвратить непреднамеренное раскрытие защищенных данных пользовательским функциям, которые могут не заслуживать доверия. Однако,
функции и операторы, помеченные системой (или системным
администратором) как LEAKPROOF могут вычисляться до выражений политики, так как они считаются доверенными.
Поскольку выражения политики добавляются непосредственно в запрос пользователя, они будут выполняться с правами того пользователя, который запускает основной запрос. Таким образом, пользователи, к которым применяется данная политика, должны иметь доступ ко всем таблицам и функциям, указанным в выражении; в противном случае при попытке обращения к таблице с включенной политикой безопасности на уровне строк будет возвращена ошибка об отсутствии прав доступа. При этом для представлений сохраняется стандартный механизм работы. Как и в обычных запросах или представлениях, при проверке прав доступа и применении политик к таблицам, на которые ссылается представление, используются права владельца представления и политики, относящиеся к нему, если только представление не определено с использованием security_invoker параметра
(см. CREATE VIEW).
Для операции MERGE. не существует отдельной политики. Вместо этого применяются политики,
определенные для SELECT, INSERT,
UPDATE, и DELETE применяются при выполнении MERGE, в зависимости от совершаемых действий.
Дополнительные сведения и практические примеры приведены в Раздел 2.2.9.
CREATE POLICY является Digital Q.DataBase
расширением.