CREATE POLICY#
CREATE POLICY
CREATE POLICY — определить новую политику защиты на уровне строк для таблицы
Синтаксис
CREATE POLICYname
ONtable_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. Политики, применяемые по типу команды
Command | SELECT/ALL policy | INSERT/ALL policy | UPDATE/ALL policy | DELETE/ALL policy | |
---|---|---|---|---|---|
USING expression | WITH CHECK expression | USING expression | WITH CHECK expression | USING 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 row | New row | — |
DELETE | Existing row [a] | — | — | — | Existing row |
ON CONFLICT DO UPDATE | Существующие и новые строки | — | Существующая строка | Новая строка | — |
[a]
Если требуется доступ на чтение к существующей или новой строке (например, предложение |
Применение нескольких политик
Когда несколько политик разных типов применяются к одной команде (например, политики SELECT
и UPDATE
применяются к команде UPDATE
), тогда пользователь должен иметь разрешения обоих типов (например, разрешение на выборку строк из отношения, а также разрешение на их обновление). Таким образом, выражения для одного типа политики объединяются с выражениями для другого типа политики с использованием оператора AND
.
Когда несколько политик одного типа команды применяются к одной команде,
должна существовать хотя бы одна политика PERMISSIVE
,
предоставляющая доступ к отношению, и все политики
RESTRICTIVE
должны пройти. Таким образом, все выражения
политик PERMISSIVE
объединяются с использованием
OR
, все выражения политик RESTRICTIVE
объединяются с использованием AND
, и результаты
объединяются с использованием AND
. Если нет
политик PERMISSIVE
, доступ запрещен.
Обратите внимание, что для объединения нескольких политик все политики ALL
рассматриваются как имеющие тот же тип, что и применяемая другая политика.
Например, в команде UPDATE
, требующей как
разрешения SELECT
, так и UPDATE
,
если существует несколько применимых политик каждого типа, они будут объединены
следующим образом:
expression
from RESTRICTIVE SELECT/ALL policy 1 ANDexpression
from RESTRICTIVE SELECT/ALL policy 2 AND ... AND (expression
from PERMISSIVE SELECT/ALL policy 1 ORexpression
from PERMISSIVE SELECT/ALL policy 2 OR ... ) ANDexpression
from RESTRICTIVE UPDATE/ALL policy 1 ANDexpression
from RESTRICTIVE UPDATE/ALL policy 2 AND ... AND (expression
from PERMISSIVE UPDATE/ALL policy 1 ORexpression
from PERMISSIVE UPDATE/ALL policy 2 OR ... )
Примечания
Вы должны быть владельцем таблицы, чтобы создавать или изменять политики для нее.
В то время как политики будут применяться для явных запросов к таблицам в базе данных, они не применяются при выполнении системой внутренних проверок целостности ссылок или проверки ограничений. Это означает, что существуют косвенные способы определения существования определенного значения. Примером этого является попытка вставить дублирующее значение в столбец, который является первичным ключом или имеет ограничение уникальности. Если вставка не удалась, то пользователь может заключить, что значение уже существует. (Этот пример предполагает, что пользователю разрешено вставлять записи, которые он не может видеть в соответствии с политикой). Другим примером является случай, когда пользователю разрешено вставлять в таблицу, которая ссылается на другую, скрытую таблицу. Существование может быть определено пользователем путем вставки значений в ссылающуюся таблицу, при котором успешная вставка будет указывать на то, что значение существует в целевой таблице. Эти проблемы могут быть решены путем тщательного создания политик, чтобы предотвратить возможность пользователя вставлять, удалять или обновлять записи, которые могут указывать на значение, которое он не может видеть, или путем использования генерируемых значений (например, замещающих ключей) вместо ключей с внешними значениями.
Обычно система применяет условия фильтрации, накладываемые с помощью политик безопасности, перед квалификациями, которые появляются в запросах пользователей, чтобы предотвратить непреднамеренное раскрытие защищенных данных ненадежным пользовательским функциям. Однако функции и операторы, помеченные системой (или системным администратором) как LEAKPROOF
, могут быть вычислены перед выражениями политики, так как они считаются надежными.
Так как выражения политики добавляются непосредственно в запрос пользователя, они будут выполняться с правами пользователя, выполняющего общий запрос. Поэтому пользователи, использующие определенную политику, должны иметь доступ к любым таблицам или функциям, на которые ссылается выражение, иначе они просто получат ошибку доступа при попытке запроса таблицы, в которой включена политика защиты на уровне строк. Однако это не изменяет работу представлений. Как и в случае с обычными запросами и представлениями, проверки разрешений и политики для таблиц, на которые ссылается представление, будут использовать права владельца представления и любые политики, применяемые к владельцу представления, за исключением случая, когда представление определено с использованием опции security_invoker
(см. CREATE VIEW
).
В отношении команды MERGE
не существует отдельной политики. Вместо этого применяются политики, определенные для команд SELECT
, INSERT
, UPDATE
и DELETE
при выполнении команды MERGE
в зависимости от выполняемых действий.
Дополнительное обсуждение и практические примеры можно найти в Раздел 5.8.
Совместимость
CREATE POLICY
- это расширение Tantor BE.