Skip to main content
Назад к блогу
4 мин чтения

GDPR для небольшого SaaS: 5-часовой сетап, которого достаточно

Не нужен юридический аудит за €10K, чтобы быть GDPR-комплаентным. Минимально жизнеспособный сетап, который я реализую для каждого EU-ориентированного SaaS: что делать, что пропустить, что реально важно.

security

Большинство фаундеров небольших SaaS в ЕС знают, что им нужен GDPR. Большинство также думают, что это требует юридического аудита за €10K, платформы управления согласиями и штатного DPO. Нет — не на маленьком масштабе.

Я настраивал GDPR-комплаенс для 6 клиентских проектов. Вот минимально жизнеспособный сетап, который занимает около 5 часов и покрывает то, что реально имеет значение.

Что GDPR реально требует (короткая версия)

  1. Законное основание для обработки: Нужна юридическая причина для сбора данных. Для SaaS: согласие (для маркетинга) или исполнение контракта (для самого сервиса).
  2. Прозрачность: Расскажите пользователям, что вы собираете, зачем и как долго храните.
  3. Минимизация данных: Не собирайте больше, чем нужно.
  4. Право на доступ/удаление: Пользователи могут запросить свои данные или их удаление.
  5. Безопасность: Защищайте хранимые данные.
  6. Уведомление об утечке: Сообщите регулятору в течение 72 часов.

Всё. Остальное (DPO, DPIA, записи об обработке) имеет пороги, которые маленький SaaS редко достигает.

5-часовой сетап

Час 1: Политика конфиденциальности (настоящая)

Не юридический шаблон, скопированный у корпорации из Fortune 500. Документ на понятном языке, покрывающий:

Пишите на понятном языке. Не юридическим жаргоном. Пользователь должен понять, что происходит с его данными, за 2 минуты чтения.

Час 2: Согласие на куки (минимальное)

Если вы используете только необходимые куки (сессия, аутентификация), баннер кук вообще не нужен по GDPR. Необходимые куки имеют исключение.

Если используете аналитику:

Моя рекомендация: используйте Plausible или PostHog в режиме без кук и пропустите баннер кук полностью. Баннер стоит вам 5–15% точности аналитики (пользователи, которые отклоняют) и добавляет UX-трение.

Час 3: Флоу удаления данных

Когда пользователь удаляет аккаунт, вы должны реально удалить его данные. Не soft-delete — hard delete из базы данных.

async function deleteUserData(userId: string) {
  // 1. Отменить активные подписки
  await stripe.subscriptions.cancel(user.stripeSubscriptionId)

  // 2. Удалить из базы данных
  await db.transaction(async (tx) => {
    await tx.delete(sessions).where(eq(sessions.userId, userId))
    await tx.delete(preferences).where(eq(preferences.userId, userId))
    await tx.delete(activities).where(eq(activities.userId, userId))
    await tx.delete(users).where(eq(users.id, userId))
  })

  // 3. Удалить из сторонних сервисов
  await posthog.deleteUser(userId)
  await sentry.deleteUser(userId)

  // 4. Залогировать удаление (без PII)
  logger.info('User data deleted', { userId, timestamp: new Date() })
}

Лог удаления (шаг 4) — ваше доказательство, что вы исполнили запрос. Храните 3 года.

Час 4: Эндпоинт экспорта данных

GDPR даёт пользователям право получить свои данные в машиночитаемом формате. Один эндпоинт:

// app/api/user/export/route.ts
export async function GET(request: Request) {
  const user = await getAuthenticatedUser(request)

  const data = {
    profile: await db.query.users.findFirst({ where: eq(users.id, user.id) }),
    preferences: await db.query.preferences.findMany({
      where: eq(preferences.userId, user.id),
    }),
    activities: await db.query.activities.findMany({
      where: eq(activities.userId, user.id),
    }),
  }

  delete data.profile.passwordHash
  delete data.profile.stripeCustomerId

  return new Response(JSON.stringify(data, null, 2), {
    headers: {
      'Content-Type': 'application/json',
      'Content-Disposition': `attachment; filename="user-data-${user.id}.json"`,
    },
  })
}

JSON — валидный машиночитаемый формат. CSV или XML не нужны.

Час 5: Аудит третьих сторон

Перечислите каждый сервис, который касается данных пользователей. Для каждого:

СервисКакие данные получаетDPA подписан?Хостинг в ЕС?
StripeEmail, имя, платёжДа (стандартный)Резидентность данных ЕС
VercelIP-адреса (логи)Да (DPA в ToS)Регион ЕС выбирается
SentryIP, контекст ошибокДа (DPA доступен)Регион данных ЕС
PlausibleНичего (без кук)Н/ПХостинг ЕС

DPA = Data Processing Agreement (Соглашение об обработке данных). У большинства SaaS-провайдеров оно есть. Нужно подписать — обычно просто галочка в их дашборде.

Что можно пропустить (на маленьком масштабе)

Стоимость бездействия

Штраф GDPR для маленькой компании начинается с €10K–€50K. Реалистичнее — первым наказанием будет предупреждение от надзорного органа. Но реальная стоимость — потерять B2B-сделку, потому что команда закупок покупателя увидела отсутствие политики конфиденциальности и DPA.

5 часов сетапа. Ноль текущих затрат при аналитике без кук. И страница конфиденциальности, которая реально понятна живым людям.


Нужен GDPR-комплаенс для вашего SaaS? Напишите — я включаю это в каждый EU-ориентированный проект.