Django-согласия и cookies под 152-ФЗ: версии документов, аудит и экспорт вместо одного чекбокса

Django-согласия и cookies под 152-ФЗ: версии документов, аудит и экспорт вместо одного чекбокса

Согласие на обработку персональных данных в Django-проекте часто начинается с одного BooleanField . Но затем оказывается, что недостаточно помнить только факт нажатия на чекбокс: пользователь мог видеть другую редакцию документа, отозвать согласие, выбрать лишь часть категорий файлов cookie, а администратору может понадобиться журнал действий и выгрузка в CSV.

Я сделал для этого два полностью независимых Django-пакета с открытым исходным кодом: django-consent-152fz для юридически значимых согласий и django-cookies-152fz для политики файлов cookie, категорий, подключённых сервисов и окна выбора. В статье покажу реальную модель данных, минимальное подключение и то, как устроены редакции, журнал событий и выгрузка данных.

Ссылки на проекты:

Сразу обозначу границу ответственности. Это технические пакеты, а не юридическая гарантия соответствия 152-ФЗ. Они не заменяют юриста, не определяют за оператора состав персональных данных и не создают автоматически корректные документы.

Их задача — дать воспроизводимый серверный контур для документов, редакций, статусов, истории действий, пользовательского выбора файлов cookie и выгрузки данных.

Почему два пакета

Сначала согласия и файлы cookie выглядели как одна задача: пользователь что-то подтверждает, а сайт должен сохранить его выбор и историю.

Но в реальном проекте это два разных направления.

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

Модуль файлов cookie связан с техническими категориями и подключёнными сервисами сайта: обязательными файлами cookie, аналитикой, маркетинговыми счётчиками, внешними виджетами и повторным запросом выбора после изменения политики.

Поэтому пакеты независимы:

При необходимости можно установить оба:

Но это не обязательная связка.

django-cookies-152fz не требует django-consent-152fz , не импортирует его модели и не использует его жизненный цикл согласий. Политики файлов cookie, категории, реестр подключённых сервисов, окно выбора, пользовательские решения, журнал событий и выгрузка данных работают внутри cookie-модуля как самостоятельный контур.

Модель согласий: цель, документ, редакция, запись, события

В коде используется не абстрактная цепочка вида Consent → ConsentVersion → UserConsent , а конкретные сущности:

ConsentPurpose — цель обработки. Например: «обработать заявку на обучение» или «ответить на обращение через форму контактов».

LegalDocument — юридический документ как постоянный контейнер.

DocumentRevision — конкретная опубликованная редакция текста. Именно к ней привязывается согласие.

ConsentRecord — запись о текущем или историческом состоянии согласия конкретного субъекта.

ConsentEvent — неизменяемый журнал переходов: выдача, отзыв, устаревание, подтверждение и другие события.

Новая редакция документа не перезаписывает старую. Если текст изменился, создаётся новый DocumentRevision . Старый ConsentRecord остаётся связанным с тем текстом, который пользователь видел в момент подтверждения.

Практически это даёт ответ на два вопроса: какой документ и какую редакцию подтвердил пользователь — и как это состояние менялось дальше.

Модуль файлов cookie — не только окно с кнопкой «Принять»

Окно выбора файлов cookie обычно воспринимают как небольшой элемент интерфейса с кнопками «Принять» и «Настроить».

Но само окно — только внешняя часть процесса. В модуле отдельно существуют политика, настройки отображения и пользовательский выбор.

CookieCategory — справочник категорий. Например:

обязательные;

обязательные;

функциональные;

функциональные;

аналитические;

аналитические;

маркетинговые.

маркетинговые.

Реестр содержит сведения о конкретных файлах cookie и подключённых сервисах: сторонних скриптах, системах аналитики или виджетах.

Для каждой записи можно хранить поставщика, назначение, категорию, срок хранения, адрес подключаемого скрипта, имена файлов cookie, стратегию очистки и признак активности.

CookiePolicyRevision фиксирует опубликованную редакцию политики вместе со снимком категорий и реестра подключённых сервисов на момент публикации.

Так можно не ограничиваться общей формулировкой «сайт использует файлы cookie», а поддерживать технический учёт подключённых сервисов.

Параллельно существует отдельный контур интерфейса:

CookieBannerRevision отвечает за текст, кнопки, вид окна выбора, настройки выбора категорий, отображение на мобильных устройствах и другие параметры интерфейса.

CookieConsentRecord хранит итоговый выбор категорий конкретного пользователя или анонимного посетителя.

CookieConsentEvent фиксирует принятие, обновление выбора, устаревание и другие действия.

Политика и окно выбора версионируются отдельно. Это позволяет изменить текст кнопки или внешний вид окна, не смешивая изменение интерфейса с изменением состава подключённых сервисов и политики.

Если опубликована новая CookiePolicyRevision , предыдущие записи выбора не должны автоматически считаться выбором пользователя для нового набора категорий или новых внешних сервисов.

Минимальная установка

Пакеты включаются добавлением приложений в INSTALLED_APPS .

Для модуля согласий:

Для модуля файлов cookie:

Настройки enable_core и enable_cookies сохранены для обратной совместимости. Для новой интеграции главный переключатель — наличие соответствующего приложения в INSTALLED_APPS .

Маршруты модуля согласий:

Маршруты модуля файлов cookie:

Затем применяются миграции:

Для демонстрационного проекта или быстрого ознакомления можно загрузить примеры:

В рабочем проекте вместо примеров создаются собственные цели обработки, юридические документы, редакции и реестр файлов cookie.

Как подключить сценарий получения согласия к форме

В демонстрационном приложении используется сценарий учебного центра: заявка на курс, обратная связь, регистрация и личный кабинет.

Для Django-формы можно использовать готовый ConsentCaptureModeMixin :

Для каждого бизнес-сценария стоит заранее зафиксировать стабильные коды:

Например:

Перед выполнением бизнес-действия проверяется статус согласия:

После успешной отправки формы и явного подтверждения пользователя создаётся запись согласия:

build_request_audit_context(...) здесь — вспомогательная функция проекта, которая собирает технические сведения HTTP-запроса для журнала действий.

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

Для внешних подключений предусмотрен публичный программный интерфейс:

Основные операции:

Окно выбора файлов cookie в шаблоне

Для модуля файлов cookie окно выбора подключается один раз в базовом шаблоне:

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

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

Программный интерфейс для клиентских приложений уже есть

Для модуля согласий предусмотрен дополнительный программный интерфейс для одностраничных приложений и мобильных клиентов.

Он подключается отдельным набором зависимостей:

Затем добавляется приложение:

Дополнительная библиотека для программного интерфейса не является обязательной зависимостью ядра. Если она не нужна, базовый пакет остаётся легче.

Отдельно существует дополнительный контур подтверждённых и бумажных согласий:

Он нужен для сценариев, где подтверждения на сайте недостаточно и требуется загрузка или проверка подписанного документа.

Журнал событий и выгрузка

Одна из целей пакетов — не просто сохранить состояние, а сделать его пригодным для сопровождения.

В модуле согласий:

ConsentRecord отвечает на вопрос: какое состояние согласия сейчас;

ConsentRecord отвечает на вопрос: какое состояние согласия сейчас;

ConsentEvent отвечает на вопрос: как система пришла к этому состоянию;

ConsentEvent отвечает на вопрос: как система пришла к этому состоянию;

ConsentModuleOperationAuditLog хранит действия в административной панели и программном слое;

ConsentModuleOperationAuditLog хранит действия в административной панели и программном слое;

выбранные записи согласий и записи журнала операций можно выгружать в CSV.

выбранные записи согласий и записи журнала операций можно выгружать в CSV.

В модуле файлов cookie:

CookieConsentRecord хранит итоговое состояние выбора категорий;

CookieConsentRecord хранит итоговое состояние выбора категорий;

CookieConsentEvent хранит события выбора, обновления и устаревания;

CookieConsentEvent хранит события выбора, обновления и устаревания;

выбранные события можно выгружать в CSV;

выбранные события можно выгружать в CSV;

разделитель CSV задаётся через административные настройки модуля.

разделитель CSV задаётся через административные настройки модуля.

Полезная практическая формула:

Стандартная административная панель Django используется намеренно. Для небольшого или среднего проекта отдельный интерфейс управления требованиями к обработке данных часто будет избыточным, а Django Admin уже даёт поиск, фильтры, разграничение доступа, действия над выбранными объектами и понятный интерфейс сопровождения.

Сценарий рассчитан прежде всего на просмотр и контроль истории. Исправление записей задним числом не должно быть штатной операцией.

Техническая совместимость

На момент публикации пакеты поддерживают:

Python 3.10–3.14;

Python 3.10–3.14;

Django 5.0–6.0;

Django 5.0–6.0;

лицензию MIT.

лицензию MIT.

У модуля согласий ядро зависит только от Django. Дополнительный программный интерфейс подключается через [api] , а ReportLab для формирования PDF-документов по сценариям подтверждённого или бумажного согласия — через [pdf] .

Модуль файлов cookie остаётся независимым: для его установки, работы окна выбора, политики, реестра, журнала событий и выгрузок не требуются модуль согласий, дополнительный программный интерфейс или связанные с ними модели.

Чего пакеты не делают

Они не определяют:

какие персональные данные вправе собирать конкретный оператор;

какие персональные данные вправе собирать конкретный оператор;

какие цели обработки допустимы;

какие цели обработки допустимы;

какой именно текст документа подходит для конкретного бизнеса;

какой именно текст документа подходит для конкретного бизнеса;

какие организационные меры должны быть внедрены внутри компании;

какие организационные меры должны быть внедрены внутри компании;

когда требуется отдельное согласие и как оно должно быть юридически сформулировано.

когда требуется отдельное согласие и как оно должно быть юридически сформулировано.

Пакеты дают технический слой, чтобы согласованный процесс не остался набором чекбоксов в шаблонах и неясных полей в базе данных.

Дальнейшее развитие: подтверждённые согласия через «Госключ»

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

Одно из направлений развития — отдельная интеграция с приложением «Госключ».

Идея не в том, чтобы заменить обычные согласия на сайте электронной подписью. В большинстве пользовательских сценариев это было бы избыточно. Скорее речь о дополнительном режиме для случаев, где требуется подтверждённое подписание документа.

Технически такой контур мог бы работать так:

В результате в записи согласия можно было бы хранить не только факт подтверждения в форме, но и сведения о подписанном документе, времени подписания, способе подтверждения и связанных результатах проверки.

Такую возможность разумно делать отдельным подключаемым приложением, а не частью базового модуля. Базовый django-consent-152fz должен оставаться пригодным для обычных сайтов без дополнительной инфраструктуры и сложного процесса подключения.

«Госключ» позволяет пользователям получать электронную подпись и подписывать электронные документы в приложении. Для организаций предусмотрен отдельный порядок подключения и программное взаимодействие, поэтому в рамках пакета это должно быть именно дополнительным, а не обязательным сценарием.

Что хотелось бы обсудить

Мне интересна обратная связь от Django-разработчиков, специалистов по защите информации, защите персональных данных и юристов, которые сталкивались с такими процессами в реальных проектах.

Особенно интересно узнать:

хватает ли текущего разделения на модуль согласий и модуль файлов cookie;

хватает ли текущего разделения на модуль согласий и модуль файлов cookie;

какие варианты выгрузки данных реально нужны чаще всего;

какие варианты выгрузки данных реально нужны чаще всего;

как удобнее встраивать сценарий получения согласия в многошаговые формы;

как удобнее встраивать сценарий получения согласия в многошаговые формы;

какие системы управления сайтами и внешние сервисы стоит поддержать в первую очередь;

какие системы управления сайтами и внешние сервисы стоит поддержать в первую очередь;

насколько востребован отдельный контур подтверждённых согласий с подписанием через «Госключ»;

насколько востребован отдельный контур подтверждённых согласий с подписанием через «Госключ»;

какие части документации нужны, чтобы внедрение в существующий Django-проект было проще.

какие части документации нужны, чтобы внедрение в существующий Django-проект было проще.

Исходный код, демонстрационные проекты, русская и английская документация доступны в репозитории проекта .

← Cybersecurity