O.G.A.S. English

Защита

От чего платформа защищает человека и его данные, как именно и что остаётся на его ответственности.

Введение

Документ описывает угрозы, учитываемые платформой, и меры защиты. Документ не является сертификатом безопасности и юридическим заключением.

1 Граница модели

Платформа работает на компьютере человека, один человек на экземпляр. Человек может быть любым, не обязательно программистом, и использует не только свои, но и чужие модули. Модуль считается доверенным кодом: человек сам его добавил и сам запускает. Модуль работает с правами того же пользователя WSL.

Из этого следует:

Отдельный OS-процесс защищает другие части от отказа модуля, но прав у модуля не отнимает.

2 Защищаемые ресурсы

Ключи к сервисам, токены и прочие секреты человека и его модулей — это ценность человека и модуля, но платформа ими не распоряжается: не хранит, не выдаёт и не управляет. Единственные ключи, которые платформа держит сама, — ключ компьютера и ключ писем профиля: ими она подписывает посылки и открывает письма (раздел 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 может подключиться вместо окна и от его имени запускать прогоны, изменять настройки, устанавливать модули, останавливать экземпляр. Страница окна с содержимым из сети расширила бы возможности нападения.

Мера:

Остаточный риск: токен виден в командной строке процесса окна любой программе того же пользователя Windows, и такая программа может подключиться с этим токеном. Обмен по 127.0.0.1 не шифруется. С включённым портом отладки любая местная программа управляет страницей окна. Защиты от кода того же человека платформа не обещает — как в T-02.

3.11 Просьба повторного запуска (T-11)

Угроза: запуск глаголом, которому нужна мастерская, оставляет работающему экземпляру записку run/launch.json в папке данных и будит его сигналом (Устройство платформы, 3.6.3). Программа того же пользователя может оставить такую записку сама и заставить экземпляр сделать вызов, о котором человек не просил.

Мера:

Остаточный риск: программа того же пользователя может открыть лицо любой программы человека и тем самым включить её — то же самое она может сделать, запустив ярлык. От программ того же пользователя платформа не защищает (раздел 1).

3.12 Рисунок пульта (T-12)

Угроза: рисунок пульта приходит из чужих рук — с переданным процессом или из загруженного файла. Файл под именем рисунка может оказаться не рисунком; SVG может нести сценарий и ссылки наружу; имя файла или путь переноса может указать за пределы папки пульта; ссылка в папке может при переносе вытащить в пакет любой файл машины.

Мера:

Остаточный риск: разбор самого изображения выполняет WebView2; уязвимость его разборщика PNG, JPEG, GIF или WebP платформа не закрывает.

3.13 Файл процесса (T-13)

Угроза: файл, который человек даёт процессу, — картинка, звук, видео, любой файл (Форматы файлов, раздел 16) — может оказаться не тем, чем назван; имя в вызове или поле ссылки может указать за пределы папки процесса; файл может быть огромным или брошенным на половине.

Мера:

Остаточный риск: разбор картинки, звука и видео выполняет WebView2, как у рисунка пульта; модуль получает файл как файл результата и разбирает его сам (Модули, раздел 6). Открытый файл разбирает программа Windows, которая его открыла, со своими ошибками: документ с изъяном в ней подействует на неё; окончание имени, а не содержимое, решает, какая программа его откроет.

3.14 Скачанное из источника (T-14)

Угроза: источник — витрина O.G.A.S., Hugging Face, Civitai или сайт, который человек назвал сам, — или кто-то на пути к нему отдаёт не то: файл с именем, ведущим за пределы папки, файл больше обещанного или бесконечный, подменённое содержимое, нейросеть в формате, который при чтении исполняет код (.bin, .pt, .pth, .ckpt, .pkl — сохранённые через pickle), программу или модуль, которые делают с правами человека что угодно. Запрос поиска уходит с компьютера и говорит источнику, что человек ищет.

Мера:

Остаточный риск: витрина ogas.space подписана ключом сайта, а её файлы закреплены контрольными суммами внутри подписанной витрины: захват сервера не подменит ни витрину, ни файлы. Подменит — утечка ключа сайта с компьютера автора сайта, до версии платформы с новым ключом. Другие витрины, Hugging Face и Civitai не подписаны: подлинность их файлов проверяется только контрольной суммой, которую называет тот же источник, — подменённый источник подменит и её. Модуль и программа из источника — чужой код с правами человека (3.1). Нейросеть в формате safetensors кода не исполняет, но модуль, который её читает, может прочитать её небезопасно. Лицензию скачанного платформа показывает, а не проверяет: соблюдать её — дело человека.

3.15 Посылки и сайт (T-15)

Угроза: чужой выдаёт себя за профиль человека; захваченный сервер ogas.space подсовывает платформе ложную витрину, доску обращений, отзывы, состояния отправок или письма; поток посылок заваливает сайт; посылка протаскивает исполняемый файл или выводит путь из своей папки на компьютере автора сайта; по сайту связывают посылки одного человека между собой.

Мера:

Остаточный риск: автор сайта видит, чей профиль стоит за каждой посылкой, в том числе инкогнито. Похищенный компьютер подписывает за профиль, пока главным ключом не отозвали все компьютеры, кроме своего; ключ писем у него остаётся, и письма, пришедшие до нового профиля, он прочтёт. Кто потерял и файл ключа, и код восстановления, теряет профиль: восстановить его некому. Подпись не делает вещь безопасной: автор сайта читает код, но может пропустить спрятанное, а зависимостей в посылке нет — их ставит окружение (3.7).

4 Обязательные меры реализации

5 Модель доверия

5.1 Один человек на экземпляр

Журнала действий человека нет. Экземпляр обслуживает одного человека, ролей нет, а что происходило, видно по журналу событий, контрольным точкам и core.jsonl. Отдельный журнал «кто что сделал» нужен там, где людей несколько, — вместе с ролями и удалённым доступом.

Входа по паролю нет. Удалённых вызовов нет. Функция подтверждает себя ядру токеном запуска и записью в реестре. Окно подтверждает себя функции ui токеном сессии (T-10); это метка подключения, а не вход человека.

Ядро допускает функцию к работе при совпадении следующих сведений:

Модуль не может вызвать запись документа, остановку экземпляра или другие методы ядра.

5.2 Доступа по сети нет

Обращение к платформе по сети невозможно. Открытый вход неизбежно будет обнаружен, а надёжно защитить его сложно.

6 Личные данные

Платформа отправляет наружу только посылки — по команде человека и показав, что уходит (раздел 8). Сама она только читает подписанные файлы сайта ogas.space: при запуске, если включены настройки profile.check_on_start и sources.check_on_start, иначе по кнопке «Проверить»; сайт при этом узнаёт только адрес, с которого читают, как у любого посетителя. Модуль отправлять данные может: это доверенный код с правами человека.

Журналы хранят как можно меньше содержимого пакетов: вместо копий больших данных в них ссылки. Сколько хранить журналы, когда их удалять и какие требования предъявляет законодательство той или иной страны, не определено.

7 Обновления и происхождение кода

Обновление — замена исполняемых файлов. Подписи у них нет, поэтому подлинность исполняемых файлов, модулей и пакетов Python не гарантируется.

При разработке выполняются:

Готовые программы, модули и обновления программы и платформы выходят на сайте 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 (новая версия платформы); обе включены по умолчанию и видны в настройках.