Глава 17. Контроль доступа к данным
«Классификация без контроля доступа — декорация. Контроль доступа без мониторинга — иллюзия.»
В главе 16 мы классифицировали данные и защитили их шифрованием. Теперь нужно ответить на вопрос: кто, когда и при каких условиях получает доступ к конкретным данным? Это покрывает возможности 4 (Data Monitoring & Sensing) и 7 (Data Access Control) из NSA Data Pillar.
17.1 Зачем: от RBAC к ABAC
Ролевой контроль доступа (RBAC) назначает разрешения через роли: analyst может читать таблицу orders. Но что если analyst из Европы должен видеть только европейские заказы? А analyst с незащищённого устройства — только агрегаты?
NIST SP 800-162 определяет Attribute-Based Access Control (ABAC):
«Access control methodology where authorization is determined by evaluating attributes associated with the subject, object, requested operations, and environment conditions against policy.»
Четыре компонента ABAC совпадают с архитектурой Zero Trust (NIST SP 800-207):
| ABAC (NIST 800-162) | Zero Trust (800-207) | Назначение |
|---|---|---|
| Policy Decision Point (PDP) | Механизм политик (PE) | Принимает решения |
| Policy Enforcement Point (PEP) | Точка применения политик (PEP) | Применяет решения |
| Policy Information Point (PIP) | Источники контекста | Предоставляет атрибуты |
| Policy Administration Point (PAP) | Администратор политик (PA) | Управляет политиками |
Ключевое преимущество ABAC: решения меняются динамически при изменении атрибутов — без перестройки ролевой модели.
17.2 Гранулярный контроль в облаках
AWS Lake Formation: Tag-Based Access Control
Lake Formation реализует ABAC через LF-Tags — пары ключ-значение, назначаемые ресурсам Data Catalog.
Масштабируемость: классический метод (Named Resource) требует n(Principals) × n(Resources) грантов. LF-TBAC — только n + n. Для 3 пользователей и 10 таблиц: 30 грантов vs 13 операций.
-- Назначение тегов ресурсам
ALTER TABLE sales.orders SET LF_TAGS ('classification'='confidential');
ALTER TABLE sales.products SET LF_TAGS ('classification'='internal');
-- Грант на основе тегов
GRANT SELECT ON TAGS (classification='confidential')
TO PRINCIPAL 'arn:aws:iam::123456789012:role/AnalystEU';Fine-Grained Access Control (FGAC) — Lake Formation поддерживает контроль на уровне строк и ячеек (row-level и cell-level security) для Athena, Redshift Spectrum, Glue ETL и EMR (GA с ноября 2021, улучшения автоматической компактификации — ноябрь 2024).
Источник: aws.amazon.com/lake-formation/features, docs.aws.amazon.com/lake-formation/latest/dg/data-filtering.html
GCP BigQuery: Row-Level и Column-Level Security
Column-level security использует policy tags из Data Catalog:
-- Доступ к защищённым столбцам требует роли
-- Data Catalog Fine-Grained Reader на соответствующем policy tag
-- Настраивается через Data Catalog Taxonomy APIRow-level security — DDL-команда CREATE ROW ACCESS POLICY:
CREATE ROW ACCESS POLICY eu_only_filter
ON project.dataset.orders
GRANT TO (
"group:[email protected]",
"serviceAccount:[email protected]"
)
FILTER USING (region = "EU");Политика работает как WHERE-clause: пользователи видят только строки, соответствующие фильтру.
Источник: cloud.google.com/bigquery/docs/row-level-security-intro
Azure: Microsoft Purview Data Policies
Microsoft Purview предоставляет data owner policies — грант доступа к данным напрямую из портала Purview governance. При наличии нескольких политик применяется наиболее ограничительная.
17.3 Мониторинг активности баз данных
Контроль доступа без аудита — незавершённая защита. NSA Data Pillar (возможность 4: Data Monitoring & Sensing) требует обнаружения аномального доступа.
pgAudit для PostgreSQL
pgAudit обеспечивает детализированный аудит через стандартный механизм логирования PostgreSQL. Два режима:
Session audit — глобальный аудит по классам операций:
-- На уровне базы данных
ALTER DATABASE finance SET pgaudit.log = 'read,write';
-- Классы: READ, WRITE, FUNCTION, ROLE, DDL, MISC, MISC_SET, ALLObject audit — аудит доступа к конкретным таблицам:
-- Создание роли-аудитора
CREATE ROLE auditor WITH NOLOGIN;
ALTER DATABASE finance SET pgaudit.role = 'auditor';
-- Аудит всех SELECT к таблице salary
GRANT SELECT ON salary TO auditor;Только суперпользователи могут изменять настройки pgAudit — иначе пользователи могли бы отключить свой аудит.
Источник: github.com/pgaudit/pgaudit
AWS Database Activity Streams
Amazon RDS передаёт активность БД в Amazon Kinesis в режиме реального времени:
- Всегда зашифровано — AWS KMS обязателен
- Поддерживаемые движки — Aurora (MySQL/PostgreSQL), RDS for SQL Server, RDS for Oracle
- Ретенция — 24 часа по умолчанию в Kinesis
- Стоимость — DAS бесплатно, оплата только за Kinesis
RDS/Aurora → Database Activity Streams → Kinesis → Lambda/S3/SIEM
→ Guardium/ImpervaИсточник: docs.aws.amazon.com/AmazonRDS/latest/UserGuide/DBActivityStreams.html
GCP Cloud SQL Audit
- PostgreSQL: расширение pgAudit, включается через флаг
cloudsql.enable_pgaudit - MySQL: плагин
cloudsql_mysql_audit(MySQL Audit API), логи в Cloud Logging
Ограничение: максимальная скорость записи логов — 4 МБ/с. Превышение может привести к исчерпанию диска.
Azure SQL Auditing
Azure SQL аудит записывает события в три возможных направления (любая комбинация):
- Azure Storage account
- Log Analytics workspace
- Event Hubs
Серверный аудит применяется ко всем существующим и новым базам данных.
Источник: learn.microsoft.com/azure/azure-sql/database/auditing-overview
17.4 Data Lineage: происхождение данных
Data lineage отвечает на вопрос: откуда пришли данные и как они трансформировались? Это критично для Zero Trust: если данные скомпрометированы, нужно знать все downstream-системы.
OpenLineage: открытый стандарт
OpenLineage (LFAI & Data Foundation, graduated Sep 2023) определяет четыре ключевые сущности:
| Сущность | Идентификатор | Описание |
|---|---|---|
| Job | namespace + name | Процесс, потребляющий и производящий датасеты |
| Run | UUID | Экземпляр выполнения job |
| Dataset | namespace + name | Данные (таблица, файл, топик) |
| Facet | — | Метаданные, привязанные к любой сущности |
Три типа событий: RunEvent, DatasetEvent, JobEvent. Спецификация формализована в JsonSchema.
Источник: openlineage.io/docs/spec/object-model
Облачные решения
| Облако | Сервис | OpenLineage-совместим | Особенности |
|---|---|---|---|
| AWS | Amazon DataZone | Да (GA 2024) | Lineage из Glue v5.0+, dbt, Airflow, Spark |
| GCP | Dataplex Universal Catalog | Да (ProcessOpenLineageRunEvent API) | Column-level lineage для BigQuery; ретенция 30 дней |
| Azure | Microsoft Purview | Да (OpenLineage connector) | Data Factory, Synapse, Databricks |
Ограничение GCP Dataplex: lineage данные хранятся только 30 дней и появляются в течение 24 часов после выполнения job.
17.5 Токенизация данных
Токенизация заменяет чувствительные значения на неинформативные токены, сохраняя функциональность системы.
FPE vs Tokenization
| Характеристика | Format-Preserving Encryption (FPE) | Tokenization |
|---|---|---|
| Обратимость | Да (с ключом) | Да (vaulted) или нет (vaultless) |
| Формат | Сохраняет длину и тип символов | Может сохранять или нет |
| Стандарт | NIST AES FF1, FF3-1 | Нет единого стандарта |
| Хранение | Stateless (без состояния) | Stateful (vault) или stateless |
| Применение | Кредитные карты, SSN | Любые чувствительные данные |
HashiCorp Vault Transform
Требует Vault Enterprise с модулем Advanced Data Protection (ADP-Transform).
Три типа трансформаций:
# 1. FPE (FF3-1 + AES-256) — обратимое, сохраняет формат
vault write transform/transformation/card-fpe \
type=fpe \
template=creditcardnumber \
tweak_source=internal \
allowed_roles=payments
# 2. Masking — необратимое, замена символов
vault write transform/transformation/card-mask \
type=masking \
template=creditcardnumber \
masking_character="#" \
allowed_roles=analytics
# 3. Tokenization — stateful, с хранилищем
vault write transform/transformation/card-token \
type=tokenization \
allowed_roles=processingИсточник: developer.hashicorp.com/vault/docs/secrets/transform
GCP Sensitive Data Protection
GCP SDP предоставляет de-identification как API-сервис (см. главу 16, раздел 16.5):
- FPE-FFX — обратимое, сохраняет формат
- AES-SIV — детерминированное шифрование, base64-encoded с surrogate annotation
- HMAC-SHA-256 — необратимый хеш
- Character masking — замена символов
17.6 AI/ML Data Governance
Рост AI/ML создаёт новые вызовы для data governance: кто имеет доступ к обучающим данным? Какие модели используют какие датасеты? Как предотвратить утечку данных через инференс?
NIST AI 600-1: Generative AI Risk Profile
NIST AI 600-1 (26 июля 2024) — профиль управления рисками генеративного AI, дополняющий AI RMF 1.0. Выделяет 12 специфических рисков GAI, включая:
- Data leakage (утечка обучающих данных через выходы модели)
- Hallucinations (генерация ложной информации)
- Harmful bias (предвзятость в данных и моделях)
- CBRN information access (доступ к опасной информации)
Четыре приоритета: Governance, Content Provenance, Pre-deployment Testing, Incident Disclosure.
Источник: nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence
Практические контроли
| Контроль | AWS | GCP | Azure |
|---|---|---|---|
| Доступ к моделям | SageMaker Role Manager, IAM ABAC | Vertex AI Model Organization Policy | Azure AI Studio RBAC |
| Lineage обучающих данных | DataZone (OpenLineage) | Vertex AI Experiments | Purview Data Lineage |
| Аудит инференса | CloudWatch Logs, CloudTrail | Cloud Logging | Azure Monitor |
| Guardrails | Bedrock Guardrails | Model Armor | Azure AI Content Safety |
17.7 Лаборатория: OPA для контроля доступа к данным
Цель
Реализовать ABAC-политику с помощью OPA, контролирующую доступ к данным на основе атрибутов пользователя и классификации данных.
Предварительные требования
- Docker
- OPA CLI (
brew install opaили из GitHub releases)
Шаг 1: Создание политики
mkdir -p opa-data-lab && cd opa-data-labФайл policy.rego:
package data_access
import rego.v1
# По умолчанию — запретить
default allow := false
# Разрешить доступ к public данным для всех аутентифицированных
allow if {
input.resource.classification == "public"
input.subject.authenticated == true
}
# Разрешить доступ к internal данным для сотрудников
allow if {
input.resource.classification == "internal"
input.subject.authenticated == true
input.subject.employee == true
}
# Разрешить доступ к confidential данным:
# - сотрудник + соответствующий отдел + защищённое устройство
allow if {
input.resource.classification == "confidential"
input.subject.authenticated == true
input.subject.employee == true
input.subject.department == input.resource.department
input.subject.device_compliant == true
}
# Разрешить доступ к restricted данным:
# - всё вышеперечисленное + MFA + одобренная роль
allow if {
input.resource.classification == "restricted"
input.subject.authenticated == true
input.subject.employee == true
input.subject.department == input.resource.department
input.subject.device_compliant == true
input.subject.mfa_verified == true
input.subject.role in input.resource.allowed_roles
}
# Причина отказа для аудита
reason contains msg if {
not allow
input.resource.classification == "confidential"
not input.subject.device_compliant
msg := "device not compliant"
}
reason contains msg if {
not allow
input.resource.classification == "restricted"
not input.subject.mfa_verified
msg := "MFA not verified"
}Шаг 2: Тестовые данные
Файл input_allow.json:
{
"subject": {
"authenticated": true,
"employee": true,
"department": "finance",
"device_compliant": true,
"mfa_verified": true,
"role": "analyst"
},
"resource": {
"classification": "confidential",
"department": "finance",
"allowed_roles": ["analyst", "manager"]
},
"action": "read"
}Файл input_deny.json:
{
"subject": {
"authenticated": true,
"employee": true,
"department": "engineering",
"device_compliant": false,
"mfa_verified": false,
"role": "developer"
},
"resource": {
"classification": "confidential",
"department": "finance",
"allowed_roles": ["analyst", "manager"]
},
"action": "read"
}Шаг 3: Проверка политики
# Тест 1: доступ разрешён (finance analyst → confidential finance data)
opa eval -d policy.rego -i input_allow.json "data.data_access.allow"
# Результат: true
# Тест 2: доступ запрещён (engineering dev → confidential finance data)
opa eval -d policy.rego -i input_deny.json "data.data_access.allow"
# Результат: false
# Тест 3: причина отказа
opa eval -d policy.rego -i input_deny.json "data.data_access.reason"
# Результат: ["device not compliant"]Шаг 4: OPA как сервер (для интеграции с приложениями)
# Запуск OPA как REST API
docker run -d --name opa -p 8181:8181 \
-v $(pwd)/policy.rego:/policy.rego \
openpolicyagent/opa:latest run --server /policy.rego
# Запрос решения
curl -s -X POST http://localhost:8181/v1/data/data_access/allow \
-H "Content-Type: application/json" \
-d @input_allow.json | jq .
# {"result": true}
# Очистка
docker rm -f opaИнтеграция с БД: в production OPA возвращает решения, а приложение или прокси (Envoy, API Gateway) применяет их. Для PostgreSQL паттерн описан в OPA Blog: «Write Policy in OPA. Enforce Policy in SQL.» — OPA генерирует WHERE-clause, приложение передаёт его в запрос.
17.8 Чек-лист
- [ ] ABAC-модель определена (атрибуты субъектов, объектов, среды)
- [ ] Гранулярный контроль данных развёрнут (Lake Formation FGAC / BigQuery RLS / Purview policies)
- [ ] Аудит БД включён (pgAudit / DAS / Cloud SQL Audit / Azure SQL Auditing)
- [ ] Data lineage отслеживается (OpenLineage / Dataplex / Purview)
- [ ] Токенизация применяется для чувствительных полей (Vault Transform / GCP SDP / FPE)
- [ ] AI/ML governance определён: доступ к моделям, обучающим данным, аудит инференса
- [ ] OPA или аналогичный PDP используется для динамических решений о доступе
- [ ] Мониторинг аномального доступа настроен (NSA: Data Monitoring & Sensing)
17.9 Итоги
Контроль доступа к данным — это динамическая система, а не набор статических правил. Ключевые принципы:
- ABAC > RBAC для данных — атрибуты позволяют принимать решения на основе контекста (устройство, время, местоположение), что соответствует принципу «никогда не доверяй» NIST SP 800-207
- Мониторинг = обязательность — pgAudit, Database Activity Streams, Cloud SQL Audit обеспечивают видимость, без которой невозможно обнаружение аномалий
- Lineage для оценки радиуса поражения — при инциденте lineage показывает все затронутые downstream-системы
- Токенизация > шифрование для аналитики — FPE и токенизация позволяют работать с данными без их раскрытия
- AI/ML — новый фронтир — NIST AI 600-1 даёт фреймворк для управления рисками, но практики только формируются
С завершением Части VI (главы 16-17) мы покрыли пятый столп CISA — данные. В Части VII перейдём к сквозным аспектам: наблюдаемости, политике как коду, реагированию на инциденты и комплаенсу.