Learning Platform
Глоссарий Troubleshooting
Урок 08.02 · 28 мин
Продвинутый
Evidence PipelineS3 Object LockImmutable StorageRetentionWORMArchitectureGESoda Core

Введение

CDO Office решает: операционных DQ-прогонов хватает (24 часовых GE-прогона × 8 контролей × 1.2M поездок в день), но реконструкция evidence за Q3 2024 показывает пробелы — 6 из 30 sampled прогонов не могут быть восстановлены (UPDATE Snowflake-таблицы перезаписали старые строки; никто не зафиксировал hash входа). Engineering Lead: «Нужно строить proper pipeline». CDO: «Что значит proper?». Lead: «End-to-end — от DQ engine до auditor view, с неизменяемым архивом посередине».

Этот урок — паттерн архитектуры. M7.1 описал, какие атрибуты должен иметь evidence; M7.2 — как evidence pipeline их физически собирает + хранит.

Пайплайн — 5 стадий

End-to-end:

  1. DQ engine — выполняет правила (GE / Soda / dbt / custom).
  2. Metadata emitter — нормализует результаты в структурированную схему; добавляет timestamp, подпись, control_id.
  3. Неизменяемое хранилище — WORM-персистентность с retention SOX-grade.
  4. Attestation system — review Business Owner + sign-off; exception management.
  5. Auditor view — read-only доступ для external + internal audit.
Evidence pipeline — DQ engine → emitter → immutable store → attestation → auditor

Переключи tooling stack (GE 1.17.1 / Soda 4.0 / Anomalo). Кликни stage → IPE attributes + required artefacts + anti-patterns + SwiftRide example. Storage и auditor stages tool-agnostic by design.

rules → events → WORM artefacts → sign-off → audit retrieval
Кликни stage выше, чтобы открыть детализацию — IPE attributes, артефакты, анти-паттерны, SwiftRide example.

Стек выше — переключаемый: GE 1.17.1, Soda 4.0, Anomalo. Хранилище и стадия auditor — tool-agnostic по дизайну (separation of concerns — целостность evidence не зависит от выбора DQ-инструмента).

Стадия 1 — DQ engine

Согласно M5.5 — правила DQ реализуют контроль-активности. Взгляд M7 — engine выдаёт структурированный вывод, пригодный для эмиссии evidence.

Необходимый вывод per run:

  • run_id (UUID, сгенерированный engine)
  • rule_id или expectation_name (стабильный, версионированный)
  • dataset_identifier (FQN — snowflake.dl_marts.fct_driver_earnings)
  • dataset_snapshot_pointer (timestamp снапшота Snowflake, S3 versionId, dbt manifest SHA)
  • input_metrics (row count, hash sample)
  • rule_logic_version (semantic version или git SHA файла expectations)
  • thresholds (полный снапшот, а не просто указатель — пороги могут меняться между прогонами)
  • observed_values (числитель, знаменатель, вычисленная метрика)
  • result (pass / fail / exception + код причины)
  • execution_metadata (compute resource, идентичность runner’а, runtime в секундах)

Нативный вывод GE 1.17.1:

Great Expectationsv1.17.12026-05

GE Core 1.17.1 (5 May 2026, Python 3.10-3.13) — Checkpoint API возвращает CheckpointResult объект с validation_results[] per expectation. Каждый entry содержит expectation_config (kwargs сериализованы; сохраняет пороги), result (observed_value, element_count, unexpected_count), success: bool. data_context.checkpoint_store архивирует на filesystem / S3 (конфигурируемый backend). Data Docs HTML рендерится как вспомогательный человеко-читаемый вид (не primary evidence). Миграция с legacy 0.x → GX Core 1.x: доступен инструмент миграции expectation suite; коммерческий GX Cloud версионируется отдельно.

Нативный вывод Soda Core 4.0:

Soda Corev4.02026-05

Soda Core 4.0 (2025) — contract-first модель. data_contract.yml определяет проверки через SodaCL DSL. soda scan возвращает ScanResults JSON: per-check check_name, metric (наблюдаемое значение), outcome (‘pass’/‘fail’/‘warn’), failed_rows_sample (выборка нарушающих записей). Soda Cloud (SaaS) добавляет incident workflow; on-prem agent запускает сканы внутри VPC и emit’ит результаты через webhook. Audit trail через Soda Cloud — retention контрактный; SOX-grade требует отдельного слоя архива.

Стадия 2 — Metadata emitter

Вывод engine — внутренний для инструмента. Emitter нормализует к организационной evidence-схеме. Три обязанности.

1. Нормализация схемы. Стандартная схема evidence по всем engine; аудитор не должен парсить 3 разных формата. Evidence-схема SwiftRide v1:

{
  "evidence_version": "1.0",
  "evidence_id": "ev_2026091506000000_ctl-cde-swr-003-002",
  "timestamp_utc": "2026-09-15T06:00:00Z",
  "control_id": "CTL-CDE-SWR-003-002",
  "cde_id": "CDE-SWR-003",
  "engine": {
    "tool": "great_expectations",
    "version": "1.17.1",
    "run_id": "ge-uuid-...",
    "expectation_suite_version": "v3.2.0"
  },
  "input_state": {
    "dataset_fqn": "snowflake.dl_marts.fct_driver_earnings",
    "snapshot_at": "2026-09-15T05:59:00Z",
    "input_hash": "sha256:..."
  },
  "rule": {
    "rule_id": "expect_column_values_to_be_between",
    "thresholds": {"min": 0, "max": null}
  },
  "result": "pass",
  "observed_values": {...},
  "exception": null,
  "signature": {
    "algorithm": "HMAC-SHA256",
    "key_id": "alias/swr-evidence-signing-key",
    "value": "hex..."
  }
}

2. Подпись. HMAC-SHA256 через AWS KMS-ключ (alias swr-evidence-signing-key); доступ к ключу — IAM-роль, ассамируемая только emitter Lambda; ротация 90 дней; CloudTrail логирует всё использование ключа. Подпись покрывает все поля, кроме самой signature.

3. Emit к downstream sinks. Emitter emit’ит параллельно:

  • Неизменяемое хранилище — S3 Object Lock первичная персистентность.
  • OpenLineage event — RunEvent с DataQualityFacet в Kafka topic openlineage.runs → Marquez consumer + S3 archive consumer.
  • Operational signal — PagerDuty/Slack при fail (реагирование на инциденты — M7.4).

Архитектурный паттерн — emitter является единой точкой целостности. Если emitter скомпрометирован, цепочка evidence скомпрометирована. Защита:

  • Emitter — отдельный AWS-аккаунт (swr-evidence-prod); минимальный IAM-доступ.
  • Доступ к KMS-ключу логируется в CloudTrail; алерты на необычные паттерны доступа.
  • Code review ужесточён (CODEOWNERS = audit + security + data platform leads).
  • Emitter деплоится через GitOps; PR на любое изменение требует одобрения нескольких команд.

Стадия 3 — Неизменяемое хранилище

Выбор хранилища:

ПаттернСильные стороныСлабые стороныСлучай применения
S3 Object Lock — Compliance ModeRoot-аккаунт не может обойти; сильнейший WORMОперационная жёсткость — даже легитимная очистка требует legal reviewДефолт для evidence material CDE; паттерн SwiftRide
S3 Object Lock — Governance ModeRoot-аккаунт может обойти через s3:BypassGovernanceRetentionБолее слабая гарантия WORMПриемлемо, если IAM жёстко ограничивает обход + алерты на использование; менее зрелые программы
Azure Blob — Immutable Storage PolicyTime-based или legal holdAzure-native; реже встречается в стеке SwiftRideПреимущественно Azure-организации
AWS QLDBКриптографическая верификация + ledger semanticsОперационные накладные расходы; дорогоHigh-stakes records (сами attestations, не ежедневные DQ-прогоны)
WORM-бакет в отдельном AWS-аккаунтеDefence-in-depth; компрометация основного аккаунта не затрагивает evidenceНакладные расходы на cross-account billing/accessMaterial CDE + tier-1 финансовая значимость

Паттерн SwiftRide:

AWS Account: swr-evidence-prod (отдельный от операционных аккаунтов)
Region: eu-west-1 (primary) + репликация в eu-central-1 (DR)
Bucket: swr-evidence-prod-cde-evidence
Configuration:
  - Versioning: enabled
  - Object Lock: enabled, default retention 7 лет mode COMPLIANCE
  - Encryption: SSE-KMS, key alias/swr-evidence-encryption-key
  - Lifecycle: transition в Glacier Deep Archive после 1 года; expiration нет (Compliance Mode препятствует)
  - Replication: cross-region replication в eu-central-1
  - Access logging: enabled, в отдельный logging-бакет
  - Public access: blocked
  - IAM: write-only Lambda-роль; read-only audit-роль; IAM-разрешение на bypass удалено

Структура ключа:

s3://swr-evidence-prod-cde-evidence/
  cde-swr-003/
    ctl-cde-swr-003-002/
      year=2026/
        month=09/
          day=15/
            ev_2026091506000000_ctl-cde-swr-003-002.json

Партиционирование позволяет эффективные запросы через Snowflake EXTERNAL TABLE / Athena. Аудит, выбирающий выборки per control × period — partition prune высокоэффективен.

Evidence index:

Snowflake-таблица audit.evidence_index — вторичный индекс, указывающий на S3-ключи. Изменяемый для обновлений индекса (например, при добавлении нового evidence), но первичный evidence — неизменяем. Аудитор использует индекс только для discovery; верификация идёт в S3.

CREATE TABLE audit.evidence_index (
  evidence_id VARCHAR PRIMARY KEY,
  control_id VARCHAR,
  cde_id VARCHAR,
  timestamp_utc TIMESTAMP_NTZ,
  s3_key VARCHAR,
  evidence_sha256 VARCHAR,
  retention_expires DATE,
  signed_by VARCHAR,
  result VARCHAR
);

CREATE VIEW audit.evidence_index_audit_view AS
SELECT * FROM audit.evidence_index;
-- Granted SELECT only to AUDIT_AUDITOR_ROLE

Стадия 4 — Attestation system

GRC-платформа интегрирует evidence:

  • Workiva — SOX-first; AI-assisted control testing; широко развёрнута в Fortune 500.
  • AuditBoard — audit-first; mid-market к large enterprise; SOX + ESG.
  • ServiceNow IRM — угол continuous control monitoring (CCM); хорошо интегрируется с существующим стеком ServiceNow ITSM.
  • LogicGate Risk Cloud — современный no-code; более быстрый деплой (1-3 месяца).
  • Archer (Cinven) — наследие tier-1 банков; глубокая конфигурируемость, долгий деплой.

SwiftRide T+9M — выбран Workiva (SOX-first дорожная карта; pre-IPO timing). Детали в M8.

Attestation system читает evidence index + указатели на S3 payload; Business Owner просматривает per-control квартальный пакет; e-подписывает заявление об эффективности. Вывод attestation — сам по себе evidence (запись sign-off), сохраняемый обратно в неизменяемое хранилище с retention параллельным первичному evidence.

Стадия 5 — Auditor view

Read-only роль провижится для внешнего аудитора (Big 4 senior associate + senior manager). Разрешения роли:

  • SELECT на audit.evidence_index
  • s3:GetObject на swr-evidence-prod-cde-evidence/*
  • kms:Decrypt для KMS-ключа encryption evidence
  • kms:Verify (public-key crypto verification) для KMS-ключа signing evidence

Никаких s3:PutObject, s3:DeleteObject, write в Snowflake. Аудит не может изменить evidence → независимость сохранена.

Audit trail — все запросы аудитора логируются через Snowflake QUERY_HISTORY + CloudTrail S3 access logs. SwiftRide может продемонстрировать audit committee «да, Big 4 обращались к evidence в эти timestamps; покрыли эти выборки».

Требования retention по регуляциям

SOX 404 + AS 1105 устанавливает базовую линию 7 лет для US SOX. Другие регуляции варьируются:

РегуляцияRetentionПримечания
SOX 404 / PCAOB AS 11057 лет от закрытия audit periodБазовая линия для контролей, обусловленных US SOX
GDPR Art. 30 records of processingПо политике retention организации (обычно 6 месяцев — 5 лет)Evidence, связанный с PII; согласно Art. 5(1)(e) storage limitation
AMLR / FATF R.115-7 лет после окончания отношенийEvidence KYC + transaction monitoring
EU AI Act Art. 1810 лет от окончания placing on marketДокументация high-risk AI-системы
PCI-DSS v4.0.1 Req. 10.5Минимум 1 год, немедленная доступность 3 месяцаAudit logs cardholder data
IRS / national tax3-7 лет в зависимости от юрисдикцииEvidence, связанный с налогами (1099, withholding)
BCBS 239 / ECBКонкретно не предписан; согласуется с supervisory frameworkБанки обычно 7+ лет
DORA Art. 11-12На протяжении ICT lifecycle + 5 летEvidence операционной устойчивости

Самое ограничивающее побеждает. Multi-regulator CDE — стандартизируем по самому высокому. CDE-SWR-003 (driver_earnings — SOX + GDPR + IRS 1099 + EU labor + PCI-DSS, если card-linked) — 7 лет SOX доминирует ежедневно; 10 лет EU AI Act применяется, если ценообразование задействует high-risk AI-модель.

Практический паттерн для SwiftRide: дефолт 7 лет; дольше для конкретных CDE согласно retention metadata в реестре (M4.5). Стоимость хранения — Glacier Deep Archive на год 1; ~1.013/TB/месяцvsS3Standard1.013/TB/месяц vs S3 Standard 23/TB/месяц. Годовая стоимость для ~10TB evidence: $1.2K/год. Пренебрежимо vs избегаемые audit costs.

Проверка знанийKnowledge check
SwiftRide считает: «хранение evidence слишком дорого — давайте retention только 18 месяцев; SOX требует 7 лет, но это операционно тяжело; если аудитору нужен старый evidence — будем генерировать on-demand». Какие проблемы?
ОтветAnswer
Несколько критических изъянов: (1) Операционно невозможно — generate on-demand требует реконструкции состояния Snowflake из снапшотов / бэкапов; Time Travel максимум 90 дней; Fail-safe ещё 7 дней; за пределами ~97 дней нельзя восстановить в Snowflake нативно; потребуются Iceberg snapshots в S3 или внешний архив — то есть всё равно нужно поддерживать прошлые данные, так что 'on-demand' просто смещает стоимость к худшей архитектуре. (2) Несоответствие PCAOB AS 1105 ¶.10 — аудитору нужен evidence, доступный во время audit period (обычно Q4 для аудита fiscal year-end Q1 следующего); 18-месячный retention покрывает только последние ~6 кварталов; выборка по полному fiscal year невозможна. (3) PCAOB inspection finding — 'неспособность менеджмента предоставить evidence' = control deficiency (AS 1305 ¶.01); для material CDE = кандидат на material weakness (¶.03). (4) Контекст pre-IPO SwiftRide — раскрытие material weakness задерживает листинг NYSE на 3-6 месяцев × $50M месячного burn = $150-300M tail risk. (5) Анализ стоимости ошибочен — 7-летний retention с lifecycle к Glacier Deep Archive: ~$1.013/TB/месяц × 10TB = $122/год начиная со 2-го года; первый год S3 Standard ~$2.3K. Общая стоимость за 7 лет ~$3.5K — пренебрежимо vs риск material weakness. (6) Паттерн generate-on-demand не приемлем для аудитора: PCAOB AS 1105 'sufficient appropriate audit evidence' подразумевает сохранённый evidence, не реконструированный evidence; цепочка chain-of-custody нарушена. (7) Правильное решение: 7 лет Object Lock Compliance Mode с lifecycle transition к Glacier; бюджет $5K-10K годовое хранение; партиционирование по control_id × date для эффективного доступа; индекс в Snowflake audit.evidence_index запрашиваемый. Операционно просто, защищаемо перед аудитором, соответствует регуляциям.

Evidence pipeline SwiftRide — конкретная архитектура

┌──────────────────────────────────────────────────────────────────────┐
│  Engine layer                                                        │
│  ├─ GE 1.17.1 Checkpoints (часовые на CDE-колонках)                  │
│  ├─ Soda Core 4.0 contract scans (ежедневные contract checks)        │
│  ├─ dbt 1.9 tests (на каждый build + архив manifest)                 │
│  └─ Custom Python parity check (per CDE-SWR-003 CTL-004)             │
│                          │                                            │
│                          ▼ (validation results JSON)                  │
│  Emitter layer (AWS Account: swr-evidence-prod)                      │
│  ├─ Lambda swr-evidence-emitter (Python 3.13)                        │
│  │   ├─ Нормализация в evidence-schema-v1                            │
│  │   ├─ Захват input_state (снапшот Snowflake + sha256 hash)          │
│  │   ├─ HMAC-SHA256 sign через KMS-ключ                               │
│  │   └─ Emit в 3 sinks параллельно                                    │
│  │       ├─→ S3 Object Lock (первичный evidence)                      │
│  │       ├─→ OpenLineage Kafka topic openlineage.runs                 │
│  │       └─→ Snowflake audit.evidence_index INSERT                    │
│                          │                                            │
│                          ▼                                            │
│  Неизменяемое хранилище                                              │
│  ├─ S3 bucket swr-evidence-prod-cde-evidence                         │
│  │   ├─ Object Lock Compliance Mode дефолт 7 лет                     │
│  │   ├─ SSE-KMS encryption                                            │
│  │   ├─ Cross-region replication в eu-central-1                       │
│  │   └─ Lifecycle к Glacier Deep Archive на год 1                     │
│                          │                                            │
│                          ▼                                            │
│  Attestation layer                                                   │
│  ├─ Workiva connectors пуллят квартально                             │
│  ├─ Business Owner просматривает + e-подписывает                     │
│  ├─ Запись attestation архивируется обратно в S3 Object Lock         │
│                          │                                            │
│                          ▼                                            │
│  Auditor view                                                        │
│  ├─ Snowflake AUDIT_AUDITOR_ROLE — SELECT на audit.evidence_index    │
│  ├─ IAM read-only S3 access на evidence-бакет                        │
│  ├─ KMS Verify permission для проверки подписи                       │
│  └─ Audit-trail через QUERY_HISTORY + CloudTrail S3 access logs      │
└──────────────────────────────────────────────────────────────────────┘

Операционные метрики Q3 2026:

  • Эмиссия evidence: ~5.2M / квартал (GE часовые × 30 контролей × 92 дня + Soda ежедневные × 60 контролей × 92 дня + dbt build × ~200 PR + parity check × 92 дня)
  • Рост хранилища: ~2.8 TB / квартал (в основном Data Docs HTML + GE validation_results.json)
  • Средняя задержка S3 PUT: 180ms p99
  • Лаг cross-region replication: < 30 секунд p99
  • Верификация целостности evidence (ежедневная пересборка HMAC выборки): 100% совпадение в Q3
  • Задержка audit-запроса (audit.evidence_index point query): < 100ms p99

Антипаттерны — детально

Изменяемая Snowflake-таблица = первичный evidence

Паттерн: INSERT INTO audit.control_runs (run_id, timestamp, control_id, result) после каждого прогона.

Почему плохо: Snowflake DML изменяем; DBA с MODIFY permission может UPDATE/DELETE ретроспективно; Time Travel максимум 90+7 дней; не WORM. PCAOB AS 1105 ¶.07-.08 — внутренний источник со слабыми контролями = tier 4 reliability; аудитор хочет минимум tier 3+.

Исправление: Snowflake-таблица — вторичный индекс, указывающий на первичный evidence в S3 Object Lock. Audit.evidence_index — изменяема для INSERT, но никогда UPDATE/DELETE на исторических строках; паттерны доступа принуждаются через stored procedures + RBAC.

Нет хеша входа

Паттерн: payload evidence захватывает timestamp + result; не захватывает sha256 входного rowset.

Почему плохо: аудитор не может независимо пересчитать — даже если снапшот Snowflake доступен, нет уверенности, что снапшот совпадает с тем, на чём работал контроль. Снапшот Time Travel в timestamp X — но контроль мог запуститься в X + 30 секунд на немного более новом состоянии.

Исправление: захватить явный input_hash = sha256 нормализованной проекции входа (отсортированной по primary key + релевантным колонкам, сериализованным в JSON). Тест пересчёта: «захешируйте эту проекцию снапшота Snowflake и подтвердите совпадение с input_hash из evidence».

Нет timestamp от доверенного источника

Паттерн: emitter использует Python datetime.now() без обеспечения NTP-синхронизации.

Почему плохо: контейнеризированные нагрузки часто без NTP-синхронизации; возможен дрейф часов; даже на AWS, system clock без proper sync к AWS time source.

Исправление: AWS Lambda — часы автоматически синхронизированы с AWS time source; используйте встроенный time.time(). Для ECS/EKS — проверить, что NTP daemon работает; алерт при дрейфе > 100ms. Альтернатива — использовать server-side timestamp от S3 PUT (заголовок x-amz-date) как авторитетный; не всегда практично, потому что timestamp emitter захватывается до PUT в S3.

Единая точка отказа хранилища

Паттерн: S3-бакет в одном регионе; основной AWS-аккаунт.

Почему плохо: отключение региона AWS (us-east-1 outage Dec 2021, инциденты в eu-central-1) — evidence недоступен во время отключения; если аккаунт скомпрометирован (insider, украденные credentials), evidence в опасности.

Исправление: cross-region replication (CRR) во вторичный регион; отдельный AWS-аккаунт для evidence-бакета (defence-in-depth). Накладные расходы < 2x; устойчивость значительна.

Retention настроен, но не протестирован

Паттерн: политика бакета говорит 7 лет; никто не верифицирует, что retention применён per-object.

Почему плохо: bucket-default retention применяется только к новым объектам после применения политики; существующие объекты могут иметь более короткий retention или его отсутствие.

Исправление: ежемесячная автоматическая проверка — выборка N=100 случайных объектов по бакету; запрос head-object для Object Lock retention metadata; алерт на объекты с retention < 7 лет. Эксплицитная верификация Q1 каждого года.

Резюме

  • Evidence pipeline = 5 стадий: engine → emitter → неизменяемое хранилище → attestation → auditor view. Emitter — единая точка целостности; неизменяемое хранилище — separation of concerns.
  • Выбор DQ engine (GE 1.17.1 / Soda 4.0 / Anomalo / dbt tests) — локальный; storage + auditor стадии tool-agnostic.
  • S3 Object Lock Compliance Mode = дефолт SwiftRide; Governance Mode приемлем при жёстком IAM; отдельный AWS-аккаунт = defence-in-depth.
  • Retention выравнен с регулятором; SOX 7 лет базовая линия; EU AI Act 10 лет для high-risk AI; самое ограничивающее побеждает для multi-regulator CDE.
  • Антипаттерны: Snowflake-таблица = первичная (изменяема, максимум 90 дней Time Travel); нет хеша входа (нет пересчёта); нет timestamp от NTP-trusted источника; один регион; retention не протестирован.
  • Pipeline SwiftRide — emitter Lambda в отдельном AWS-аккаунте; cross-region replication S3; Snowflake audit.evidence_index вторичный индекс; слой attestation Workiva; роль read-only access Big 4.

В M7.3 разберём OpenLineage и Marquez как слой evidence trail — lineage + run events + dataset events; интеграция с dbt / Spark / Airflow; что аудитор хочет от evidence lineage.

Observability — мониторинг health evidence pipeline Форматы хранения — immutability и retention

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. SwiftRide Risk Function asks CDO: 'S3 Object Lock Compliance Mode vs Governance Mode — какой для CDE evidence?'. Какая правильная рекомендация + rationale?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7