Документация · v2.4
Установка и настройка KadrSync
Руководство описывает регистрацию и выбор тарифа, подключение мобильного приложения по одноразовому токену, развёртывание выделенного узла хранения для клиентов тарифа «Бизнес» и протокол поблочной загрузки, который используют все приложения KadrSync.
Как устроен KadrSync
Сервис состоит из трёх компонентов:
- Облако KadrSync — управляемое хранилище, которое принимает зашифрованные блоки, проверяет их целостность и реплицирует в три зоны. Для тарифа «Бизнес» вместо облака может использоваться выделенный узел на инфраструктуре клиента.
- Приложения — для iOS, Android, Windows, macOS и Linux. Выполняют шифрование, разбиение на блоки и дельта-синхронизацию.
- Личный кабинет — app.kadrsync.space: управление подпиской, устройствами, участниками семейного или корпоративного тарифа. Доступа к содержимому файлов не имеет.
Серверы KadrSync никогда не получают ключи шифрования. Даже при полном доступе к хранилищу и базе данных виден только шифротекст, размеры блоков и служебные метки времени.
Аккаунт и тариф
-
1
Зарегистрируйтесь на app.kadrsync.space/signup или в мобильном приложении. Новый аккаунт сразу получает 5 ГБ на бесплатном тарифе «Базовый».
-
2
Придумайте парольную фразу шифрования. Она отличается от пароля входа и никогда не передаётся на сервер: из неё на устройстве формируется мастер-ключ.
-
3
Чтобы увеличить объём, откройте Личный кабинет → Подписка и выберите тариф. «Личный» и «Семейный» доступны с 14-дневным пробным периодом. Сравнить тарифы.
| Тариф | Хранилище | Устройства | История версий |
|---|---|---|---|
| Базовый | 5 ГБ | 2 | 7 дней |
| Личный | 200 ГБ | без ограничений | 30 дней |
| Семейный | 2 ТБ на 6 участников | без ограничений | 90 дней |
| Бизнес | 1 ТБ на пользователя | без ограничений | 1 год |
Связывание мобильного приложения по токену
Новое устройство подключается к аккаунту с помощью одноразового токена связывания. Токен действует 10 минут, используется только один раз и не даёт доступа к ключам шифрования — они передаются отдельно, напрямую между вашими устройствами.
-
1
На уже подключённом устройстве или в личном кабинете откройте Настройки → Устройства → Добавить устройство. Будет показан QR-код и токен вида
KSP-7QX4-M2RD-91HF. -
2
Установите приложение KadrSync на телефон, нажмите «Войти по токену» и отсканируйте QR-код либо введите токен вручную. Клиенты тарифа «Бизнес» с выделенным узлом дополнительно указывают его адрес.
-
3
Сверьте шестизначный код безопасности на обоих экранах. Совпадение кодов подтверждает, что обмен ключами X25519 прошёл без посредника.
-
4
Выберите альбомы для резервного копирования и условия загрузки (только Wi-Fi, только при зарядке). Первичная синхронизация начнётся в фоне.
Под капотом приложение обменивает токен связывания на сессионный маркер устройства:
POST /v1/devices/pair HTTP/1.1
Host: api.kadrsync.space
Content-Type: application/json
{
"pairing_token": "KSP-7QX4-M2RD-91HF",
"device_name": "Pixel 8",
"platform": "android",
"device_public_key": "x25519:Hk3v9Q1mZ0p6cR4bT8wY2uN7aJ5eL1sD0fG3hK6xV9o="
}
HTTP/1.1 201 Created
{
"device_id": "dev_01JA8M4Z7K2Q9W3E5R6T",
"session_token": "ks_sess_…",
"expires_in": 2592000,
"plan": "family",
"quota_bytes": 2199023255552,
"chunk_size": 4194304
}
Ключ восстановления
При создании аккаунта приложение генерирует ключ восстановления из 24 слов (BIP-39). Это единственный способ расшифровать данные, если вы забыли парольную фразу и потеряли все устройства.
Служба поддержки KadrSync может восстановить доступ к аккаунту и подписке, но не к содержимому файлов. Утрата ключа восстановления и всех связанных устройств означает безвозвратную потерю данных.
Развёртывание выделенного узла хранения
Клиенты тарифа «Бизнес» могут хранить зашифрованные блоки на собственной инфраструктуре: в своём дата-центре, на NAS или в частном облаке. Узел работает по лицензионному ключу, который выдаётся в личном кабинете в разделе Организация → Выделенный узел. Учёт пользователей, подписка и личный кабинет остаются в облаке KadrSync.
| Ресурс | Минимум | Рекомендуется |
|---|---|---|
| Процессор | 2 ядра x86_64 / ARM64 | 4 ядра |
| Оперативная память | 2 ГиБ | 8 ГиБ |
| Диск | Объём данных × 1,05 | SSD для БД, RAID для блоков |
| ПО | Docker 24+, Compose v2 | Docker 27+, домен и TLS-сертификат |
| Сеть | Исходящий HTTPS к api.kadrsync.space для проверки лицензии и учёта квот | |
-
1
Подготовьте каталог и загрузите манифест
Создайте рабочий каталог и получите файлы конфигурации. Ссылка на загрузку доступна в личном кабинете после активации тарифа.
bashsudo mkdir -p /opt/kadrsync && cd /opt/kadrsync curl -fsSL -H "Authorization: Bearer $KADRSYNC_LICENSE_KEY" \ https://dl.kadrsync.space/node/latest/bundle.tar.gz | tar xz -
2
Укажите лицензию и параметры узла
Отредактируйте файл
.env: задайте лицензионный ключ, публичный адрес узла и сгенерируйте секрет для подписи сессионных маркеров..env# Лицензионный ключ из личного кабинета (Организация → Выделенный узел) KADRSYNC_LICENSE_KEY= # Публичный адрес, по которому приложения обращаются к узлу KADRSYNC_PUBLIC_URL=https://storage.company.ru # Каталог для зашифрованных блоков KADRSYNC_BLOB_PATH=/srv/kadrsync/blobs # Секрет для подписи сессионных маркеров: openssl rand -hex 32 KADRSYNC_SESSION_SECRET= POSTGRES_PASSWORD= -
3
Запустите узел и привяжите его к организации
После запуска узел проверит лицензию и появится в личном кабинете со статусом «Активен». Новые устройства сотрудников будут автоматически направлены на него.
bashdocker compose up -d docker compose exec node kadrsync-node license status # organization: org_01JA7… plan: business seats: 25 status: active -
4
Настройте TLS и обратный прокси
Приложения отказываются подключаться к узлу без HTTPS. Пример конфигурации Caddy с автоматическим выпуском сертификата:
Caddyfilestorage.company.ru { request_body { max_size 8MB } reverse_proxy node:8080 }
REST API: аутентификация
Все запросы выполняются по HTTPS к https://api.kadrsync.space/v1 (или к адресу выделенного узла) и содержат сессионный маркер устройства в заголовке Authorization. Ответ на запрос /me содержит текущий тариф и использованный объём.
curl -s https://api.kadrsync.space/v1/me \
-H "Authorization: Bearer $KADRSYNC_SESSION_TOKEN"
{
"account_id": "acc_01JA7ZK3M0Q8R5T2V6W",
"plan": "family",
"subscription_status": "active",
"renews_at": "2026-11-15T00:00:00Z",
"quota_bytes": 2199023255552,
"used_bytes": 230535987200
}
REST API: поблочная загрузка
Загрузка файла выполняется в три этапа: создание сессии загрузки с манифестом блоков, передача отсутствующих блоков и фиксация объекта. Сервер проверяет хеш BLAKE3 каждого блока после приёма; блок с несовпадающим хешем отклоняется и должен быть отправлен повторно. Квота тарифа проверяется при создании сессии.
POST /uploads
Манифест блоков, ответ — список недостающих индексов.
PUT /uploads/{id}/chunks/{n}
Передача зашифрованного блока с проверкой хеша.
POST /uploads/{id}/commit
Атомарная фиксация версии объекта.
Шаг 1. Создание сессии загрузки
Приложение заранее разбивает зашифрованный файл на блоки по chunk_size байт и вычисляет хеш каждого блока. В ответе сервер сообщает, какие блоки уже есть в хранилище (дедупликация) и какие нужно передать.
POST /v1/uploads HTTP/1.1
Host: api.kadrsync.space
Authorization: Bearer ks_sess_…
Content-Type: application/json
{
"library_id": "lib_camera_roll",
"encrypted_name": "b64:Q2l4Rk9nV0R0c3VtV1N…",
"wrapped_file_key": "b64:4h7JpX0v2Lk9bN1q…",
"size": 19084391,
"chunk_size": 4194304,
"chunks": [
{ "index": 0, "size": 4194320, "hash": "blake3:9c1e5a…44ab" },
{ "index": 1, "size": 4194320, "hash": "blake3:02fd71…b7e0" },
{ "index": 2, "size": 4194320, "hash": "blake3:7a33c0…1d58" },
{ "index": 3, "size": 4194320, "hash": "blake3:e81a2f…0c93" },
{ "index": 4, "size": 2307191, "hash": "blake3:51b4d8…f6d2" }
]
}
HTTP/1.1 201 Created
{
"upload_id": "upl_01JA8Q3VXN0F4C7B2M",
"missing_chunks": [0, 1, 3, 4],
"quota_remaining_bytes": 1968487268352,
"expires_at": "2026-10-16T18:42:31Z"
}
Размер каждого блока на 16 байт больше исходного — это тег аутентификации Poly1305. Последний блок может быть короче chunk_size. Блоки, найденные при дедупликации, в квоте повторно не учитываются.
Шаг 2. Передача блоков
Каждый недостающий блок передаётся отдельным запросом. Заголовок X-Chunk-Hash обязателен: сервер вычисляет хеш принятых байтов и сравнивает его со значением из заголовка и манифеста.
curl -X PUT "https://api.kadrsync.space/v1/uploads/upl_01JA8Q3VXN0F4C7B2M/chunks/0" \
-H "Authorization: Bearer $KADRSYNC_SESSION_TOKEN" \
-H "Content-Type: application/octet-stream" \
-H "X-Chunk-Hash: blake3:9c1e5a…44ab" \
--data-binary @chunk_0000.enc
HTTP/1.1 200 OK
{
"index": 0,
"status": "verified",
"received_bytes": 4194320,
"remaining_chunks": [1, 3, 4]
}
Пример реализации на TypeScript, которую используют десктопные приложения:
const CHUNK_SIZE = 4 * 1024 * 1024;
export async function uploadFile(api: KadrSyncApi, file: EncryptedFile) {
// 1. Разбиваем шифротекст на блоки и считаем BLAKE3 для каждого
const chunks = await splitIntoChunks(file.ciphertext, CHUNK_SIZE);
const manifest = chunks.map((c, index) => ({ index, size: c.byteLength, hash: blake3Hex(c) }));
// 2. Сервер возвращает только те блоки, которых у него нет
const { upload_id, missing_chunks } = await api.post('/uploads', { ...file.meta, chunk_size: CHUNK_SIZE, chunks: manifest });
// 3. Передаём недостающие блоки с повторами при ошибке валидации
for (const index of missing_chunks) {
await retry(() => api.put(`/uploads/${upload_id}/chunks/${index}`, chunks[index], {
'X-Chunk-Hash': manifest[index].hash,
}), { attempts: 5, retryOn: [409, 422, 503] });
}
// 4. Фиксируем версию объекта
return api.post(`/uploads/${upload_id}/commit`, { root_hash: merkleRoot(manifest) });
}
Шаг 3. Фиксация объекта
После приёма всех блоков приложение передаёт корень дерева Меркла по хешам блоков. Сервер пересчитывает его и, при совпадении, атомарно публикует новую версию объекта для остальных устройств.
POST /v1/uploads/upl_01JA8Q3VXN0F4C7B2M/commit HTTP/1.1
Host: api.kadrsync.space
Authorization: Bearer ks_sess_…
Content-Type: application/json
{ "root_hash": "blake3:f0a9c2…8e17" }
HTTP/1.1 200 OK
{
"object_id": "obj_01JA8QB6TQ1H3Z5K9P",
"version": 3,
"cursor": "gal_7f2208"
}
Коды ошибок
| Код | Идентификатор | Описание и действие приложения |
|---|---|---|
| 401 | session_expired | Сессионный маркер истёк или отозван. Требуется повторное связывание устройства. |
| 402 | subscription_inactive | Подписка не оплачена или истекла. Загрузка приостановлена, чтение доступно. Пользователь направляется в раздел «Подписка». |
| 409 | chunk_already_received | Блок уже принят ранее. Перейдите к следующему блоку. |
| 413 | chunk_too_large | Размер блока превышает chunk_size + 16 байт. |
| 422 | chunk_hash_mismatch | Хеш принятых данных не совпал с манифестом. Блок отброшен, повторите передачу. |
| 422 | root_hash_mismatch | Корень дерева Меркла не совпал при фиксации. Создайте новую сессию загрузки. |
| 507 | quota_exceeded | Исчерпан объём хранилища по тарифу. Приложение предлагает перейти на тариф с большим объёмом. |
Не нашли ответ?
Напишите в поддержку: support@kadrsync.space. Подписчики «Семейного» и «Бизнес» тарифов получают ответ в приоритетном порядке.