Уровни безопасности
Движок TinyElf Agent реализует трёхуровневый конвейер безопасности, чтобы вызовы инструментов проходили достаточную проверку безопасности перед выполнением. Три уровня выполняются последовательно, и отклонение на любом уровне завершает процесс.
Трёхуровневый конвейер безопасности
graph TB
TC["Tool call request<br/>(toolName, args)"] --> L1
subgraph Layer1["Layer 1: ExecutionFirewall"]
L1["checkToolCall(name, args)"] --> L1a{"Path in deny list?"}
L1a -->|Yes| Block1["Block<br/>[firewall] Blocked"]
L1a -->|No| L1b{"Bash command contains deny path?"}
L1b -->|Yes| Block1
L1b -->|No| Pass1["Pass"]
end
Pass1 --> L2
subgraph Layer2["Layer 2: GuardianAgent"]
L2["review(name, args)"] --> L2a{"Mode = off?"}
L2a -->|Yes| Pass2a["Skip"]
L2a -->|No| L2b{"In review scope?"}
L2b -->|No| Pass2b["Skip"]
L2b -->|Yes| L2c["LLM risk assessment<br/>(15s timeout)"]
L2c --> L2d{"Risk level decision"}
L2d -->|"guard: high/critical"| Block2["Block<br/>[guardian] Blocked"]
L2d -->|"strict: medium+"| Block2
L2d -->|Allow| Pass2["Pass"]
end
Pass2 --> L3
Pass2a --> L3
Pass2b --> L3
subgraph Layer3["Layer 3: PermissionCallback"]
L3["isSensitiveTool(name)"] --> L3a{"Requires confirmation?"}
L3a -->|No| Pass3a["Auto-pass"]
L3a -->|Yes| L3b["Send confirmation request<br/>(5min timeout)"]
L3b --> L3c{"User reply"}
L3c -->|Allow| Pass3["Pass"]
L3c -->|AllowSession| Pass3s["Pass + cache"]
L3c -->|Deny/Timeout| Block3["Deny"]
end
Pass3 --> Exec["Execute tool"]
Pass3a --> Exec
Pass3s --> Exec
Уровень 1: ExecutionFirewall
ExecutionFirewall — это детерминированный шлюз безопасности, который блокирует доступ к чувствительным системным ресурсам на основе правил шаблонов путей.
Интерфейс
class ExecutionFirewall {
constructor(workspacePath: string);
checkPath(filePath: string, operation?: 'read' | 'write'): FirewallCheckResult;
checkCommand(command: string): FirewallCheckResult;
checkToolCall(toolName: string, params: Record<string, unknown>): FirewallCheckResult;
setWorkspacePath(newPath: string): void;
}
interface FirewallCheckResult {
allowed: boolean;
deniedBy?: string;
reason?: string;
}
Правила запрещённых путей
Запрещены и чтение, и запись
| Шаблон пути | Причина |
|---|---|
C:\Windows\ | Системный каталог Windows |
C:\Program Files\ | Каталог установки программ |
C:\ProgramData\ | Каталог данных программ |
C:\Recovery\ | Раздел восстановления |
/etc/ | Каталог системной конфигурации |
/usr/ | Системный каталог |
/sbin/ | Системные бинарные файлы |
/boot/ | Загрузочный каталог |
/proc/ | Псевдофайловая система процессов |
/sys/ | Системная псевдофайловая система |
/dev/ | Файлы устройств |
.ssh/ | Каталог ключей SSH |
.gnupg/ | Каталог ключей GPG |
.aws/ | Учётные данные AWS |
.azure/ | Учётные данные Azure |
.gcloud/ | Учётные данные GCloud |
.kube/config | Конфигурация Kubernetes |
.docker/config.json | Конфигурация Docker |
id_rsa, id_ed25519, id_ecdsa | Файлы приватных ключей SSH |
.env, .env.* | Файлы переменных окружения |
credentials.json | Файл учётных данных |
service_account*.json | Ключи сервисных аккаунтов |
| Firefox/Chrome/Edge user data | Файлы конфигурации браузера |
System32\config\SAM/SYSTEM/... | Реестр Windows |
Запрещена только запись (чтение разрешено)
| Шаблон пути | Причина |
|---|---|
.gitconfig | Конфигурация Git |
.npmrc | Конфигурация npm |
.bashrc | Конфигурация Bash |
.zshrc | Конфигурация Zsh |
.profile | Конфигурация shell |
.bash_profile | Конфигурация Bash |
Сопоставление параметров путей инструментов
| Инструмент | Извлекаемый параметр пути | Тип операции |
|---|---|---|
Read | path, file_path | read |
Write | path, file_path | write |
Edit | path, file_path | write |
ListDir | path, dir_path | read |
Извлечение путей из команд
checkCommand() извлекает пути из shell-команд и проверяет каждый из них:
- Абсолютные пути Windows:
C:\path\to\file - Абсолютные пути POSIX:
/path/to/file
Уровень 2: GuardianAgent
GuardianAgent использует LLM для оценки рисков безопасности вызовов инструментов.
Интерфейс
class GuardianAgent {
constructor(
config: GuardianAgentConfig,
llmAdapter: TinyElfLLMAdapter,
auditLogger?: AuditLogger,
sessionId?: string,
workspacePath?: string,
);
review(toolName: string, args: Record<string, unknown>): Promise<GuardianReviewResult>;
clearCache(): void;
}
interface GuardianReviewResult {
allowed: boolean;
riskLevel: RiskLevel; // 'none' | 'low' | 'medium' | 'high' | 'critical'
reason: string;
cached: boolean;
}
Режимы работы
| Режим | Область проверки | Условие блокировки | Поведение при тайм-ауте/ошибке |
|---|---|---|---|
off | Нет | Блокировки нет | N/A |
monitor | Чувствительные инструменты | Блокировки нет (только логирование) | Fail open (разрешить) |
guard | Чувствительные инструменты | high, critical | Fail open (разрешить) |
strict | Все инструменты | medium, high, critical | Fail closed (запретить) |
Список чувствительных инструментов
const SENSITIVE_TOOLS = new Set(['Bash', 'Write', 'Edit', 'Agent']);
Режимы monitor и guard проверяют только эти инструменты. Режим strict проверяет все инструменты.
Уровни риска
| Уровень | Значение | Пример |
|---|---|---|
none | Полностью безопасно | Чтение файлов внутри рабочей области |
low | Низкий риск | Запись файлов проекта |
medium | Средний риск | Установка пакетов, изменение состояния |
high | Высокий риск | Операции вне рабочей области, сетевые запросы, доступ к учётным данным |
critical | Критический риск | Рекурсивное удаление, повышение привилегий, кража данных |
Ключевые правила (всегда помечаются как high/critical)
- Удаление файлов вне рабочей области
- Команды рекурсивного удаления (
rm -rf,del /s /q,Remove-Item -Recurse) - Операции с системными каталогами (
/etc,C:\Windows) - Операции с личными каталогами пользователя (Desktop, Documents)
- Повышение привилегий (
sudo,runas) - Конвейерное выполнение (
curl | sh) - Обход проверок безопасности (
--no-verify,--force) - Доступ к учётным данным
Стратегия кэширования
- Результаты одобрения кэшируются (ключ по первым 16 битам
sha256(toolName:args)) - Кэшируются только разрешающие результаты (запрещающие результаты каждый раз оцениваются заново)
- Кэш очищается в конце сессии
Константы
| Константа | Значение | Описание |
|---|---|---|
GUARDIAN_TIMEOUT_MS | 15,000 | Тайм-аут оценки LLM |
Уровень 3: PermissionCallback
TinyElfPermissionManager
class TinyElfPermissionManager {
resolvePermission(requestId: string, result: PermissionResult): void;
cleanupSession(dbSessionId: string): void;
requestPermission(dbSessionId, sender, toolName, toolInput): Promise<PermissionResult>;
buildPermissionCallback(dbSessionId, sender, permissionMode, channelCtx, channelPermissionGate):
((toolName, toolInput) => Promise<PermissionResult>) | undefined;
}
interface PermissionResult {
behavior: 'allow' | 'deny' | 'allowSession';
message?: string;
}
Поведение режимов разрешений
| Режим | Что возвращает buildPermissionCallback |
|---|---|
bypassPermissions | undefined (callback не внедряется, все инструменты проходят автоматически) |
default | Desktop callback / Channel callback |
acceptEdits | То же, что default, но Write/Edit возвращают false в isSensitiveTool |
Белый список на уровне сессии
Когда пользователь выбирает allowSession:
sessionAllowedTools: Map<string, Set<string>> // dbSessionId → Set<toolName>
Последующие вызовы с тем же именем инструмента проходят автоматически. Белый список очищается в cleanupSession().
Тайм-аут
- Режим Desktop: тайм-аут 5 минут → автоматический отказ
- Режим Channel: тайм-аут 5 минут → автоматический отказ
ChannelPermissionGate
Подтверждение разрешений в сценариях Channel реализовано через маршрутизацию сообщений.
Поток подтверждения
sequenceDiagram
participant A as TinyElfAgentLoop
participant G as ChannelPermissionGate
participant C as Channel (Discord/Telegram)
participant U as Channel User
A->>G: requestConfirmation(channelId, chatId, senderId, toolName, desc)
G->>G: Check always-allow list
alt Already in always-allow
G-->>A: true
else Not in list
G->>C: sendMessage("Confirmation needed: Bash: npm test")
C->>U: Display confirmation message
U->>C: Reply "y" / "n" / "always"
C->>G: processReply(channelId, chatId, senderId, "y")
G-->>A: true / false
end
Область действия отпечатка
Область действия ответа always определяется buildToolFingerprint():
fingerprint = `${toolName}:${description.slice(0, 120)}`
Например, Bash:npm test и Bash:rm -rf / — разные отпечатки, требующие отдельной авторизации.
Константы
| Константа | Значение | Описание |
|---|---|---|
MAX_PENDING | 5 | Максимум ожидающих подтверждений на Channel |
TIMEOUT_MS | 300,000 | Тайм-аут подтверждения (5 минут) |
Разбор ответов
Поддерживаемые ответы подтверждения (без учёта регистра, с автоматическим удалением упоминаний Discord и т. п.):
| Ответ | Поведение |
|---|---|
| y, yes, approve, ok, 确认, はい | Разрешить |
| n, no, deny, cancel, 拒绝, いいえ | Запретить |
| always, always allow, 始终允许, 常に許可 | Разрешить + добавить в список always |
AuditLogger
Все события безопасности записываются в таблицу базы данных audit_log.
Типы событий
type AuditEventType =
| 'firewall_block'
| 'permission_denied'
| 'permission_granted'
| 'permission_timeout'
| 'rate_limited'
| 'role_changed'
| 'user_created'
| 'user_deleted'
| 'injection_detected'
| 'command_blocked'
| 'guardian_review'
| 'prompt_review';
type AuditSeverity = 'info' | 'warn' | 'critical';
Стратегия записи
- Fire-and-forget: асинхронная запись, не блокирует основной поток
- Ошибки записи обрабатываются без вывода пользователю (
console.warn) и не влияют на выполнение инструмента
Ключевые файлы
| Файл | Путь | Описание |
|---|---|---|
| ExecutionFirewall | platform/security/ExecutionFirewall.ts | Файрвол путей |
| GuardianAgent | platform/security/GuardianAgent.ts | AI-оценка безопасности |
| AuditLogger | platform/security/AuditLogger.ts | Аудит-логирование |
| ChannelPermissionGate | platform/security/ChannelPermissionGate.ts | Шлюз разрешений Channel |
| InputSanitizer | platform/security/InputSanitizer.ts | Санитизация ввода |
| PromptGuardian | platform/security/PromptGuardian.ts | Обнаружение prompt injection |
| RateLimiter | platform/security/RateLimiter.ts | Ограничение частоты запросов |
| UserPermissionService | platform/security/UserPermissionService.ts | Разрешения ролей пользователей |
| TinyElfPermissions | agent-core/engine/tinyelf/TinyElfPermissions.ts | Менеджер разрешений |
Все пути указаны относительно packages/desktop/app/main/services/.
Точки расширения
- Пользовательские запрещённые пути: добавьте правила в массив
SYSTEM_DENIED_PATHS - Пользовательский системный промпт Guardian: измените константу
SYSTEM_PROMPT - Пользовательские события аудита: добавьте новые типы в
AuditEventType - Пользовательские ответы Channel: расширьте сопоставление regex в
processReply
Связанные модули
| Модуль | Путь | Связь |
|---|---|---|
| TinyElfAgentLoop | agent-core/engine/tinyelf/TinyElfAgentLoop.ts | Вызывающий компонент конвейера безопасности |
| TinyElfSessionRunner | agent-core/engine/tinyelf/TinyElfSessionRunner.ts | Создание экземпляров Firewall/Guardian |
| ShellTool | agent-core/engine/tinyelf/tools/ShellTool.ts | Встроенный чёрный список команд |
| TinyElfLLMAdapter | agent-core/engine/tinyelf/TinyElfLLMAdapter.ts | LLM, используемая Guardian |