Многоагентная среда статического анализа безопасности приложений для ИИ-агентов программирования: картографирует кодовые базы, ищет классы уязвимостей, связывает и проверяет находки, а также формирует отчёты в форматах SARIF, JSON и PDF.
Многоагентный инструмент проверки безопасности приложений для Claude Code (а позднее и для других ИИ-агентов). Один навык-маршрутизатор направляет работу в полноценный конвейер наступательной безопасности, который картирует кодовую базу, ищет уязвимости с помощью базы знаний по каждому классу, выстраивает цепочки находок в эскалации, проверяет реальное воздействие и формирует отчёты в README / JSON / SARIF / doc / PDF.
Область применения: этот инструмент выполняет статический анализ (обзор исходного кода, трассировку потоков данных, построение PoC/полезных нагрузок) для кода, которым вы владеете или который уполномочены тестировать. Он не атакует живые сторонние системы.
security-harness/ # a plugin marketplace └── plugins/security-harness/ ├── skills/ │ ├── sh-router # single entry point - routes any appsec request │ ├── sh-security-review # the pipeline orchestrator (Stages 0-5) │ └── sh-kb-* (15) # per-vuln-class knowledge bases ├── agents/ │ ├── sh-recon # map: Graft graph + stack/SBOM/CVE + attack surface │ ├── sh-hunter # find: source→sink hunting, one per class (parallel) │ ├── sh-chainer # escalate: combine findings into attack chains │ ├── sh-verifier # confirm: offensive + seceng + dev verification + PoC │ └── sh-reporter # deliver: README/JSON/SARIF/HTML/PDF/doc └── references/ # shared contracts (finding schema, SARIF map, state files, rubrics)
### Охватываемые классы уязвимостей (навыки `sh-kb-*`)
access-control (IDOR/BOLA/priv-esc) · sqli · xss · ssrf · injection (cmd/code/SSTI/LDAP) · auth (session/JWT)
· deserialization · path-traversal (LFI/RFI) · secrets · csrf · xxe · open-redirect · crypto · race-conditions
· file-upload. Зависимые CVE/SBOM обрабатываются на этапе разведки.
## Установка
Харнесс поставляется для нескольких агентов. Полные сведения об упаковке и контрольный
список релиза находятся в [`docs/DISTRIBUTION.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/docs/DISTRIBUTION.md).
**Claude Code** — добавьте этот репозиторий как маркетплейс плагинов и установите плагин:```
/plugin marketplace add dmdhrumilmistry/security-harness
/plugin install security-harness
/plugin marketplace add принимает любой из вариантов: GitHub owner/repo (как выше), полный git URL
(https://github.com/dmdhrumilmistry/security-harness.git) или локальный путь к клону
(например, /plugin marketplace add ./security-harness из каталога, содержащего вашу копию).
Затем выполните /plugin install security-harness и перезагрузите по запросу.
Gemini CLI — нативное расширение, манифест в корне репозитория:```bash gemini extensions install https://github.com/dmdhrumilmistry/security-harness
**opencode, Codex или любой агент [agentskills.io](https://agentskills.io)** — скопируйте
навыки в каталог обнаружения. Codex дополнительно подхватывает `AGENTS.md` самостоятельно:```bash
git clone https://github.com/dmdhrumilmistry/security-harness
cd security-harness
python3 scripts/sync-agent-skills.py --install agents # ~/.agents/skills
python3 scripts/sync-agent-skills.py --install opencode # ~/.config/opencode/skills
Graft устанавливается и настраивается автоматически пайплайном. Этап 0 запускает npm install -g @nanonets/graft, если он отсутствует (требуется Node/npm), затем graft init <target> --no-agents --no-global
для регистрации MCP-сервера Graft и хуков свежести для целевого репозитория. Сам граф (<target>/graft/,
автоматически добавляемый в gitignore) строится во время разведки. Для ручной предварительной установки: npm install -g @nanonets/graft. Структурная сборка Graft бесплатна и не требует API-ключа; опциональный проход LLM --deep использует GRAFT_API_KEY /
GRAFT_PROVIDER / GRAFT_MODEL, если они заданы.
Остальные инструменты также автоматически устанавливаются Этапом 0 при их отсутствии (через любой доступный на машине менеджер пакетов — winget/choco/scoop, brew, apt, npm/pip/go — см. references/tooling-setup.md). Установки анонсируются, предпочитаются методы без повышения прав и они никогда не блокируют запуск: всё, что не удаётся установить, просто помечается как недоступное, и пайплайн переключается на резервный вариант. Этап 0 устанавливает только то, что заполняет отсутствующую группу возможностей:
syft · CVE: один из grype
(предпочтительно), trivy или osv-scannerwkhtmltopdf или pandoc (для PDF/DOCX); иначе вы получаете report.html (или PDF через headless-Chrome).Все они опциональны — пайплайн изящно деградирует до нативного поиска + разбора манифестов, если ничего не установлено.
Вызовите роутер с запросом на естественном языке:``` /sh-router full security review of ./api /sh-router find SQLi and IDOR in src/ /sh-router just map this codebase # recon only
Или вызовите конвейер напрямую:```
/sh-security-review . classes:sqli,access-control,ssrf depth:deep
/sh-security-review . stage:report # regenerate reports for the latest run
Каждый этап выполняется на модели, подобранной под его когнитивную нагрузку, поэтому токены тратятся там, где качество обнаружения действительно от них зависит, и экономятся на механической работе. Это поведение по умолчанию — аргументы не требуются.
| Этап | Модель по умолчанию |
|---|---|
| recon | sonnet |
| hunt (для каждого класса) | haiku для классов шаблонов (secrets, crypto, open-redirect, csrf) · sonnet для трассировки source→sink (sqli, xss, ssrf, injection, path-traversal, xxe, file-upload, auth) · opus для классов глубокой логики (access-control, race-conditions, deserialization) |
| chain | opus |
| verify | opus (шлюз точности — остаётся сильным) |
| report | haiku |
Переопределяется аргументом models: (также передаётся через роутер):```
/sh-security-review . # default tiered map above
/sh-security-review . models:max # every stage + hunter on opus (max quality, max cost)
/sh-security-review . models:cheap # aggressive downshift (trades some verify precision)
/sh-security-review . models:verify=opus,hunt=sonnet # per-stage overrides
/sh-security-review . models:report=sonnet,hunt.pattern=sonnet # per-hunter-tier override
Этапы: `setup, recon, hunt, chain, verify, report`. Модели: `opus, sonnet, haiku, inherit`. Для `hunt`
указание модели без уточнения сводит всех охотников к ней; `hunt.pattern` / `hunt.trace` / `hunt.logic` нацелены на один уровень.
Другие способы экономии токенов встроены: recon порождает охотников только для классов с реальной поверхностью атаки, охотники
запрашивают граф Graft вместо чтения целых файлов, а `findings.json`/SARIF генерируются
детерминированным скриптом, а не моделью.
### Вывод
Всё сохраняется в `<target>/.security-harness/<run-id>/`:
- `recon.md`, `codebase-map.json` — карта (стек, SBOM, CVE, поверхность атаки).
- `findings.jsonl` → `chains.md` → `verified.jsonl` — рабочее состояние (см. `references/state-files.md`).
- `reports/` — `README.md`, `findings.json`, `results.sarif`, `report.html`, `report.pdf` (+ `report.docx`).
Каждая опубликованная находка содержит полезную нагрузку, PoC, вердикт верификации, идентификаторы CWE/OWASP, CVSS и
митигацию на уровне кода.
## Ревью pull request
`sh-pr-review` проверяет отдельный pull request, а не всю кодовую базу, публикует
результат в виде inline-комментариев **в самом PR** и устанавливает статус коммита `security/pr-review`,
который может применяться branch protection.
**Запускайте со своей машины, на любом PR, который вы можете читать.** Установите плагин и спросите:```
review https://github.com/acme/api/pull/128
review PR 42
security review this PR
Вставьте ссылку на PR — и он проверит этот PR в том репозитории, сначала клонировав его во временный каталог, потому что охотники читают файлы, а не только патч. Ничего не записывается в репозиторий, в котором вы работаете.
Передайте просто число — и он разрешит его относительно репозитория, в котором вы сейчас находитесь, того, на который
указывает git remote. Не передавайте ничего — и он возьмёт открытый PR для вашей текущей ветки.
Фаза 7 выводит находки и вердикт и спрашивает перед тем, как что-либо опубликовать — отказ является нормальным исходом, и полезная нагрузка остаётся на диске, чтобы вы могли опубликовать её позже.
Прежде чем тратить какой-либо анализ, он проверяет, можете ли вы вообще писать в целевой репозиторий, так что проверка чужого проекта сразу сообщает вам, что публикация вернёт 403, вместо того чтобы обнаружить это через десять минут.
Три свойства делают его пригодным в качестве шлюза слияния, а не шумом:
pr_impact
со значением introduced, aggravated или pre_existing. Первые два блокируют; pre_existing
сообщается и никогда не блокирует. Блокировка слияния из-за кода, который автор никогда не писал, — это то, как
обязательная проверка оказывается удалённой, поэтому когда охотник сомневается между aggravated и
pre_existing, он должен выбрать pre_existing.sh-kb-*,
затем выбирает уровень. Уровень 0 (нет изменений, значимых для безопасности) не запускает ничего
вообще и всё равно устанавливает статус. Уровень 3 запускает полный конвейер.| Вердикт | Статус | Когда |
|---|---|---|
| fail | failure | находка introduced или aggravated на уровне --fail-on или выше (по умолчанию medium), уверенность >= 80 |
| warn | success | ничего introduced или aggravated; предсуществующие находки сообщены |
| pass | success | нет находок, или триаж остановился на уровне 0 |
| error | error | проверка не смогла завершиться |
warn сообщает success намеренно: предупреждение, которое блокирует слияние, — это провал с
лишними шагами, и команды реагируют на это удалением проверки. error держится отдельно от
failure, чтобы сломанный запуск никогда не выглядел как уязвимость, которую он не нашёл.
Событие проверки всегда COMMENT, никогда REQUEST_CHANGES или APPROVE. Статус
коммита — это механизм принуждения, и именно его читает защита ветки.
Область действия: навык пишет в pull request и статус коммита и больше никуда. Он не открывает issues и ничего не создаёт ни в одном внешнем трекере.
PR проверяется один раз на каждый push, поэтому вторая проверка должна быть дешевле первой, иначе инструмент станет тем, что люди отключают.
Дедупликация происходит до трат, а не до публикации. Отпечатки, уже имеющиеся на PR, читаются в Фазе 1 и передаются охотникам и верификатору. Обнаружение дубликата в конце означало бы, что самая дорогая модель в конвейере уже повторно подтвердила вывод, который был записан на PR всё это время. Это не требует кэша: состояние живёт в PR, поэтому оно работает на холодной машине и в CI.
Локальный кэш делает остальное инкрементальным. sh-review-cache хранит хеши файлов, находки и вердикты каждого запуска
в каталоге кэша вашей ОС (никогда в репозитории, поскольку кросс-репозиторная проверка выполняется во временном клоне, который удаляется). Следующая проверка перепроверяет только
файлы, содержимое которых действительно изменилось, переиспользует вердикты для находок, которые не изменились, и
переиспользует карту разведки, если ничего из того, что она покрывает, не сдвинулось.
Слияние базовой ветки не стоит ничего. Слияние main в ветку PR меняет head
SHA и ничего из того, что написал автор, но статус коммита привязан к SHA, поэтому обязательная
проверка молча исчезает с нового head. Когда собственные файлы PR побайтово идентичны
и дельта базы не затрагивает ничего, от чего зависят находки, предыдущий вердикт
переставляется на новый SHA вообще без запуска агентов. Именно последнее условие делает это безопасным: слияние базы, которое удаляет санитайзер, оставляет все файлы PR неизменными, при этом
превращая безопасную строку в эксплуатируемую.
Инвалидация намеренно консервативна, потому что устаревшая запись в инструменте безопасности
делает его не медленным, а неправильным. Ключ кэша хеширует каждую базу знаний sh-kb-*,
поэтому обновление KB инвалидирует каждую закэшированную находку — закэшированное «чисто» никогда не должно
подавлять находку, для поимки которой было написано это обновление. Идентичность модели, версия навыка, содержимое
файлов и TTL в 7 дней тоже инвалидируют, а неуказанная модель считается промахом.
--no-cache отключает его, --refresh-cache перебазирует, а run.md записывает по фазам
что было запущено, переиспользовано и пропущено, так что кэш, который тихо перестал попадать, виден,
а не предполагается.
Проверка и статус коммита публикуются по умолчанию. Проверка, которая была вычислена и
никогда не доставлена, никому не помогла. --confirm возвращает запрос перед публикацией, --dry-run
ничего не отправляет, --no-status публикует проверку, но оставляет статус коммита в покое.
Публикация идёт через scripts/sh-pr-post.py, а не через вручную собранные вызовы API, потому что это
многошаговая операция с обязательным хвостом: проверка, затем статус, затем квитанции, причём
422 восстанавливается перемещением комментария, а не сдвигом номера строки. Скрипт
никогда не завершается, оставляя статус в pending — если проверку не удаётся опубликовать, он всё равно
устанавливает error, сообщая, что инструментарий дал сбой, а не обвиняя PR.
Inline-комментарии зарезервированы для находок уровня medium или выше с уверенностью >= 80. Находки низкой серьёзности идут в свёрнутую секцию тела, поэтому находка низкого приоритета, появляющаяся с нулём inline-комментариев, — это работающая политика, а не сбой.
Каждый запуск записывает, во что он обошёлся, чтобы «кэш работает» и «проверки стали медленнее» перестали быть предметом мнений.```bash python3 /scripts/sh-metrics.py path # where records live python3 /scripts/sh-metrics.py report # aggregate, by model python3 /scripts/sh-metrics.py purge --older-than-days 30
Два JSONL-файла, доступных только для добавления, — `runs.jsonl` (репозиторий, PR, уровень, вердикт, итоги, переданные вами флаги) и `events.jsonl` (одна строка на фазу или агента: модель, токены, длительность, результат, был ли он переиспользован из кэша). JSONL — чтобы упавший запуск всё равно оставлял валидные строки выше места падения.
| Платформа | Метрики | Кэш |
|---|---|---|
| **Linux / BSD** | `$XDG_DATA_HOME/security-harness/metrics`<br>по умолчанию `~/.local/share/security-harness/metrics` | `$XDG_CACHE_HOME/security-harness`<br>по умолчанию `~/.cache/security-harness` |
| macOS | `~/Library/Application Support/security-harness/metrics` | `~/Library/Caches/security-harness` |
| Windows | `%LOCALAPPDATA%\security-harness\metrics` | `%LOCALAPPDATA%\security-harness\cache` |
Linux следует спецификации XDG Base Directory, поэтому оба пути учитывают `XDG_DATA_HOME` и
`XDG_CACHE_HOME`, когда они заданы, и откатываются к `~/.local/share` и `~/.cache`, когда
они не заданы. Переопределить любой из них напрямую можно с помощью `SH_METRICS_DIR` и `SH_REVIEW_CACHE_DIR`.
**О `python` против `python3`:** большинство дистрибутивов Linux поставляют `python3` и вообще не имеют
`python`, поэтому в примерах здесь используется `python3`. Входящие в комплект скрипты содержат
shebang `#!/usr/bin/env python3` и являются исполняемыми, поэтому `./scripts/sh-metrics.py report`
работает напрямую в Linux и macOS. Навык определяет
`PY="$(command -v python3 || command -v python)"` один раз за запуск, что покрывает все три
платформы, включая Git Bash в Windows.
**Строго локально.** Ни один из скриптов не содержит сетевого кода или конечной точки для отправки отчётов.
Всё, что похоже на токен, редактируется перед записью, потому что локальные файлы вставляют
в issues.
### Запуск без присмотра
Необязательно и является отдельным решением от использования навыка. Сначала запускайте его вручную на своих PR
некоторое время, чтобы вы знали, что он говорит о вашей кодовой базе, прежде чем он скажет это
перед вашей командой.
Когда вы будете готовы, раздел «Enforcing the check on a repository» в
[`references/pr-review-mapping.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/plugins/security-harness/references/pr-review-mapping.md)
содержит готовый к копированию рабочий процесс для **вашего** репозитория, а также отказоустойчивый механизм, который не даёт мёртвой задаче
оставить обязательную проверку застрявшей в состоянии `pending`.
Порог остаётся на значении по умолчанию `medium`. Ранее существовавшие находки никогда не блокируют слияние,
поэтому неотсканированная кодовая база не создаёт стену красного в первый же день — провалить проверку может только то, что PR
фактически вносит или усугубляет.
## Как это работает
1. **Настройка** — проверка доступных инструментов, определение области, создание каталога запуска.
2. **Разведка** (`sh-recon`) — построение графа Graft; определение стека/версий; SBOM + CVE; перечисление точек входа,
границ доверия и опасных стоков.
3. **Охота** (`sh-hunter` ×N, параллельно) — один охотник на каждый релевантный класс загружает свою базу знаний `sh-kb-*`,
отслеживает ввод атакующего от источника до стока и фиксирует кандидатов. Общий **журнал попыток** не даёт
агентам повторять пробы друг друга.
4. **Цепочка** (`sh-chainer`) — компоновка находок в пути атаки с более высокой серьёзностью.
5. **Проверка** (`sh-verifier`) — сначала опровержение, затем подтверждение эксплуатируемости на основе доказательств, создание PoC, назначение
CVSS и отсечение ложных срабатываний.
6. **Отчёт** (`sh-reporter`) — создание итоговых материалов.
Субагенты не разделяют ничего, кроме файлов; контракт описан в `plugins/security-harness/references/state-files.md`.
## Расширение
Добавьте новый класс уязвимостей, создав `skills/sh-kb-<class>/SKILL.md` по общему шаблону
(Когда охотиться · Источники и стоки · Рецепт обнаружения · Полезные нагрузки/PoC · Фильтры ложных срабатываний · CWE/OWASP ·
Подсказки по цепочкам · Митигация), затем добавьте его slug в перечисление `class` в `references/finding-schema.json`
и в таблицу маршрутизации в `skills/sh-router/SKILL.md`.
## Автоматические обновления базы знаний
Запланированный GitHub Action (`.github/workflows/update-knowledge-base.yml`) поддерживает базы знаний `sh-kb-*`
в актуальном состоянии. **Каждый второй день** (а также при ручном `workflow_dispatch`) он запускает агента, который дистиллирует новые,
заслуживающие доверия публичные исследования по безопасности — OWASP, PortSwigger Research, CWE/CAPEC, NIST, MDN, отобранные репозитории GitHub
и публичные раскрытия HackerOne — в небольшие, хорошо обоснованные улучшения. Затем **второй, состязательный
агент-ревьюер** сканирует получившийся diff на вредоносное/внедрённое содержимое, и PR
**автоматически сливается только если этот ревьюер одобряет**.
### Два workflow, три job
Создание PR намеренно отделено от ревью и слияния, поэтому то, что пишет
diff, никогда не является тем, что решает его выпустить.
**Этап 1 — [`update-knowledge-base.yml`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/workflows/update-knowledge-base.yml)**
(по расписанию или вручную). Один job, `create-pr`:
1. **Генерация** — агент редактирует KB из источников из белого списка. Без коммита, без push.
2. **Открытие PR** — детерминированный шаг открывает (или обновляет) PR в ветке `automated/kb-update`
с меткой `awaiting-review`.
3. **Передача** — при успешном создании PR он запускает этап 2 с номером PR.
**Этап 2 — [`kb-review-and-merge.yml`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/workflows/kb-review-and-merge.yml)**
(запускается этапом 1 или вручную для любого автоматизированного PR). Два job:
- **`review`** — *отдельный* запуск агента состязательно проверяет diff на
артефакты prompt-injection, правки вне области, секреты/эксфильтрацию, PII, оружизированные
эксплойты, источники вне белого списка или нарушения внутреннего стиля. У него **нет веба и нет
shell**, и он **отказывает безопасно**: всё подозрительное, любая неопределённость или отсутствующий
файл вердикта → REJECT. Вердикт публикуется как комментарий к PR и управляет меткой.
- **`merge`** — выполняется **только** при `APPROVE` и сливает PR. При `REJECT` он пропускается, и
job `blocked` сообщает почему.
> **Почему dispatch, а не триггер `pull_request`:** PR, открытый `GITHUB_TOKEN`,
> не запускает workflow `pull_request`. `workflow_dispatch` — одно из двух событий,
> исключённых из этой защиты от рекурсии, поэтому этап 1 может надёжно передать управление.
**Автослияние означает, что одобряющий агент попадает код в `main`.** Контроли этого:
- Job слияния отклоняет любой PR, который закрыт, из форка или чья head-ветка
находится вне `automated/*` (`ALLOWED_HEAD_PREFIX` в workflow).
- Он предпочитает собственное автослияние GitHub, поэтому **защита ветки всё ещё применяется**. При правиле
на `main`, требующем одобряющего ревью, PR встаёт в очередь и ждёт человека вместо
слияния. Он откатывается к немедленному слиянию только в репозиториях, где автослияние отключено.
- Установите вход `auto_merge` в `false` при ручном запуске, чтобы проверить без слияния.
- Промпт ревьюера сообщает агенту, что его вердикт обязателен, а не рекомендателен.
> Требуется настройка репозитория **"Allow GitHub Actions to create and approve pull requests"** (Settings →
> Actions → General → Workflow permissions), чтобы workflow мог открыть PR. Если вы хотите человека в
> цикле несмотря на автослияние, защитите `main` правилом защиты ветки, требующим pull request и как
> минимум одного одобряющего ревью — путь автослияния это учитывает.
### Подключаемые агенты
Оба этапа выполняются через [`.github/actions/ai-agent`](https://github.com/dmdhrumilmistry/security-harness/blob/main/.github/actions/ai-agent/action.yml),
составное действие, которое направляет работу тому агенту, которого вы настроите. Claude Code, OpenAI
Codex, Gemini CLI и лазейка для всего остального:
| `agent` | Запускает | Учётные данные |
|---|---|---|
| `claude` (по умолчанию) | `anthropics/claude-code-action@v1` | `CLAUDE_CODE_OAUTH_TOKEN` или `ANTHROPIC_API_KEY` |
| `codex` | `codex exec --full-auto` | `OPENAI_API_KEY` |
| `gemini` | `gemini --yolo --prompt` | `GEMINI_API_KEY` |
| `custom` | ваши `KB_AGENT_INSTALL` / `KB_AGENT_COMMAND` | всё, что ему нужно |
Выбирайте для каждого запуска из входов `workflow_dispatch` или задайте переменные репозитория, чтобы изменить
значение по умолчанию: `KB_AGENT` и `KB_MODEL` для генератора, `KB_REVIEW_AGENT` и
`KB_REVIEW_MODEL` для ревьюера. Запуск генератора и ревьюера на **разных
агентах** — значимый шаг усиления защиты: инъекция, настроенная под одну модель, с меньшей вероятностью
сработает на второй, независимой.
Для `agent: custom` задайте `KB_AGENT_COMMAND` как shell-команду. Промпт записывается в
файл, указанный в `$AGENT_PROMPT_FILE`, а `$AGENT_MODEL` несёт вход модели.
Защита от prompt-injection, поскольку генератор читает открытый веб:
- **Белый список доменов.** `WebFetch` ограничен доверенными доменами в
`.github/kb-update/trusted-sources.md` (продублировано в `--allowedTools` workflow). `WebSearch` может
обнаруживать URL, но фактически загружать можно только домены из белого списка.
- **Содержимое — это данные, а не команды.** Промпт задачи (`.github/kb-update/prompt.md`) инструктирует Claude
рассматривать каждый загруженный байт как недоверенный справочный материал и игнорировать любые инструкции, встроенные в
страницу — тела отчётов HackerOne (создаваемые пользователями) помечены как наиболее рискованный уровень.
- **Ни shell, ни push у генератора; ревьюер — это ворота.** Генератор может только редактировать файлы.
Независимый ревьюер (`.github/kb-update/review-prompt.md`) — это то, что стоит между загруженным содержимым
и `main` — ничто не сливается без его явного одобрения.
- **Разные агенты для генератора и ревьюера.** Необязательно и самая сильная версия ворот: задайте
`KB_AGENT` и `KB_REVIEW_AGENT` как два разных движка.
**Настройка:**
- Добавьте учётные данные для того агента, которого используете (Settings → Secrets and variables → Actions):
**`CLAUDE_CODE_OAUTH_TOKEN`** (по умолчанию), `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` или `GEMINI_API_KEY`.
OAuth-токен аутентифицируется по **лимитам использования вашей подписки Claude**, а не по тарифицируемому
API-ключу — сгенерируйте его локально с помощью `claude setup-token` (требуется активная подписка Claude Pro/Max)
и вставьте результат.
- Включите **"Allow GitHub Actions to create and approve pull requests"** (Settings → Actions → General →
Workflow permissions), чтобы workflow мог открыть свой PR. Рекомендуется: добавьте правило защиты ветки на `main`,
требующее PR и одобряющего ревью, чтобы никакое автоматизированное изменение не попало туда без человека даже при
включённом автослиянии.
- Чтобы изменить разрешённые источники, отредактируйте белый список в `trusted-sources.md` **и** соответствующие
записи `WebFetch(domain:...)` в workflow — держите их синхронизированными.
Каждый запуск записывает, что он сделал, в `.github/kb-update/last-run-summary.md`.
## Дорожная карта
- ~~Подключение зеркал Codex / Cursor.~~
✅ Выпущено: `AGENTS.md`, расширение Gemini CLI и `scripts/sync-agent-skills.py`
для `.agents/skills` и opencode. См. [`docs/DISTRIBUTION.md`](https://github.com/dmdhrumilmistry/security-harness/blob/main/docs/DISTRIBUTION.md).
- ~~Необязательное дополнение баз знаний живой выборкой (PortSwigger/OWASP/CWE) поверх отобранных справочников.~~
✅ Выпущено как запланированный обновлятор базы знаний выше.
- Необязательный мост DAST для подтверждения во время выполнения находок `needs-runtime`.
## Лицензия
MIT