Хранилище конфигурации
Хранилище конфигурации синхронизирует конфигурацию CLI между устройствами. Конфигурации шифруются на устройстве ключом шифрования содержимого (CEK), которым сервер никогда не владеет. Раздел Безопасность точно указывает, от чего это защищает и от чего не защищает.
Способы разблокировки (слоты ключей)
На одно хранилище приходится один CEK, обёрнутый отдельно для каждого способа разблокировки (по аналогии со слотами ключей LUKS). Любой отдельный слот открывает один и тот же ключ, а слоты можно добавлять и удалять без повторного шифрования данных:
| Способ | Что это | Примечания |
|---|---|---|
| Passkey | WebAuthn passkey с расширением PRF | Самый надёжный вариант, привязан к устройству |
| Мастер-пароль | Пароль, который вы задаёте сами, растянутый через PBKDF2-SHA256 (600 000 итераций) | Работает без аппаратуры с поддержкой PRF, а также позволяет подключать CLI без браузера |
| Код восстановления | Сгенерированный код вида RC1-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX | Показывается один раз при создании, сохраните его в надёжном месте |
Все способы работают по одной и той же схеме: слот выдаёт секрет, который вместе с серверным секретом разворачивает CEK. Ни одной из половин по отдельности недостаточно, и секрет слота никогда не попадает на сервер. Слот с мастер-паролем является самым слабым из трёх: у сервера есть всё необходимое, чтобы офлайн подбирать пароль, поэтому пароль должен быть надёжным. У слотов passkey и кода восстановления такой слабости нет.
Слоты управляются в портале, на странице «Хранилище конфигурации». Организациям, которым нужна разблокировка только по аппаратному ключу, доступна политика требовать passkey: она отклоняет и отзывает все слоты, кроме passkey, для всего хранилища.
Разблокировка выполняется на уровне устройства: вы разблокируете хранилище один раз на новом устройстве, и после этого ежедневные операции CLI (push/pull) работают без обращения к passkey или вводу пароля.
Предварительные требования
- Двухфакторная аутентификация включена в вашей учётной записи
- Для способа passkey: провайдер passkey с поддержкой PRF, например, ключ безопасности FIDO2 (YubiKey), iCloud Keychain, Google Password Manager, 1Password или Dashlane
- Браузер: Chrome 133+, Edge 133+, Firefox 130+ или Safari 17+
Требование PRF относится только к слоту passkey. Способы с мастер-паролем и кодом восстановления работают в любом поддерживаемом браузере.
Настройка
- Перейдите в Хранилище конфигурации в боковой панели, затем нажмите Настроить хранилище конфигурации
- Контрольный список требований проверяет ваш браузер, 2FA и статус сессии
- Выберите первый способ разблокировки и нажмите Создать хранилище конфигурации:
- Passkey, если ваш провайдер поддерживает PRF: ключ безопасности нужно коснуться дважды, чтобы зарегистрировать его и чтобы получить ключи шифрования.
- Мастер-пароль, который работает в любом браузере, в том числе с провайдерами passkey без PRF, например Bitwarden.
- При желании код восстановления: он показывается один раз, и его нужно сохранить до создания хранилища.
- Настройка завершена. CLI хранит секрет разблокировки в связке ключей операционной системы.
Passkey можно добавить позже на странице Config Storage. Держите не меньше двух способов разблокировки, чтобы потерянный или неподдерживаемый аутентификатор не лишил вас доступа.
Совместимость провайдеров PRF
| Провайдер | Поддержка PRF | Платформы |
|---|---|---|
| YubiKey / ключи безопасности FIDO2 | ✅ | Windows 11, macOS, Linux |
| iCloud Keychain | ✅ | macOS 15+, iOS 18+ |
| Google Password Manager | ✅ | Android |
| 1Password | ✅ | Android, iOS |
| Dashlane | ✅ | Кроссплатформенный |
| Расширение Bitwarden | ❌ | Используйте вместо него мастер-пароль |
| Windows Hello | ❌ | Не поддерживается |
Подключение CLI без браузера
Машина без браузера (сервер, CI-раннер, демон executor) может подключиться к существующему хранилищу через способ с мастер-паролем:
rdc config remote enable --master-password
Требования:
- Слот с мастер-паролем уже создан через портал (ключ во время создания слота держит браузер, поэтому сам этот шаг без браузера выполнить нельзя)
- API-токен со скоупом
config:enrollдля аутентификации запроса
Подключение представляет собой операцию чтения: CLI получает открытые параметры KDF слота и обёрнутый ключ, локально вычисляет секрет пароля и разворачивает CEK прямо на устройстве. Это даёт устройству возможность расшифровывать и синхронизировать конфигурацию, но не изменяет само хранилище.
Как ключи попадают в CLI
rdc config remote enable (и rdc config rotate-cek) передают секрет разблокировки в CLI через сервер аккаунта. CLI и браузер напрямую не общаются, поэтому всё работает одинаково на сервере без браузера, в WSL с браузером в Windows и на телефоне.
- Сначала войдите в CLI командой
rdc subscription login. Сервер привяжет запрос к этому аккаунту. - CLI создаёт кратковременный запрос и выводит ссылку и код сопряжения, например
7KQ2-M9XD-P4RT. Всё, что несёт ссылка, лежит после символа#, а браузеры никогда не отправляют эту часть на сервер. - Откройте ссылку в любом браузере, где выполнен вход в тот же аккаунт. Запрос от другого аккаунта отклоняется.
- Когда страница попросит, введите код сопряжения из терминала. Кнопка разблокировки остаётся неактивной, пока код не совпадёт.
- Разблокируйте хранилище с помощью passkey или мастер-пароля. Браузер запечатывает ключ для CLI, а сервер пересылает блоб, который не может прочитать.
- CLI расшифровывает блоб, сохраняет секрет в системной связке ключей ОС и сообщает об успехе.
Запрос действует 10 минут. Чтобы отменить его, нажмите Ctrl+C в CLI: CLI просит сервер отозвать ссылку, и она сразу перестаёт работать, а страница предлагает запустить команду снова. Если этот запрос не дошёл, ссылка остаётся рабочей до истечения срока запроса. Если ссылку открыли после истечения срока или после перенаправления на вход потерялась часть после #, запустите команду заново.
Код сопряжения вычисляется из ключа внутри ссылки. Если кто-то подменит ссылку своей, код в вашем терминале не совпадёт с ожидаемым страницей, и ничего не будет выдано.
Это защищает от подмены ссылки и от ретранслятора, который подменяет или подделывает блоб. От сервера, который отдаёт изменённый код страницы, это не защищает: страницу, которую вы открываете, отдаёт сервер аккаунта, и ключи защищены ровно настолько, насколько надёжен этот код. То же доверие распространяется на все страницы портала, работающие с ключом конфигурации.
Включение и офлайн-чтение
rdc config remote enable подключает активную конфигурацию к хранилищу. Если хранилище пустое, включение инициализирует его данными вашей текущей локальной конфигурации: локальные ресурсы отправляются как первая версия хранилища, а затем считываются обратно, чтобы подтвердить, что цикл прошёл успешно. Если в хранилище уже есть содержимое, включение согласовывает конфигурацию с ним, а не перезаписывает его (при реальном расхождении операция прерывается, если не передан флаг --force).
После включения конфигурация хранит полный кеш для чтения, зашифрованный так же, как и любая локальная конфигурация, поэтому хранилищем можно пользоваться, даже если сервер аккаунта недоступен:
- Чтение работает офлайн. Кешированное содержимое выдаётся с предупреждением об устаревании в stderr, с указанием версии и времени кеширования (
cachedVersion/cachedAt). - Запись требует сервер и завершается отказом при его недоступности. Офлайн-очереди записи не существует: запись, которая не может достучаться до сервера, завершается ошибкой с указанием сервера. Если команда записи завершилась успешно, изменение уже на сервере.
- Одновременные изменения с двух машин разрешаются через pull-replay-repush: сервер принимает отправку только поверх версии, которую она заменяет, а проигравшая отправка повторяется поверх свежей копии, поэтому параллельное изменение в другом месте не перезаписывается.
- Локальная конфигурация (без блока
remote) этим никак не затрагивается и полностью работает офлайн.
Что синхронизируется
Всё в конфигурации синхронизируется, включая сетевой ID каждого репозитория, кроме следующих локальных для устройства полей: schemaVersion, version, remote, encryption, renetPath, credentials.masterPasswordVerifier, а также полей входа account.accountServer и account.e2ePublicKey. Вход и выход из системы выполняются отдельно на каждом устройстве.
Версии и восстановление
Сервер хранит последние 50 версий каждой конфигурации.
rdc config remote versions
rdc config remote restore <version>
Восстановление публикует старое содержимое как новую версию поверх текущей; номер версии никогда не двигается назад. Каждое устройство получает восстановленное содержимое при следующем pull, и восстановление фиксируется в журнале аудита.
Ротация ключа
Ротация CEK хранилища переоборачивает его под новым поколением:
- Коды восстановления всегда аннулируются при ротации, сгенерируйте и сохраните новый код после неё
- Слот с мастер-паролем сохраняется, только если пароль был повторно введён в мастере ротации
- Слот, оставшийся на старом поколении, помечается как устаревший, а не падает с непонятной ошибкой расшифровки
- Токены конфигурации остальных участников отзываются, а устройству, у которого остался старый ключ, предлагается заново включить синхронизацию через
rdc config remote enable
Управление участниками
Хранилище конфигурации привязано к организации. Участники управляются через веб-портал:
- Просмотр участников: Хранилище конфигурации → Участники
- Добавить участника: В настоящее время только через CLI (веб-интерфейс планируется)
- Удалить участника: Нажмите кнопку удаления на странице Участники (требуется 2FA + повторная аутентификация)
Защитные механизмы предотвращают удаление последнего активного участника или удаление самого себя.
Конфигурации в хранилище дополнительно привязаны к команде, но эта привязка является контролем доступа на стороне сервера, а не криптографической изоляцией: один общий для всей организации CEK шифрует конфигурации всех команд, а то, какие команды доступны конкретному участнику для чтения, определяет сервер.
Безопасность
Что защищено. Хранимые конфигурации конфиденциальны при компрометации хранилища сервера и при пассивном операторе. Каждый блоб привязан к своему хранилищу, конфигурации, команде и версии, поэтому сервер не может подменить блоб одной конфигурации блобом другой или изменить его незаметно.
Что не защищено. Оператор, подающий вредоносный код портала, может прочитать ключ в браузере. Оператор также может утаить самую новую версию от устройства, которое её ещё не видело.
| Сервер может | Сервер не может |
|---|---|
| Видеть идентификаторы конфигураций, команды, номера версий, временные метки, размеры блобов, количество полей в конфигурации и тип каждого поля, а также IP-адреса клиентов | Видеть имена машин, репозиториев или хранилищ (они скрыты) или любое значение конфигурации |
| Отказывать, задерживать или удалять конфигурации и их историю | Выдать содержимое одной конфигурации за другую или изменить его незаметно для устройства |
| Выдать устройству старую версию, если оно ещё не видело более новую | Выдать CLI версию старше той, что он уже видел: CLI её отклонит |
| Офлайн подбирать мастер-пароль | Открыть слот passkey или кода восстановления |
Другие меры защиты:
- Разделённый ключ: для расшифровки нужен и секрет слота (на устройстве), и секрет сервера
- Удаление требует знания: чтобы убрать зафиксированное значение из конфигурации, нужно доказать, что значение было известно, поэтому агент с частичным доступом не может незаметно стереть поля
- Ротация токенов: каждый запрос обновляет токен конфигурации; токен привязан к IP-адресу своего первого использования и истекает через 7 дней
- Отзыв: удаление участника сразу же удаляет его слоты ключей и токены; то, что он уже успел получить, остаётся на его устройстве, а ротация CEK не даёт сохранённому им ключу открывать более поздние версии
Устранение неполадок
| Ошибка | Причина | Решение |
|---|---|---|
| PRF not supported | Аутентификатор не поддерживает расширение PRF | Используйте YubiKey, iCloud Keychain, 1Password или Dashlane, либо добавьте слот с мастер-паролем |
| X25519 not supported | Слишком старая версия браузера | Обновите до Chrome 133+, Edge 133+, Firefox 130+ или Safari 17+ |
| Already configured | Хранилище уже существует для вашей организации | Посетите /account/config-storage для управления |
| Config storage not configured | На сервере отсутствует blob-хранилище | Свяжитесь с администратором для настройки R2/RustFS |
| Token expired | Нет активности 7 дней, либо машина сменила сеть | Обновляется автоматически через вход; если сохранённого входа нет, выполните rdc subscription login или rdc config remote enable |
| Конфигурация вернулась в более старой версии | Сервер вернул более старую копию, чем та, что это устройство уже видело | Локально ничего не изменилось; повторите попытку и сообщите, если повторяется |
| Cannot remove last member | Навсегда заблокирует хранилище | Сначала добавьте другого участника |
| Stale slot | Слот относится к состоянию до последней ротации ключа | Добавьте слот заново (коды восстановления нужно генерировать заново после каждой ротации) |
Смотрите также
- Веб-консоль: разблокировка хранилища в браузере для запуска команд
- Прокси и executor: как разблокированный ключ передаётся executor’у