231a64300d
Существенная переработка base-system по итогам multi-agent ревью: - A/B-единица = весь boot-юнит (kernel+dtb+initramfs+rootfs) на слот; загрузчик вне A/B - bootcount/bootlimit + mark-good (Shell-кадр) — иначе откат не срабатывает - overlay upper/work на tmpfs; персист только через /data - ФС /data: f2fs(рек)/ext4 + power-safe mount + durable-write (fsync/rename) - at-rest шифрование /data (fscrypt, eFuse-bound, v4) - watchdog: SoC+MCU разведены, вооружён в boot-окне, единственный владелец - boot-порядок исправлен под architecture §6 (splash в Stage 0, ядро в Stage 1) - secure boot = OTP-eFuse необратим + key-mgmt (не «мягкий переключатель») - НОВОЕ: время (RTC/NTP/GPS, TLS-gating), память (zram/OOM/cgroup), логи (journald volatile + критичное в /data + pstore), first-boot, factory-reset, локаль - OTA: A=механизм/подпись, L=канал; verified-boot в бюджете boot; SD-тир; образ v0≠v4 Кросс-док: roadmap (образ v4 = флешируемый релиз), hardware (тепло/eMMC ✅ резолв), security-privacy (at-rest шифрование как открытый→направлен в A §3). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
148 lines
12 KiB
Markdown
148 lines
12 KiB
Markdown
# Контракт: безопасность и приватность
|
||
|
||
> Модель изоляции, разрешений и приватности (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.
|
||
- 🟡 **Шифрование данных at-rest.** Изъятая eMMC/SD = открытая утечка ПДн водителя
|
||
(память `.md`, токены, app-storage); sandbox это не закрывает (модель §1–§6 — про
|
||
работающую систему, не про физическое изъятие). → решено направлением в
|
||
[a-base-system.md](../domains/a-base-system.md) §3 (fscrypt чувствительных поддеревьев,
|
||
привязка к OTP/eFuse, v4 вместе с secure boot).
|
||
|
||
---
|
||
|
||
## Журнал решений (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 |
|