CREATE POLICY#

CREATE POLICY

CREATE POLICY

CREATE POLICY — определить новую политику защиты на уровне строк для таблицы

Синтаксис

CREATE POLICY name ON table_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), чтобы созданные политики применялись.

Политика предоставляет разрешение на выбор, вставку, обновление или удаление строк, которые соответствуют применимому выражению политики. Существующие строки таблицы проверяются на соответствие выражению, указанному в USING, в то время как новые строки, которые будут созданы с помощью INSERT или UPDATE, проверяются на соответствие выражению, указанному в WITH CHECK. Если выражение USING возвращает true для данной строки, она становится видимой для пользователя, а если возвращается false или null, то строка невидима. Если выражение WITH CHECK возвращает истину для строки, она вставляется или обновляется, а если возвращается ложь или null, возникает ошибка.

Для операторов INSERT, UPDATE и MERGE выражения WITH CHECK применяются после срабатывания триггеров BEFORE и перед фактическими модификациями данных. Таким образом, триггер BEFORE ROW может изменить данные, которые будут вставлены, что повлияет на результат проверки политики безопасности. Выражения WITH CHECK применяются перед другими ограничениями.

Имена политик привязаны к таблицам. Поэтому одно имя политики может быть использовано для множества различных таблиц и иметь определение для каждой таблицы, соответствующее этой таблице.

Политики могут применяться к конкретным командам или к конкретным ролям. По умолчанию для вновь созданных политик они применяются ко всем командам и ролям, если не указано иное. К одной команде может применяться несколько политик; подробнее см. ниже. Таблица 291 содержит сводку о том, как различные типы политик применяются к конкретным командам.

Для политик, которые могут иметь как выражения USING, так и WITH CHECK (ALL и UPDATE), если не определено выражение WITH CHECK, то выражение USING будет использоваться как для определения видимых строк (обычный случай USING), так и для разрешения добавления новых строк (WITH CHECK случай).

Если для таблицы включена политика защиты на уровне строк, но нет применимых политик, предполагается политика доступа "отказ по умолчанию", чтобы ни одна строка не была видимой или обновляемой.

Параметры

name

Имя создаваемой политики. Оно должно отличаться от имени любой другой политики для таблицы.

table_name

Имя (опционально с указанием схемы) таблицы, к которой применяется политика.

PERMISSIVE

Укажите, что политика должна быть создана как разрешительная политика. Все разрешительные политики, применимые к данному запросу, будут объединены с использованием логического оператора OR. Создавая разрешительные политики, администраторы могут добавлять записи, к которым можно получить доступ. По умолчанию политики являются разрешительными

RESTRICTIVE

Специфицируйте, что политика должна быть создана как ограничительная политика. Все ограничительные политики, которые применимы к данному запросу, будут объединены с использованием логического оператора AND. Создавая ограничительные политики, администраторы могут сократить набор записей, к которым можно получить доступ, так как для каждой записи должны быть пройдены все ограничительные политики.

Обратите внимание, что должна быть хотя бы одна политика с разрешительными правами, чтобы предоставить доступ к записям, прежде чем ограничительные политики могут быть использованы для сокращения этого доступа. Если существуют только ограничительные политики, то ни одна запись не будет доступна. Когда присутствует смесь политик с разрешительными и ограничительными правами, запись доступна только в том случае, если хотя бы одна из политик с разрешительными правами проходит, в дополнение ко всем ограничительным политикам.

command

Команда, к которой применяется политика. Допустимые варианты: 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 #

Использование ALL для политики означает, что она будет применяться ко всем командам, независимо от типа команды. Если существует политика ALL и существуют более конкретные политики, то будут применяться как политика ALL, так и более конкретная политика (или политики). Кроме того, политики ALL будут применяться как к выборке в запросе, так и к изменению данных, используя выражение USING для обоих случаев, если только выражение USING было определено.

В качестве примера, если выполняется команда UPDATE, то политика ALL будет применяться как к выборке строк, которые UPDATE сможет выбрать для обновления (применяя выражение USING), так и к обновленным строкам, чтобы проверить, разрешено ли их добавление в таблицу (применяя выражение WITH CHECK, если оно определено, и выражение USING в противном случае). Если команда INSERT или UPDATE пытается добавить строки в таблицу, которые не проходят выражение WITH CHECK политики ALL, то вся команда будет прервана.

SELECT #

Использование SELECT для политики означает, что она будет применяться к запросам SELECT и всегда, когда требуются разрешения SELECT на отношение, для которого определена политика. Результатом является то, что только те записи из отношения, которые проходят политику SELECT, будут возвращены во время запроса SELECT, и запросы, которые требуют разрешения SELECT, такие как UPDATE, также будут видеть только те записи, которые разрешены политикой SELECT. Политика SELECT не может иметь выражения WITH CHECK, так как она применяется только в случаях, когда извлекаются записи из отношения.

INSERT #

Использование INSERT для политики означает, что она будет применяться к командам INSERT и командам MERGE, которые содержат действия INSERT. Строки, которые не проходят эту политику, приведут к ошибке нарушения политики, и вся команда INSERT будет прервана. Политика INSERT не может иметь выражение USING, так как она применяется только в случаях, когда записи добавляются в отношение.

Обратите внимание, что INSERT с ON CONFLICT DO UPDATE проверяет политики INSERT, выражения WITH CHECK только для строк, добавленных в отношение через путь INSERT.

UPDATE #

Использование 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 #

Использование DELETE для политики означает, что она будет применяться к командам DELETE. Только строки, проходящие эту политику, будут видны команде DELETE. Могут быть строки, видимые через SELECT, которые нельзя удалить, если они не проходят выражение USING для политики DELETE.

В большинстве случаев команда DELETE также требует чтения данных из столбцов в отношении, из которого происходит удаление (например, в предложении WHERE или RETURNING). В этом случае также требуются права SELECT на отношение, и применяются соответствующие политики SELECT или ALL в дополнение к политикам DELETE. Таким образом, пользователь должен иметь доступ к удаляемой строке(ам) через политику SELECT или ALL, в дополнение к разрешению на удаление строки(ам) через политику DELETE или ALL.

В политике DELETE нельзя использовать выражение WITH CHECK, так как оно применяется только в случаях, когда записи удаляются из отношения, и нет новой строки для проверки.

Таблица 291. Политики, применяемые по типу команды

CommandSELECT/ALL policyINSERT/ALL policyUPDATE/ALL policyDELETE/ALL policy
USING expressionWITH CHECK expressionUSING expressionWITH CHECK expressionUSING expression
SELECTСуществующая строка
SELECT FOR UPDATE/SHAREСуществующая строкаСуществующая строка
INSERT / MERGE ... THEN INSERTНовая строка
INSERT ... RETURNING New row [a] New row
UPDATE / MERGE ... THEN UPDATE Existing & new rows [a] Existing rowNew row
DELETE Existing row [a] Existing row
ON CONFLICT DO UPDATEСуществующие и новые строкиСуществующая строкаНовая строка

[a] Если требуется доступ на чтение к существующей или новой строке (например, предложение WHERE или RETURNING, которая ссылается на столбцы из отношения).


Применение нескольких политик

Когда несколько политик разных типов применяются к одной команде (например, политики SELECT и UPDATE применяются к команде UPDATE), тогда пользователь должен иметь разрешения обоих типов (например, разрешение на выборку строк из отношения, а также разрешение на их обновление). Таким образом, выражения для одного типа политики объединяются с выражениями для другого типа политики с использованием оператора AND.

Когда несколько политик одного типа команды применяются к одной команде, должна существовать хотя бы одна политика PERMISSIVE, предоставляющая доступ к отношению, и все политики RESTRICTIVE должны пройти. Таким образом, все выражения политик PERMISSIVE объединяются с использованием OR, все выражения политик RESTRICTIVE объединяются с использованием AND, и результаты объединяются с использованием AND. Если нет политик PERMISSIVE, доступ запрещен.

Обратите внимание, что для объединения нескольких политик все политики ALL рассматриваются как имеющие тот же тип, что и применяемая другая политика.

Например, в команде UPDATE, требующей как разрешения SELECT, так и UPDATE, если существует несколько применимых политик каждого типа, они будут объединены следующим образом:

expression from RESTRICTIVE SELECT/ALL policy 1
AND
expression from RESTRICTIVE SELECT/ALL policy 2
AND
...
AND
(
  expression from PERMISSIVE SELECT/ALL policy 1
  OR
  expression from PERMISSIVE SELECT/ALL policy 2
  OR
  ...
)
AND
expression from RESTRICTIVE UPDATE/ALL policy 1
AND
expression from RESTRICTIVE UPDATE/ALL policy 2
AND
...
AND
(
  expression from PERMISSIVE UPDATE/ALL policy 1
  OR
  expression from PERMISSIVE UPDATE/ALL policy 2
  OR
  ...
)

Примечания

Вы должны быть владельцем таблицы, чтобы создавать или изменять политики для нее.

В то время как политики будут применяться для явных запросов к таблицам в базе данных, они не применяются при выполнении системой внутренних проверок целостности ссылок или проверки ограничений. Это означает, что существуют косвенные способы определения существования определенного значения. Примером этого является попытка вставить дублирующее значение в столбец, который является первичным ключом или имеет ограничение уникальности. Если вставка не удалась, то пользователь может заключить, что значение уже существует. (Этот пример предполагает, что пользователю разрешено вставлять записи, которые он не может видеть в соответствии с политикой). Другим примером является случай, когда пользователю разрешено вставлять в таблицу, которая ссылается на другую, скрытую таблицу. Существование может быть определено пользователем путем вставки значений в ссылающуюся таблицу, при котором успешная вставка будет указывать на то, что значение существует в целевой таблице. Эти проблемы могут быть решены путем тщательного создания политик, чтобы предотвратить возможность пользователя вставлять, удалять или обновлять записи, которые могут указывать на значение, которое он не может видеть, или путем использования генерируемых значений (например, замещающих ключей) вместо ключей с внешними значениями.

Обычно система применяет условия фильтрации, накладываемые с помощью политик безопасности, перед квалификациями, которые появляются в запросах пользователей, чтобы предотвратить непреднамеренное раскрытие защищенных данных ненадежным пользовательским функциям. Однако функции и операторы, помеченные системой (или системным администратором) как LEAKPROOF, могут быть вычислены перед выражениями политики, так как они считаются надежными.

Так как выражения политики добавляются непосредственно в запрос пользователя, они будут выполняться с правами пользователя, выполняющего общий запрос. Поэтому пользователи, использующие определенную политику, должны иметь доступ к любым таблицам или функциям, на которые ссылается выражение, иначе они просто получат ошибку доступа при попытке запроса таблицы, в которой включена политика защиты на уровне строк. Однако это не изменяет работу представлений. Как и в случае с обычными запросами и представлениями, проверки разрешений и политики для таблиц, на которые ссылается представление, будут использовать права владельца представления и любые политики, применяемые к владельцу представления, за исключением случая, когда представление определено с использованием опции security_invoker (см. CREATE VIEW).

В отношении команды MERGE не существует отдельной политики. Вместо этого применяются политики, определенные для команд SELECT, INSERT, UPDATE и DELETE при выполнении команды MERGE в зависимости от выполняемых действий.

Дополнительное обсуждение и практические примеры можно найти в Раздел 5.8.

Совместимость

CREATE POLICY - это расширение Tantor BE.