Защита
От чего платформа защищает человека и его данные, как именно и что остаётся на его ответственности.
Введение
Документ описывает угрозы, учитываемые платформой, и меры защиты. Документ не является сертификатом безопасности и юридическим заключением.
1 Граница модели
Платформа работает на компьютере человека, один человек на экземпляр. Человек может быть любым, не обязательно программистом, и использует не только свои, но и чужие модули. Модуль считается доверенным кодом: человек сам его добавил и сам запускает. Модуль работает с правами того же пользователя WSL.
Из этого следует:
- O.G.A.S. не является песочницей для модулей;
- поле
permissions_infoв манифесте — сведения от автора, а не ограничение; - модуль может читать и изменять любые файлы, доступные человеку, и обращаться к сети. Диски Windows подключены в WSL как
/mnt/<диск>, поэтому модулю доступны и документы Windows; - вредоносный или подменённый модуль может получить доступ ко всем этим данным;
- модуль от другого человека опасен так же, как любая загруженная программа.
Отдельный OS-процесс защищает другие части от отказа модуля, но прав у модуля не отнимает.
2 Защищаемые ресурсы
- файлы модулей;
- манифесты и записанные версии;
- документы графов и пультов;
- входные данные;
- файлы результатов прогонов;
- журналы и диагностические данные;
- настройки платформы и человека;
- доступные человеку внешние сервисы и файлы;
- одноразовые токены запуска функций (внутренние метки подключения, а не секреты человека);
- токен сессии окна (внутренняя метка подключения окна к функции
ui, действует до остановки функции); - состояние долгих модулей;
- ключ компьютера и ключ писем профиля (раздел 8).
Ключи к сервисам, токены и прочие секреты человека и его модулей — это ценность человека и модуля, но платформа ими не распоряжается: не хранит, не выдаёт и не управляет. Единственные ключи, которые платформа держит сама, — ключ компьютера и ключ писем профиля: ими она подписывает посылки и открывает письма (раздел 8); главного ключа профиля она не хранит. Токен запуска функции хранится только в памяти и модулю не передаётся. Где и как хранить свои секреты, решает человек или автор модуля, и отвечает за это он сам.
3 Угрозы и меры
3.1 Вредоносный модуль (T-01)
Угроза: модуль читает файлы, отправляет данные в сеть, запускает программы или меняет систему.
Мера: перед первым созданием или установкой модуля мастерская один раз за сессию предупреждает: модуль работает с правами пользователя, песочницы нет. Фактического ограничения нет.
Остаточный риск: высокий. Для недоверенных модулей платформа не подходит. Человек без подготовки не может оценить чужой модуль по коду. Поэтому до добавления платформа показывает, что именно приходит: название, размер, что модуль скачает, отпечаток и есть ли такой модуль уже (process.inspect, Сборка, установка и обслуживание, 5.6). Прав модуля платформа не показывает: песочницы нет, и такие права были бы обманом.
3.2 Чужая программа выдаёт себя за функцию (T-02)
Угроза: другая программа на том же компьютере пытается говорить с ядром как функция платформы.
Мера: Unix-сокет с правами 0600 на файловой системе Linux (не на диске Windows), проверка SO_PEERCRED — uid экземпляра и pid запущенной функции, одноразовый токен запуска в OGAS_LAUNCH_TOKEN, обязательное знакомство (handshake) первым сообщением. Модуль токена не получает и к сокету не подключается; при запуске модуля окружение очищается. От доверенного кода того же человека это не защищает.
Остаточный риск: программа, запущенная тем же человеком, может пользоваться всем, что доступно ему. Защиты от хозяина машины платформа не обещает.
3.3 Путь за пределы своей папки (T-03)
Угроза: в документе указан путь за пределами разрешённой папки.
Мера: относительные пути считаются от папки хозяина документа; .. и абсолютные пути отклоняются; границы папки проверяются; произвольные пути в методах запрещены. Путь в папке данных вдобавок разворачивается по ссылкам: самая глубокая существующая часть пути должна остаться внутри папки данных, иначе path_outside_root. Следствие: символьная ссылка внутри папки данных, ведущая наружу, не работает — прогоны на другом диске делают через --data-dir или монтирование, а не ссылкой. Папку установки платформа по ссылкам не разворачивает: её собрал сам человек, и модуль, положенный ссылкой, — обычный рабочий приём. Исключение в папке данных одно — программа, которую функция просит запустить оттуда (command_base: data у core.process.spawn): папки на её пути проверяются по ссылкам, а сама программа может быть ссылкой наружу и должна вести к файлу. Так запускается интерпретатор окружения процесса — ссылка на Python, из которого окружение сделано, — когда папка данных лежит вне папки установки; внутри неё путь считается от папки установки, где ссылки не разворачиваются и так. Окружение не путешествует с программой: пакет его не несёт, и .venv ставит у себя функция модулей.
Остаточный риск: между проверкой и записью остаётся зазор: ссылку можно подменить именно в этот момент. Запись идёт заменой файла, а не записью по ссылке, поэтому подмена приведёт к отказу или к файлу внутри папки, но строгое доказательство отсутствует. Модуль по модели доверия и так работает с правами человека (T-01).
3.4 Повреждённый протокол (T-04)
Угроза: неверный JSON, слишком длинная строка, смесь отладочного текста и протокола в stdout, зависший канал.
Мера: UTF-8, одно сообщение на строку, предел длины строки 4 МиБ, ограниченные очереди, отдельный поток stderr, ограничение времени ожидания, ответ Parse error и управляемое закрытие канала.
Остаточный риск: правильность сборки строк из частей и отказа при переполнении очереди подтверждается только сквозными проверками.
3.5 Секрет попал в журнал (T-05)
Угроза: модуль пишет секрет в stdout или stderr, либо секрет оказывается в результате и попадает в журнал.
Мера: своих секретов платформа не добавляет; модуль держит свои в файле .env своей папки, который не уходит при передаче модуля (Модули, раздел 9); размер данных пакета в JSON ограничен, большие данные идут файлами результатов. Журналы, документы и сокет экземпляра создаются с правами 0600: другие пользователи машины их не читают.
Остаточный риск: высокий. Платформа не умеет надёжно распознавать секреты в произвольном выводе доверенного модуля. Отказ настройкам, в имени которых есть secret, password, token, api_key, apikey или private_key, ловит только очевидные имена: ключ с другим именем, например openai_key, запишется в файл настроек как обычное значение.
3.6 Внешнее действие выполнилось дважды (T-06)
Угроза: после сбоя шаг повторно отправляет письмо, запрос или запись.
Мера: постоянный operation_id шага, объявление модуля idempotent / non_idempotent / unknown, решение человека, если исход шага неизвестен.
Остаточный риск: модуль может объявить себя безопасным для повтора неправильно; проверить смысл его работы платформа не может.
3.7 Установка зависимостей (T-07)
Угроза: вредоносный или подменённый пакет Python выполняет свой код во время установки окружения.
Мера: установка только по явной команде, отдельным OS-процессом, за которым платформа следит, из общего requirements.txt процесса, собранного из требований его модулей; источник и версии показываются, если их сообщает установщик.
Остаточный риск: установка пакетов — это выполнение чужого кода с правами человека. Проверки подписей и репутации нет. Переменные прокси человека, если они заданы, функции и модули получают как есть, и адрес прокси с именем и паролем в нём модулю тоже виден: модуль — доверенный код (3.1), а установка без них в сети с выходом только через прокси невозможна.
3.8 Перегрузка платформы работой (T-08)
Угроза: бесконечный цикл, огромный пакет, переполненный stdout или stderr, много OS-процессов, бесконечные перезапуски.
Мера: пределы на длину строки, очереди, размер файла результата, число кругов цикла, время, число OS-процессов и число перезапусков подряд.
Предела памяти и загрузки процессора у модуля нет. Причины: модуль — доверенный код самого человека или взятый им у другого; prlimit и cgroups v2 в WSL ведут себя особым образом и требуют проверки на целевой машине; при одном прогоне за раз виновник виден сразу.
Остаточный риск: высокий и принятый. Модуль с утечкой памяти займёт всю виртуальную машину WSL (по умолчанию половина оперативной памяти) и остановит платформу целиком; помогают только предел времени модуля timeout_ms и остановка прогона.
3.9 Документ повреждён при записи (T-09)
Угроза: сбой во время записи оставляет половину JSON или несогласованный набор файлов процесса.
Мера: временный файл, fsync файла, прежний файл в .bak через rename, fsync папки, номер поколения и проверка, что поколение N полное, иначе откат к N−1.
Остаточный риск: как ведут себя fsync, rename и файловая система WSL, требует проверки на целевой машине.
3.10 Окно платформы и его порт (T-10)
Угроза: функция ui ожидает соединения по TCP на 127.0.0.1. Программа Windows или WSL может подключиться вместо окна и от его имени запускать прогоны, изменять настройки, устанавливать модули, останавливать экземпляр. Страница окна с содержимым из сети расширила бы возможности нападения.
Мера:
- только
127.0.0.1; порт свободный на каждый запуск (ui.window.port= 0); - токен сессии — 256 бит из
/dev/urandom, новый при каждом запуске функции; окно получает его в командной строке; - первое сообщение соединения —
ui.window.helloс токеном; токены сравниваются за одинаковое время, чтобы по скорости ответа нельзя было подобрать токен. При несовпадении — ошибкаui_window_unauthorizedи закрытие. Окно одно: новое вытесняет прежнее; - окну закрыты
function.handshakeи все методы ядра, кромеcore.status,core.health,core.space,core.event.subscribeиcore.shutdown; остальное —method_not_allowed. Документы, запуск модулей и публикация событий остаются функциям; - страница встроена в исполняемый файл окна; правило
default-src 'self'запрещает загрузку чего-либо извне, внешних скриптов и страниц из сети в окне нет; - средства отладки WebView2 (
ui.window.devtools_port) по умолчанию выключены и помечены как режим разработки.
Остаточный риск: токен виден в командной строке процесса окна любой программе того же пользователя Windows, и такая программа может подключиться с этим токеном. Обмен по 127.0.0.1 не шифруется. С включённым портом отладки любая местная программа управляет страницей окна. Защиты от кода того же человека платформа не обещает — как в T-02.
3.11 Просьба повторного запуска (T-11)
Угроза: запуск глаголом, которому нужна мастерская, оставляет работающему экземпляру записку run/launch.json в папке данных и будит его сигналом (Устройство платформы, 3.6.3). Программа того же пользователя может оставить такую записку сама и заставить экземпляр сделать вызов, о котором человек не просил.
Мера:
- экземпляр выполняет по записке только глагол, который его реестр описывает как требующий мастерской, и только с аргументами, которые реестр этому глаголу даёт; глаголы прогона и установки по записке не выполняются;
- записка читается один раз и удаляется; нечитаемая, другого формата и пролежавшая дольше полуминуты не исполняется;
- записка доступна только пользователю, как и остальная папка данных;
- в поставке такой глагол один: он показывает лицо программы, и программа при этом включается, как при запуске её ярлыком.
Остаточный риск: программа того же пользователя может открыть лицо любой программы человека и тем самым включить её — то же самое она может сделать, запустив ярлык. От программ того же пользователя платформа не защищает (раздел 1).
3.12 Рисунок пульта (T-12)
Угроза: рисунок пульта приходит из чужих рук — с переданным процессом или из загруженного файла. Файл под именем рисунка может оказаться не рисунком; SVG может нести сценарий и ссылки наружу; имя файла или путь переноса может указать за пределы папки пульта; ссылка в папке может при переносе вытащить в пакет любой файл машины.
Мера:
- рисунок принимает и отдаёт только функция пульта (Форматы файлов, 7.2): имя — одно имя файла с окончанием из закрытого перечня, без папок; файл обязан начинаться так, как файл его вида, и быть не крупнее настройки
canvas.image_max_bytes; - окно показывает рисунок только как изображение — адресом с данными внутри, без обращения к сети: сценарии в SVG не исполняются, внешние ссылки не загружаются; политика содержимого страницы другого и не допускает (Мастерская, раздел 3);
- идентификатор процесса и пути переноса, пришедшие в вызове, проверяются: одно имя папки и путь внутри папки данных;
- ссылки в папке пульта не читаются и не переносятся, недописанный файл не виден;
- свой вид элемента — данные: документ
ogas.look/1с закрытым перечнем полей и рисунки, проверяемые как любой рисунок пульта; кода, сценариев и ссылок за пределы своей папки в нём нет, и папка вида принимается только целиком.
Остаточный риск: разбор самого изображения выполняет WebView2; уязвимость его разборщика PNG, JPEG, GIF или WebP платформа не закрывает.
3.13 Файл процесса (T-13)
Угроза: файл, который человек даёт процессу, — картинка, звук, видео, любой файл (Форматы файлов, раздел 16) — может оказаться не тем, чем назван; имя в вызове или поле ссылки может указать за пределы папки процесса; файл может быть огромным или брошенным на половине.
Мера:
- файл принимает и отдаёт только функция графа (
process.file.put,process.file.read): имя — одно имя файла, не скрытое и без папок; читается только файл изfiles/процесса или из результатов названного запуска, путь — внутри этой папки, ссылка файловой системы не читается; - файл не крупнее настройки
graph.file_max_bytes; части идут по порядку, пропущенная или повторная отклоняется, недописанное через сутки убирается; запуску файл дают, только пока он идёт; - окно показывает картинку, звук и видео только адресом
blob:, который само делает из прочитанного содержимого, и не больше 64 МиБ; политика страницы пускает для картинок адреса с данными внутри иblob:, для звука и видео — толькоblob:, и сеть не трогается; - текстовый файл окно показывает словами: читает его начало, не больше 256 КиБ, и выводит как текст, а не как разметку;
- файл, который человек открывает программой Windows или показывает в папке, программа окна берёт той же
process.file.readи кладёт копию в свою папку внутри временной папки Windows: имя — простое имя файла, без папок, без имён устройств Windows; копия не больше 512 МиБ. Открывается только вид, который смотрят, слушают или читают, — картинка, звук, видео, PDF, текст, документ, — по окончанию имени; программа, сценарий, ярлык, страница и всё неизвестное не открываются никогда — проверку делает сама программа окна, а не страница (ui_window_open_refused, Коды ошибок); такой файл можно только показать в Проводнике, и что с ним делать, решает человек.
Остаточный риск: разбор картинки, звука и видео выполняет WebView2, как у рисунка пульта; модуль получает файл как файл результата и разбирает его сам (Модули, раздел 6). Открытый файл разбирает программа Windows, которая его открыла, со своими ошибками: документ с изъяном в ней подействует на неё; окончание имени, а не содержимое, решает, какая программа его откроет.
3.14 Скачанное из источника (T-14)
Угроза: источник — витрина O.G.A.S., Hugging Face, Civitai или сайт, который человек назвал сам, — или кто-то на пути к нему отдаёт не то: файл с именем, ведущим за пределы папки, файл больше обещанного или бесконечный, подменённое содержимое, нейросеть в формате, который при чтении исполняет код (.bin, .pt, .pth, .ckpt, .pkl — сохранённые через pickle), программу или модуль, которые делают с правами человека что угодно. Запрос поиска уходит с компьютера и говорит источнику, что человек ищет.
Мера:
- в сеть функция источников ходит только по команде человека: поиск — по кнопке, загрузка — после того, как человек увидел файлы, их размер и лицензию; сама она ничего не ищет и не скачивает, и окно говорит, что запрос уходит на сайт источника;
- только
https, и переадресация — только наhttps; витрина в файле на этом компьютере (file:) может называть файлы только на этом же компьютере; ключей и входа на сайт источника платформа не знает: нейросеть, для которой источник требует вход или согласие с условиями, не скачивается, и человек видит почему; - имя каждого файла, пришедшего из сети, проверяется: относительный путь из обычных имён, без
.., без скрытых и без имён устройств; пишется он только внутрь папки своей загрузкиdownloads/<загрузка>/, сначала во временный файл рядом, и встаёт на место переименованием, когда скачан и проверен; - размер известен заранее и сверяется: загрузка больше настройки
sources.max_gibили больше свободного места не начинается; файл, выросший сверх объявленного источником, обрывается; - контрольная сумма SHA-256 сверяется, когда источник её называет — у витрины O.G.A.S. она обязательна для каждого файла, у Hugging Face есть у больших файлов, у Civitai — у файлов модели; не совпала — файл удаляется, загрузка отказывает (
source_hash_mismatch); - файлы, которые при чтении исполняют код, помечены в списке и сами не выбираются; если в выдаче есть
.safetensors, выбираются они; - картинку найденного для плитки функция источников берёт только с адреса, который источник назвал для этой вещи в последнем поиске, а не с адреса, который назвало окно; не крупнее 2 МиБ; принимает её, только если первые байты — PNG, JPEG, WebP или GIF; окну отдаёт данными, и окно показывает их как изображение, не обращаясь к сети, как рисунок пульта (3.12);
- скачанная нейросеть встаёт в папку нейросетей через её хозяина — функцию модулей — под именем, которое назвал человек, и не заменяет существующую; скачанные программа и модуль лежат в
downloads/и принимаются как принесённые папкой:process.inspectиmodule.inspectпоказывают, что придёт, и спрашивают о доверии (3.1); - проверенной считается только витрина на ogas.space — адрес начинается с
https://ogas.space/— и только если её подпись ключом сайта сходится (8.5); подпись не сходится или её нет — отказsource_signature_bad, и из такой витрины библиотека ничего не показывает; всякая другая витрина, в том числе витрина O.G.A.S., перенесённая настройкой на другой адрес или в файл, помечена в библиотеке «никто не проверял», а программу и модуль из неё платформа принимает только после вопроса о доверии с адресом витрины — каждый раз, даже если в этом сеансе человек уже сказал, что доверяет модулям; программа спрашивает так же, потому что приносит модули; заготовка интерфейса — данные, а не код: она принимается без вопроса о доверии, но только если её вместилища и элементы проходят правила пульта (canvas.piece.import).
Остаточный риск: витрина ogas.space подписана ключом сайта, а её файлы закреплены контрольными суммами внутри подписанной витрины: захват сервера не подменит ни витрину, ни файлы. Подменит — утечка ключа сайта с компьютера автора сайта, до версии платформы с новым ключом. Другие витрины, Hugging Face и Civitai не подписаны: подлинность их файлов проверяется только контрольной суммой, которую называет тот же источник, — подменённый источник подменит и её. Модуль и программа из источника — чужой код с правами человека (3.1). Нейросеть в формате safetensors кода не исполняет, но модуль, который её читает, может прочитать её небезопасно. Лицензию скачанного платформа показывает, а не проверяет: соблюдать её — дело человека.
3.15 Посылки и сайт (T-15)
Угроза: чужой выдаёт себя за профиль человека; захваченный сервер ogas.space подсовывает платформе ложную витрину, доску обращений, отзывы, состояния отправок или письма; поток посылок заваливает сайт; посылка протаскивает исполняемый файл или выводит путь из своей папки на компьютере автора сайта; по сайту связывают посылки одного человека между собой.
Мера:
- каждая посылка подписана ключом компьютера, за который поручился главный ключ профиля и который он назвал в карточке; без главного ключа за профиль не подписать, а главного ключа платформа не хранит; «Отозвать все компьютеры, кроме этого» оставляет на сайте один компьютер, и потерянный, даже ещё ничего не отправлявший, больше не подписывает (8.1);
- всё, что платформа читает с ogas.space, принимается, только если подпись ключом сайта сходится; имя файла входит в подпись, и один подписанный файл не выдать за другой (8.5);
- письма запечатаны ключом писем получателя: сервер, автор сайта и любой читатель сайта видят только запечатанные байты;
- посылка уходит только по команде человека, после того как он увидел, что уходит; перед отправкой платформа решает задачку на счёт — поток посылок стоит дорого, а регистрации нет;
- в предложенную вещь платформа не кладёт окружений, кэша, секретов
.env, прогонов, памяти узлов и исполняемых файлов; модуль не на Python уходит исходниками с lock-файлом зависимостей; пути вещи — относительные, из обычных имён, без..и скрытых; - сайт не показывает ключей профиля, а посылку инкогнито не связывает ни с профилем, ни с другими посылками (8.6).
Остаточный риск: автор сайта видит, чей профиль стоит за каждой посылкой, в том числе инкогнито. Похищенный компьютер подписывает за профиль, пока главным ключом не отозвали все компьютеры, кроме своего; ключ писем у него остаётся, и письма, пришедшие до нового профиля, он прочтёт. Кто потерял и файл ключа, и код восстановления, теряет профиль: восстановить его некому. Подпись не делает вещь безопасной: автор сайта читает код, но может пропустить спрятанное, а зависимостей в посылке нет — их ставит окружение (3.7).
4 Обязательные меры реализации
- не хранить в исходном коде собственных секретов платформы: платформа ими не владеет;
- не передавать модулю токен запуска функции;
- не принимать команду, у которой неверно указан отправитель или хозяин;
- не передавать модулю переменные
OGAS_LAUNCH_TOKENиOGAS_SOCKET; - проверять версию договора до того, как функция начнёт работать;
- проверять размер входных данных прежде, чем выделять под них много памяти;
- ограничивать
stdoutиstderrи не давать потокам чтения зависнуть друг на друге; - не писать протокольные данные в
stderrфункции без пометки; - не считать вывод модуля безопасным;
- не писать в журнал крупные данные пакетов целиком и значения настроек с секретными именами;
- сохранять документы целиком;
- предупреждать о модели доверия перед созданием, установкой и добавлением модуля;
- забывать токен запуска после того, как функция завершилась;
- не включать приём соединений извне по умолчанию: порт окна — только
127.0.0.1и только с токеном сессии; - не давать окну методы ядра вне закрытого списка;
- не хранить главный ключ профиля: после создания профиля или подключения компьютера он забывается;
- не принимать с ogas.space ни одного файла, подпись которого ключом сайта не сходится.
5 Модель доверия
5.1 Один человек на экземпляр
Журнала действий человека нет. Экземпляр обслуживает одного человека, ролей нет, а что происходило, видно по журналу событий, контрольным точкам и core.jsonl. Отдельный журнал «кто что сделал» нужен там, где людей несколько, — вместе с ролями и удалённым доступом.
Входа по паролю нет. Удалённых вызовов нет. Функция подтверждает себя ядру токеном запуска и записью в реестре. Окно подтверждает себя функции ui токеном сессии (T-10); это метка подключения, а не вход человека.
Ядро допускает функцию к работе при совпадении следующих сведений:
- известный
function_id; - токен запуска;
- версия договора;
- список разрешённых ей команд;
- принадлежность
process_handleэтой функции.
Модуль не может вызвать запись документа, остановку экземпляра или другие методы ядра.
5.2 Доступа по сети нет
Обращение к платформе по сети невозможно. Открытый вход неизбежно будет обнаружен, а надёжно защитить его сложно.
6 Личные данные
Платформа отправляет наружу только посылки — по команде человека и показав, что уходит (раздел 8). Сама она только читает подписанные файлы сайта ogas.space: при запуске, если включены настройки profile.check_on_start и sources.check_on_start, иначе по кнопке «Проверить»; сайт при этом узнаёт только адрес, с которого читают, как у любого посетителя. Модуль отправлять данные может: это доверенный код с правами человека.
Журналы хранят как можно меньше содержимого пакетов: вместо копий больших данных в них ссылки. Сколько хранить журналы, когда их удалять и какие требования предъявляет законодательство той или иной страны, не определено.
7 Обновления и происхождение кода
Обновление — замена исполняемых файлов. Подписи у них нет, поэтому подлинность исполняемых файлов, модулей и пакетов Python не гарантируется.
При разработке выполняются:
- фиксация версий зависимостей Rust в
Cargo.lock; - проверка лицензий: пакет со стороны, лицензию которого платформа не может взять, и пакет платформы без своей лицензии не проходят
make ci(scripts/third_party.py --check); перечень чужих пакетов с текстами их лицензий поставка несёт с собой; - закрепление нужных версий пакетов Python в
requirements.txtмодулей; - просмотр изменений манифестов;
- исключение секретов из репозитория;
- проверка путей внутри экспорта процесса и отпечатков модулей при добавлении;
- запись версий ядра, функций и модулей в диагностические сведения.
Готовые программы, модули и обновления программы и платформы выходят на сайте ogas.space. Его витрина подписана ключом сайта (8.5); исполняемые файлы обновления платформы — нет. Что платформа делает со скачанным из источника и чего не обещает — 3.14.
Платформа не становится хранилищем секретов.
8 Профиль, посылки и подпись сайта
Профиль — то, чем человек подписывает всё, что платформа отправляет на ogas.space; подпись сайта — то, чем автор сайта подписывает всё, что платформа оттуда читает. Хозяин профиля, посылок и писем — функция profile; витрины — функция sources. Форматы — Форматы файлов, раздел 21.
8.1 Ключи профиля
Таблица 1 — Ключи профиля
| Ключ | Что это | Где живёт | Для чего |
|---|---|---|---|
| главный | Ed25519 | у человека: кодом восстановления на бумаге и файлом ключа там, где он решил; платформа не хранит | создать профиль, подключить и отозвать компьютер, изменить и удалить профиль |
| компьютера | Ed25519, случайный | папка данных функции profile, только для пользователя |
подписывать посылки; за него поручился главный ключ |
| писем | X25519, выводится из главного | там же | открывать письма; одинаков на всех компьютерах профиля |
Секретные части ключей не покидают компьютер. Открытые части главного ключа и ключа компьютера едут в каждой посылке: по ним программа автора сайта проверяет подпись. Публике они не показываются.
8.2 Код восстановления
Код — главный ключ (32 байта) и два байта его SHA-256, записанные 55 знаками алфавита Crockford base32 группами по пять. При вводе буква O читается как ноль, I и L — как единица. Код, у которого контрольные байты не сходятся, отклоняется (key_code_bad), а не читается как другой ключ.
8.3 Файл ключа
Файл ключа хранит код. С паролем код зашифрован XChaCha20-Poly1305 ключом, который Argon2id выводит из пароля; без пароля код лежит в файле как есть, и файл надо хранить как сам код. Неверный пароль — отказ key_password_bad.
8.4 Что каким ключом подписано
Главный ключ подписывает сам: карточку профиля — в ней он называет компьютер, с которого она пришла, — отзыв компьютеров и удаление профиля, а ещё поручительство за ключ компьютера. Сайт принимает подпись только тех компьютеров, которые главный ключ назвал в карточке. Остальные посылки подписывает ключ компьютера. Подпись — над байтами тела посылки как они есть.
8.5 Подпись сайта
Каждый файл, который платформа читает с ogas.space, лежит рядом со своей подписью <имя>.sig — подписью Ed25519 над строкой ogas.site/1, именем файла и его байтами. Открытые части ключей сайта записаны в общем коде платформы; новый ключ сайта выходит новой версией платформы. Файл без подписи или с подписью, которая не сходится, не принимается (site_signature_bad, у витрины — source_signature_bad), и из него ничего не показывается.
8.6 Кто что видит
Таблица 2 — Кто что видит
| Что | Публика на сайте | Автор сайта | Ещё кто |
|---|---|---|---|
| карточка профиля | после взгляда автора сайта | да | — |
| ключи профиля | нет | открытые части | секретные — только владелец |
| отзыв, обращение, «Беру», сделанное | после взгляда автора сайта, с именем или «инкогнито» | да, и чей профиль | — |
| сообщение об ошибке | только «что выходит» и версия, если автор сайта поставил её под вещь | целиком | автор вещи — целиком, без имени сообщившего |
| ответ автора на отзыв | под отзывом, после взгляда автора сайта | да | написавший отзыв видит его в своих отправках |
| новый отзыв о вещи | отзыв — после взгляда автора сайта | да | автор вещи — уведомлением в платформе |
8.7 Когда платформа обращается к сайту
Отправляет — только по команде человека. Читает — по команде или при запуске, если включена настройка profile.check_on_start (свои отправки и письма) или sources.check_on_start (новая версия платформы); обе включены по умолчанию и видны в настройках.