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():
- phone → 7****123 (первая цифра + последние 3)
- email → r***@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.completedevent с PCI scope. - Cookies / Authorization headers — Sentry FastApiIntegration их фильтрует
- Полные phone в логах — middleware маскирует в timing_mw output (только rid + path).
- Geolocation — координаты пишутся только в
me.locationevent и хранятся ≤ 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 дней должны быть удалены