storage-p

API-документация

Тот же REST API, на котором работает веб-клиент. Каждая запись шифруется прямо в браузере, ещё до отправки — сервер видит только шифротекст и прочитать его не может. На нём можно собрать свой клиент или выдать интеграции ограниченный, подтверждаемый доступ к нескольким записям. Base URL: https://storage-p.com

OpenAPI-спека (машиночитаемая, для интеграций) /openapi.yaml

Гайды

Сквозные разборы того, что storage-p реально умеет — строго по фактическому набору функций, без выдумок.

Self-host на своём сервере

Запусти storage-p как Docker-контейнер за Caddy на своём домене. Caddy отдаёт статический клиент и проксирует /api в бэкенд; база SQLite зашифрована at-rest через SQLCipher. Ты управляешь всем сам — ключи не держит никто, кроме тебя.

Хранение и генерация SSH/TLS-ключей

Генерируй Ed25519 SSH-ключи (формат OpenSSH) и self-signed TLS-сертификаты во вкладке «Генераторы» или загружай готовые файлы ключей/сертификатов (до 1 МБ). Приватный материал шифруется в браузере до отправки, поэтому он никогда не лежит на сервере в открытом виде.

Одноразовые ссылки burn-after-read

Поделись одной записью или целой папкой по ссылке, ключ расшифровки которой живёт только во фрагменте URL (#…) — части, которую браузер не отправляет на сервер. Задай TTL и лимит просмотров; после последнего просмотра данные больше не открыть.

Ограниченные API-токены с подтверждением

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

Проекты и доступ для команды

Преврати папку в проект с собственным ключом. Дай другому пользователю доступ на чтение или запись — ключ проекта запечатывается под его публичный ключ (X25519), и он работает с актуальными записями, а сервер не видит читаемой копии. Любой доступ можно отозвать.

Встроенный TOTP / 2FA

Храни TOTP-секрет логина рядом с ним и читай живой одноразовый код в том же месте — storage-p заменяет аутентификатор. Свой аккаунт тоже можно защитить TOTP-двухфакторкой.

Импорт из другого менеджера

Перенеси Bitwarden JSON, KeePass CSV или любой CSV со столбцами name/username/password/url/notes. Разбор и шифрование идут на твоём устройстве, поэтому записи перешифровываются под твой ключ и не загружаются в открытом виде.

API-документация · API

Аутентификация

Получи access-токен через register/login, затем шли его как Bearer. Access-токены короткоживущие (15 мин); обновляй refresh-токеном.

Authorization: Bearer <access_token>

Auth

Регистрация, вход и поддержание сессии. Мастер-пароль не покидает браузер — на сервер уходит только Argon2id auth-hash.

POST /api/v1/auth/register
Создать аккаунт. Клиент сам выбирает параметры KDF и загружает уже зашифрованный приватный ключ.
Тело{ email, master_password, kdf_salt_b64, kdf_memory_kib, kdf_iters, kdf_parallelism, pubkey_b64, privkey_enc_b64 }
Ответ{ access_token, refresh_token, user_id, kdf_* }
POST /api/v1/auth/login
Войти. Возвращает токены и KDF-соль, нужную клиенту для деривации vault-ключа.
Тело{ email, master_password, totp_code? }
Ответ{ access_token, refresh_token, user_id, kdf_*, totp_required }
POST /api/v1/auth/refresh
Обменять refresh-токен на свежий короткоживущий access-токен.
Тело{ refresh_token }
Ответ{ access_token, refresh_token }
POST /api/v1/auth/logout Bearer
Отозвать текущий refresh-токен.
Ответ{ ok }
POST /api/v1/auth/totp/setup Bearer
Включить TOTP-двухфакторку для аккаунта.
Тело{ secret_b32, current_code }
Ответ{ ok }

Vault

CRUD по записям. Всё уходит и приходит уже зашифрованным; сервер хранит и отдаёт только шифротекст.

GET /api/v1/vault Bearer
Список всех записей (шифротекст) в хранилище.
Ответ[ { id, meta_enc_b64, body_enc_b64, version, created_at, updated_at } ]
POST /api/v1/vault Bearer
Добавить запись. meta/body уже зашифрованы на клиенте до отправки.
Тело{ meta_enc_b64, body_enc_b64, blind_index_b64? }
Ответ{ id, ... }
GET /api/v1/vault/:id Bearer
Получить одну запись по id.
PUT /api/v1/vault/:id Bearer
Обновить запись; expected_version защищает от перезаписи более свежего изменения.
Тело{ meta_enc_b64?, body_enc_b64?, expected_version }
DELETE /api/v1/vault/:id Bearer
Переместить запись в корзину (soft-delete, обратимо).
GET /api/v1/vault/trash Bearer
Список записей в корзине.
POST /api/v1/vault/:id/restore Bearer
Восстановить запись из корзины.
DELETE /api/v1/vault/:id/purge Bearer
Удалить запись навсегда — без возможности отмены.

Sharing

Два способа передать секрет: одноразовая burn-after-read ссылка или end-to-end доставка другому пользователю через sealed-box.

POST /api/v1/share Bearer
Создать одноразовую ссылку. Ключ расшифровки лежит в URL-фрагменте и на сервер не попадает.
Тело{ payload_b64, nonce_b64, ttl_secs, max_views }
Ответ{ id, expires_at }
GET /api/v1/share/:id
Открыть одноразовую ссылку. Сгорает после разрешённого числа просмотров.
Ответ{ payload_b64, nonce_b64 }
GET /api/v1/users/lookup?email= Bearer
Найти публичный ключ пользователя по email, чтобы поделиться с ним end-to-end.
Ответ{ user_id, pubkey_b64 }
POST /api/v1/shares/user Bearer
Отправить запись другому пользователю, запечатав под его публичный ключ — откроет только он.
Тело{ to_email, payload_b64 }
GET /api/v1/shares/incoming Bearer
Список записей, которыми с тобой поделились.
DELETE /api/v1/shares/:id Bearer
Удалить входящий или исходящий шеринг.

Tokens & confirmations

Scoped-токены дают интеграции читать выбранные записи — по желанию с подтверждением в приложении или Telegram.

GET /api/v1/tokens Bearer
Список твоих API-токенов.
POST /api/v1/tokens Bearer
Создать scoped-токен для интеграции — выбрать, какие записи можно читать и нужно ли подтверждение на каждое чтение.
Тело{ name, item_ids[], require_confirmation, rate_limit_per_hour, ttl_secs }
Ответ{ id, token, expires_at }
DELETE /api/v1/tokens/:id Bearer
Немедленно отозвать токен.
GET /api/v1/confirmations/pending Bearer
Список запросов на доступ, ожидающих твоего решения.
POST /api/v1/confirmations/:id/resolve Bearer
Подтвердить или отклонить ожидающий запрос.
Тело{ decision: "approve"|"deny" }
GET /api/v1/api/vault/:id Bearer (scoped token)
Как интеграция читает scoped-запись. Если нужно подтверждение, первый запрос вернёт confirmation_id для опроса, пока ты не одобришь.

Ограниченные API-токены (для интеграций)

Создай ограниченный токен в UI (API-токены). Он может читать только разрешённые записи, и чтение можно требовать подтверждать. Поток: первый GET возвращает confirmation_id со статусом pending_confirmation; владелец подтверждает в приложении или через Telegram; повтори GET с ?confirmation_id= чтобы получить (всё ещё зашифрованную клиентом) запись.

Заметки

meta_enc / body_enc — это nonce(24)‖ciphertext, зашифрованные vault-ключом, выведенным из мастер-пароля. Сервер их расшифровать не может.