Wrapped - сервис одноразовой передачи секретов: паролей, кода, скриншотов и файлов. Данные шифруются в браузере отправителя, на сервере хранится только ciphertext, после первого успешного открытия пакет уничтожается. Администратор не может прочитать содержимое - у него нет ключа.
Зачем это нужно
Обычная переписка и облачные заметки плохо подходят для чувствительных данных. Сообщение остаётся в истории, файл лежит в чате месяцами, а «временная» ссылка нередко переживает саму необходимость. Wrapped устроен иначе: вы создаёте wrap, отправляете ссылку или токен получателю, тот один раз расшифровывает содержимое - и на сервере уже нечего красть повторно.
Удобно передать пароль от временного доступа, конфиг, API-ключ, скриншот с персональными данными или небольшой архив. Не нужно плодить аккаунты и не нужно верить хостингу «на слово»: модель zero-knowledge заложена в протокол, а не в политику приватности.
Как устроено шифрование
На клиенте - Web Crypto и AES-GCM. Ключ генерируется в браузере и передаётся получателю во фрагменте URL - части после #, которая не уходит на сервер в HTTP-запросе. Ссылка выглядит как /w/#; есть и компактный токен wrapped_v1... Сервер знает идентификатор и ciphertext, но не знает ключ. Даже полный доступ к базе и объектному хранилищу не даёт прочитать чужие данные.
Опционально wrap защищается паролем. Перед выдачей ciphertext сервер проверяет Argon2-хеш. Опечатка не сжигает пакет сразу: пустой ввод не тратит попытку, при неверном пароле UI показывает, сколько попыток осталось. Лимит настраивается в админке (по умолчанию три). Когда попытки исчерпаны, wrap уничтожается - защита от перебора, а не «вечный сейф».
Одноразовая жизнь пакета
После успешной расшифровки объект удаляется из хранилища, статус - consumed. Превью остаётся только в сессии браузера получателя. Можно задать TTL: если никто не открыл wrap вовремя, он истекает сам. Так снижается риск «забытых» ссылок.
Что можно положить внутрь
Текст с подсветкой синтаксиса и ручным выбором языка - удобно для кода и конфигов. Файлы и изображения: drag-and-drop, выбор с диска, вставка скриншота из буфера. Интерфейс на русском и английском, светлая и тёмная тема.
Для защиты от ботов - Cloudflare Turnstile и hCaptcha. Публичные лимиты и настройки отдаются клиенту через API; серверного «зашифруй за меня» нет - сервер принципиально не должен видеть plaintext.
Админка для оператора
Есть статистика: объём нерасшифрованного ciphertext в MinIO, pending и уже расшифрованные wraps, загрузки, статусы, события аудита. В настройках - лимиты размера и TTL, rate limits, MIME allowlist, режим пароля и число попыток, CAPTCHA. Журнал аудита с фильтрами, пагинацией и очисткой. «Опасная зона» - полная purge wraps и объектов, если нужно экстренно обнулить стенд.
Развёртывание
Стек: FastAPI, PostgreSQL, MinIO. Для разработки - Docker Compose. Для продакшена образ на Docker Hub: inecs/wrapped; достаточно compose и своего .env. Есть Helm-чарт для Kubernetes. При старте контейнер сам применяет миграции Alembic.
Для интеграций открыт тот же ZK-протокол, что в UI: получить настройки, загрузить ciphertext, одноразово забрать его через unwrap. Ошибки пароля структурированы: password_required, bad_password с оставшимися попытками, password_locked.
Кому это подходит
Командам, которым нужна своя «одноразовая капсула» без зависимости от чужих pastebin-сервисов. Инженерам, которые передают секреты в чатах и хотят минимизировать след. Админам, которым важны лимиты, аудит и self-hosted контроль. Wrapped не заменяет менеджер паролей и не хранит историю - он закрывает узкий, но частый сценарий: передать сейчас и не оставить копию «на всякий случай».
Итог
Wrapped - минималистичный self-hosted drop для зашифрованных данных с честной моделью: ключ у людей, ciphertext на сервере, жизнь пакета - один успешный unwrap. Простота для отправителя и получателя, прозрачность для оператора и отсутствие иллюзии, что хостинг «ничего не видит» без технического доказательства.
Демо-сайт тут https://wrapped.antropoff.ru