Перейти к содержанию

Privacy & PII в телеметрии

Phase 13 из OBSERVABILITY_ROADMAP.md. Что мы НЕ отправляем и как маскируем то, что отправляем.

Принцип

Любая телеметрия (Sentry events, user_events, notification logs, Loki logs) должна быть безопасна для глаз разработчика, не давать прямой персональной идентификации, и проходить требования 152-ФЗ.

Что маскируется автоматически

arkhyz_shared.events.emit_event() (Phase 1)

Маскирование в _mask_dict(): - phone7****123 (первая цифра + последние 3) - emailr***@example.com (первая буква + домен) - password, token, secret, card_number, pan, cvv, code, verification_token, access_token, refresh_token, api_key, private_key*** - Любой ключ содержащий password/token/secret***

arkhyz_shared.sentry_tags.tag_sms() (Phase 1)

phone параметр маскируется до отправки в Sentry tag/context.

Sentry SDK init

sentry_sdk.init(
    ...,
    send_default_pii=False,  # не отправляем IP, cookie, user
)

Что мы НЕ собираем

  • Полные номера карт — никогда. Card.last4 — только в payment.completed event с PCI scope.
  • Cookies / Authorization headers — Sentry FastApiIntegration их фильтрует
  • Полные phone в логах — middleware маскирует в timing_mw output (только rid + path).
  • Geolocation — координаты пишутся только в me.location event и хранятся ≤ 30 дней с целью SOS.
  • Full names / passport — никогда в event'ах. Хранятся только в public.users за RLS.

Retention

Источник Срок Где
public.user_events 90 дней планируется cron DELETE
public.notifications по умолчанию TTL не задан TODO: cron DELETE > 1 год
Prometheus metrics 30 дней (default) volume prometheus_data
Loki logs 7 дней volume loki_data
error-collector events 30 дней (ERROR_COLLECTOR_RETENTION_DAYS) volume error_collector_data (SQLite)
sentry_sdk meta (tags/extra) сохраняется в errors.meta JSON-полем
Redis counters TTL 30 дней volume arkhyz-redis

IP и User-Agent

  • IP: пишется в public.user_events.ip (тип inet). По 152-ФЗ — это PII.
  • План: zero last octet через 30 дней. Пока не реализовано.
  • User-Agent: пишется как есть (не PII по российскому закону).

Право на удаление (GDPR / 152-ФЗ)

-- Удалить все события и нотификации конкретного user_id
DELETE FROM public.user_events WHERE actor_id = '<uuid>';
DELETE FROM public.notifications WHERE user_id = '<uuid>';
-- Очистить Redis counters (опционально — там нет PII по user-level)

В будущем — endpoint /admin/users/{id}/forget.

Право на экспорт

В будущем — endpoint /admin/users/{id}/data-export отдаёт всё что мы храним по этому user_id в JSON.

Что НЕ должен делать разработчик

  • logger.info(f"user {phone} logged in") — phone не должен попасть в Loki. → logger.info(f"user logged in") + tag_sms(phone=...) (масочный).
  • sentry_sdk.set_user({"email": ..., "phone": ...}) — отключено через send_default_pii=False.
  • ❌ Включать before/after с полными username/email в emit_event.
  • ❌ Класть JWT в Sentry tag.

Чек-лист аудита (раз в квартал)

  • [ ] Grep r"\+7\d{10}" в Loki за последние 7 дней — должно быть 0 (или только masked)
  • [ ] Grep @[a-z]+\.[a-z]+ в user_events.before/after JSON — только masked
  • [ ] Проверить Sentry-event'ы на наличие card.number / Authorization
  • [ ] Проверить что send_default_pii=False всё ещё в Sentry init
  • [ ] Reset retention: события старше 90 дней должны быть удалены