Динамическая маскировка снежинки маскирует базовую таблицу: производные таблицы не маскируются, а представления становятся пустыми?
У меня есть необработанная таблица, в которой есть вариантный столбец данных json. Есть несколько обычных представлений (не материализованных представлений), а таблицы создаются с использованием событий json из исходной таблицы.
После применения политики маскирования с использованием UDF к столбцу вариантов необработанной таблицы, когда роль bi_analyst
, я обнаружил две проблемы:
- Таблицы, полученные из базовой таблицы, не маскируются
bi_analyst
роль; - Представления, полученные с использованием базовой таблицы, становятся пустыми с
bi_analyst
роль;
Кто-нибудь знает, почему это произошло? дозировать эту функцию динамического маскирования, не поддерживающую представления в базовой таблице?
Что я хотел бы сделать, так это замаскировать базовые данные, и все таблицы и представления, исходящие из них, также замаскированы с указанной ролью. С этими таблицами легко работать, так как я могу просто применить к ним политику маскирования.
Однако я понятия не имею о взглядах. Как я могу по-прежнему получать доступ к представлениям с ролью, которая должна видеть данные, но не конфиденциальные столбцы?
UDF - это:
-- JavaScript UDF to mask pii data --
use role ACCOUNTADMIN;
CREATE OR REPLACE FUNCTION full_address_masking(V variant)
RETURNS variant
LANGUAGE JAVASCRIPT
AS
$$
if ("detail" in V) {
if ("latitude" in V.detail) {
V.detail.latitude = "******";
}
if ("longitude" in V.detail) {
V.detail.longitude = "******";
}
if ("customerAddress" in V.detail) {
V.detail.customerAddress = "******";
}
}
return V;
$$;
Политика маскирования:
-- Create a masking policy using JavaScript UDF --
create or replace masking policy json_address_mask as (val variant) returns variant ->
CASE
WHEN current_role() IN ('ACCOUNTADMIN') THEN val
WHEN current_role() IN ('BI_ANALYST') THEN full_address_masking(val)
ELSE full_address_masking(val)
END;
Команда sql для установки политики маскирования для необработанных данных:
-- Set masking policy --
use role ACCOUNTADMIN;
alter table DB.PUBLIC.RAW_DATA
modify column EVERYTHING
set masking policy json_address_mask;
Политика маскирования применяется к столбцу вариантов. EVERYTHING
, какая структура данных выглядит:
{
"detail": {
"customAddress": "******",
"id": 1,
"latitude": "******",
"longitude": "******"
},
"source": "AAA"
}
Производная таблица:
create or replace table DB.SCHEMA_A.TABLE_A
as
select * from DB.PUBLIC.RAW_DATA
where everything:source='AAA';
grant select on table DB.schema_A.table_A to role bi_analyst;
Вид:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::float as detail_latitude,
everything:detail:longitude::float as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
grant select on view DB.SCHEMA_A.VIEW_A to role bi_analyst;
В результате RAW_DATA
замаскирован, TABLE_A
совсем не замаскирован, VIEW_A
получает 0 строк, возвращаемых при запросе данных с BI_ANALYST
роль.
2 ответа
№1 - Когда вы создаете таблицу из таблицы, в которой есть замаскированные данные, вы получите данные, к которым у роли, создающей новую таблицу, есть доступ в замаскированной таблице. Итак, в вашем примере TABLE_A имеет немаскированные данные, потому что они были созданы ролью, которая имеет к ним доступ. Политика маскирования не применяется к новой таблице автоматически.
№2 - Что касается №2, я считаю, что ваша единственная проблема заключается в том, что JSON в вашем примере сформирован неправильно, поэтому вы получаете значения NULL. Когда я исправил этот json следующим образом, он отлично работает с той же функцией и политикой маскирования, которые вы опубликовали:
{
"detail":{
"latitude": 132034034.00,
"longitude": 12393438583732,
"id": 1,
"customAddress" : "XXX Road, XXX city, UK"
},
"source": "AAA"
}
Замаскированный результат:
{
"detail": {
"customAddress": "XXX Road, XXX city, UK",
"id": 1,
"latitude": "******",
"longitude": "******"
},
"source": "AAA"
}
Проблема с таблицами, которые не были замаскированы, хорошо объясняется @Mike в своем ответе. Решением может быть просто создание производных таблиц с использованием роли, которая ограничена политикой маскирования.
Проблема представлений связана с типом замаскированного значения "******", которое является строковым типом, в то время как фактический тип полей latitude
а также longitude
плавают. При создании представления я все еще использовалlatitude
а также longitude
поля для плавающего типа:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::float as detail_latitude,
everything:detail:longitude::float as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
Есть скрытая ошибка приведения "******" к плаванию, но снежинка по-прежнему создает вид. Но когда я запрашиваю данные сBI_ANALYST
роль, он возвращает 0 строк.
Таким образом, обходной путь - преобразование этих полей в вариантный тип:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::variant as detail_latitude,
everything:detail:longitude::variant as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
Что не идеально, потому что полностью изменилось определение представления, ни одна из ролей не может получить фактический тип данных с плавающей запятой / числом, даже включая accountadmin