docs: завершить Tier 1 (контракты) + ревью-фикс red-line CAN
- security-privacy: изоляция, capabilities, гейтинг по каналам, приватность/152-ФЗ; first-party = вшит в подписанный образ; рисковые комбинации (vehicle_read+network) - plugin-sdk: манифест, точки расширения, коллизия интентов, host-allowlist - hardware: RK3588, power-safe, периферия, HAL/BSP портирование - ВАЖНО: уточнён red-line CAN (принцип #2 + hardware §4): «чтение» = без управляющих/actuator/write-передач; диагностические OBD read-запросы допустимы (иначе не прочитать DTC); listen-only — только пассивный сниффинг - + автозащита питания, тепло, износ eMMC; кросс-доковые аннотации Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# Контракт: безопасность и приватность
|
||||
|
||||
> Модель изоляции, разрешений и приватности (152-ФЗ). Здесь **решаются открытые
|
||||
> вопросы**, направленные из [ipc.md](ipc.md): гейтинг data-plane, экспорт объектов
|
||||
> из песочницы, приватное хранилище, целостность манифеста.
|
||||
|
||||
Статус: **v1 (на ревью).**
|
||||
Связано с: [architecture.md](../architecture.md) (§5,§7) · [ipc.md](ipc.md) · [plugin-sdk.md](plugin-sdk.md) · [principles.md](../principles.md) (#1,#2,#7) · домен F
|
||||
|
||||
---
|
||||
|
||||
## 1. Слои защиты (defense-in-depth)
|
||||
|
||||
| Слой | Что гарантирует |
|
||||
|------|-----------------|
|
||||
| **Архитектурный** | write-пути к CAN нет в системе → красные линии держатся даже при полном компромиссе (принципы #1, #2) |
|
||||
| **Песочница** | bubblewrap (апы/плагины) + systemd-hardening (ядро) — ограничивает syscalls/FS/сеть |
|
||||
| **Брокер/портал** | доступ к ресурсам только через capability-гейтинг (D-Bus-прокси + сокеты) |
|
||||
| **Грант пользователя** | сторонние capabilities подтверждает пользователь |
|
||||
|
||||
> Ключевой инвариант: **сбежавший из песочницы плагин всё равно не запишет в CAN** —
|
||||
> писать некуда. Песочница защищает данные и приватность, не красные линии.
|
||||
|
||||
## 2. Песочница
|
||||
|
||||
- **Апы/плагины — bubblewrap:** mount/pid/net/user namespaces, **seccomp**-фильтр
|
||||
syscalls, минимальный FS-вид, `no-new-privileges`. Плагин видит только: свой код,
|
||||
разрешённые сокеты, своё приватное хранилище.
|
||||
- **Ядро — systemd-hardening:** `ProtectSystem`, `RestrictAddressFamilies`,
|
||||
`SystemCallFilter`, и т.п. на доверенных юнитах.
|
||||
- WASM-тир для лёгких логических плагинов — задел (см. architecture §7).
|
||||
|
||||
## 3. Модель capabilities
|
||||
|
||||
Манифест декларирует, что апу/плагину нужно. Каждая capability открывает ровно один
|
||||
ресурс и гейтится на своём канале:
|
||||
|
||||
| capability | что открывает | канал / механизм гейтинга |
|
||||
|------------|---------------|----------------------------|
|
||||
| `vehicle_read:[signals]` | чтение указанных сигналов | D-Bus-прокси: `VehicleData`, фильтр по списку |
|
||||
| `assistant_intents:[…]` | регистрация интентов | D-Bus: `Assistant.RegisterIntents` + OWN `IntentHandler` |
|
||||
| `ui_tiles` / `ui_screens` | вклад в UI | D-Bus: `Shell.Register*` (+ Wayland-сокет, если поверхность) |
|
||||
| `audio_out` | воспроизведение | **PipeWire-сокет** (пропускается в песочницу) |
|
||||
| `audio_in` (микрофон) | запись с микрофона — **высокочувствительно** | PipeWire-сокет + **runtime-грант + видимый индикатор**; сторонним — ограниченно |
|
||||
| `network` | доступ в сеть (опц. **host-allowlist** в манифесте) | net-namespace + **runtime-грант** |
|
||||
| `location` | GPS/положение | D-Bus (location) + **runtime-грант** |
|
||||
| `gpu` (render) | GPU-ускорение (UI/ML) | bubblewrap пропускает `/dev/dri` |
|
||||
| `storage` | приватное хранилище | bubblewrap **mount** `/data/apps/<id>/` |
|
||||
|
||||
> Чего нет в манифесте — физически недоступно: нет сокета, нет имени на шине, нет mount.
|
||||
|
||||
## 4. Гейтинг по каналам (закрывает routed-вопросы из ipc)
|
||||
|
||||
- **D-Bus** — фильтрующий per-app прокси из манифеста (детали — [ipc.md](ipc.md) §5).
|
||||
- **PipeWire (аудио)** — bubblewrap пропускает pipewire-сокет только при `audio_*`.
|
||||
→ *закрывает «гейтинг data-plane».*
|
||||
- **Wayland (графика/UI)** — wayland-сокет пропускается только при `ui_*` с поверхностью.
|
||||
→ *закрывает «гейтинг data-plane».*
|
||||
- **Экспорт объектов из песочницы** — прокси разрешает плагину **OWN** имена строго
|
||||
под префиксом `ru.shturman.plugin.<id>.*`, чтобы Assistant/Shell могли звать его
|
||||
`IntentHandler`/UI-объекты. → *закрывает «экспорт объектов».*
|
||||
- **Приватное хранилище** — `storage` монтирует в песочницу только `/data/apps/<id>/`;
|
||||
чужие данные и системные пути не видны. → *закрывает «приватное хранилище».*
|
||||
|
||||
## 5. Жизненный цикл разрешения
|
||||
|
||||
```
|
||||
declare (манифест) → install: пользователь видит запрошенные capabilities и
|
||||
подтверждает → enforce (прокси + sandbox конфигурятся под манифест) →
|
||||
runtime-грант для чувствительных (network / audio_in / location) — отдельный
|
||||
промпт в момент использования
|
||||
```
|
||||
|
||||
- **First-party** апы — авто-грант. *Что делает их first-party:* они **часть
|
||||
подписанного read-only base-образа** (вшиты, не устанавливаются пользователем) —
|
||||
это и есть якорь доверия, а не флажок в манифесте.
|
||||
- **Сторонние** — устанавливаются в `/data`, **всегда** в песочнице и под
|
||||
capability-гейтингом; install-time ревью + runtime-промпты на чувствительное.
|
||||
|
||||
## 6. Доверие и дистрибуция (целостность манифеста)
|
||||
|
||||
🟡 **Выбор на подтверждение:**
|
||||
- **(рек., сейчас)** install-time approve + песочница: пользователь видит
|
||||
capabilities и соглашается; защита — sandbox. Просто, достаточно для раннего этапа.
|
||||
- **(задел)** **подпись манифеста** + keyring издателей — против подмены capabilities
|
||||
при сторонней дистрибуции. → домен F (экосистема/«магазин»).
|
||||
- **(опц.)** курируемый стор с ревью.
|
||||
|
||||
Рекомендую: сейчас — approve+sandbox; подпись/стор — когда включаем community-маховик.
|
||||
→ *закрывает «целостность манифеста» (с явным заделом).*
|
||||
|
||||
## 7. Приватность / 152-ФЗ
|
||||
|
||||
**Принцип:** local-first; наружу — минимум и осознанно.
|
||||
|
||||
| Данные | Где обрабатываются | Уходит в облако? |
|
||||
|--------|--------------------|------------------|
|
||||
| Голос (аудио) | локально (STT/TTS) | **никогда** |
|
||||
| Текст запроса | локально → онлайн-LLM при необходимости | только текст, только в онлайн-режиме |
|
||||
| Данные машины (OBD/DTC) | локально | **в промпт онлайн-LLM** — только когда пользователь спросил и активен онлайн-режим; в офлайне не уходит вовсе |
|
||||
| Память о водителе (`.md`) | локально | нет (без явного согласия) |
|
||||
| Телеметрия | локально | **opt-in**, по умолчанию выключена |
|
||||
|
||||
- Онлайн-LLM — только **RU-провайдеры** (GigaChat/YandexGPT), данные в РФ (152-ФЗ).
|
||||
- **Прозрачность:** в онлайн-режиме контекст машины уходит провайдеру в составе
|
||||
промпта — это явно сообщается; офлайн-фолбэк держит всё на устройстве.
|
||||
|
||||
**Микрофон:** wake-word слушает постоянно, но **локально**; в обработку идёт только
|
||||
после слова-активатора; включённый микрофон показывается **видимым индикатором**.
|
||||
|
||||
**Охват гарантий и рисковые комбинации.** Таблица выше описывает поведение
|
||||
first-party (ассистент). Сторонний плагин с `network` **+** чувствительными данными
|
||||
(`vehicle_read`/`location`) теоретически может слить их куда угодно — это **рисковая
|
||||
комбинация**: требует заметного предупреждения при установке, по возможности —
|
||||
host-allowlist сети. Системная приватность держится на **capability-контроле**, а не
|
||||
только на политике ассистента.
|
||||
|
||||
---
|
||||
|
||||
## Открытые вопросы (найдено на self-review → роутинг)
|
||||
|
||||
- ◻️ **Отзыв и управление грантами.** Пользователь должен видеть и **отзывать**
|
||||
выданные capabilities по каждому апу. → Settings/Shell + домен C.
|
||||
- 🟡 **Цепочка доверия к base-образу.** Secure boot (якорь) — в [hardware.md](hardware.md) §3;
|
||||
осталась вторая половина — **подписанные OTA**. → домен A.
|
||||
- ✅ **Host-scoping сети.** → решено в [plugin-sdk.md](plugin-sdk.md) §3 (host-allowlist
|
||||
в манифесте; голый `network: true` — повышенный риск).
|
||||
- ◻️ **Локальный audit-log** чувствительного доступа (микрофон, сеть, гранты) —
|
||||
локально, не телеметрия. → этот контракт + Settings.
|
||||
|
||||
---
|
||||
|
||||
## Журнал решений (security-privacy)
|
||||
|
||||
| Решение | Выбор | Дата |
|
||||
|---------|-------|------|
|
||||
| Изоляция | bubblewrap (апы) + systemd-hardening (ядро); WASM — задел | 2026-06-16 |
|
||||
| Гейтинг ресурсов | per-capability на своём канале (D-Bus / PipeWire / Wayland / FS) | 2026-06-16 |
|
||||
| Экспорт из песочницы | OWN под префиксом `ru.shturman.plugin.<id>.*` | 2026-06-16 |
|
||||
| Хранилище | `storage` → mount `/data/apps/<id>/` | 2026-06-16 |
|
||||
| Доверие к манифесту | install-approve + sandbox сейчас; подпись/стор — задел (🟡) | 2026-06-16 |
|
||||
| Приватность | local-first; в облако только текст; OBD в промпт лишь онлайн + по запросу; телеметрия opt-in | 2026-06-16 |
|
||||
Reference in New Issue
Block a user