
Самостоятельно размещаемая платформа анализа угроз — агрегация фидов, ИИ-триаж, покрытие MITRE ATT&CK и разработка правил обнаружения с интеграцией Sentinel. Работает автономно или с полной интеграцией с Azure.
Самостоятельно размещаемая платформа киберразведки, которая агрегирует RSS-каналы от более чем 60 поставщиков решений безопасности, выполняет AI-триаж, сопоставляет находки с вашим инвентарём активов RunZero и выводит практически применимые оповещения через веб-панель в тёмной теме.
Создана для работы автономно с нулевой зависимостью от облака или полностью интегрированной в среду Azure/Entra/Sentinel — выберите уровень, соответствующий вашим возможностям.
| Уровень | Скрипт | AI-триаж | Аутентификация | Хранилище | Что вы получаете |
|---|---|---|---|---|---|
| Basic | scripts/setup-basic.sh | Выкл. | Локальный API-ключ | Локальный Postgres (Docker) | Агрегация каналов, извлечение IOC, матрица MITRE, панели мониторинга — без AI, без облака, без необходимости где-либо регистрироваться |
| Basic + API | scripts/setup-basic-api.sh | Anthropic (напрямую) | Локальный API-ключ | Локальный Postgres (Docker) | Всё вышеперечисленное плюс AI-триаж критичности/TTP/сводок |
| Azure + API | scripts/setup-azure.ps1 | Azure AI Foundry | Microsoft Entra ID SSO | Ваш собственный Postgres (Azure DB for PostgreSQL и т. д.) | Полное развёртывание в Azure Container Apps, SSO с ролями для каждого пользователя. (Интеграция с конвейером detections.ai появится в будущем релизе — см. ниже.) |
Все три уровня запускают один и тот же код приложения — меняется только набор заданных переменных окружения. Полный справочник см. в разделе Переменные окружения.```bash
./scripts/setup-basic.sh
./scripts/setup-basic-api.sh
./scripts/setup-azure.ps1
Два bash-скрипта поднимают локальный контейнер Postgres, применяют схему и генерируют `backend/.env` / `frontend/.env.local` для вас — затем выводят две команды для фактического запуска приложения (`pip install` + запуск бэкенда, `npm install` + запуск dev-сервера фронтенда). `setup-azure.ps1` — это тонкая обёртка вокруг `infra/provision.ps1`, настоящего runbook развёртывания Azure Container Apps.
---
## Возможности
- **Агрегация фидов** — опрашивает 60+ RSS-фидов безопасности уровней Tier 1/2/3 по расписанию; автоматически дедуплицирует и фильтрует промо-контент
- **AI-триаж** — классифицирует каждую запись по уровню серьёзности (Critical/High/Medium/Low/Informational), TTP-техникам MITRE ATT&CK и даёт краткое описание на простом языке. Модульность провайдера: прямой Anthropic API или Azure AI Foundry, переключается одной переменной окружения без потери функциональности в любом случае
- **Извлечение IOC** — автоматически извлекает IP-адреса, домены, URL-адреса, хеши файлов и CVE из каждой записи
- **Интеграция с RunZero** — синхронизирует ваш инвентарь активов и сопоставляет threat intel с реальными активами; совпадения по CVE, названиям ПО, версиям ОС и IP-адресам. Три подвкладки в разделе `RUNZERO`: **Matches** (записи, сопоставленные с вашим инвентарём, с фильтрацией по серьёзности/дате/уверенности/KEV), **Exposure** (подтверждённое/возможное положение на уровне организации с отслеживанием устранения) и **Metrics** (тренды поступления против устранения во времени)
- **Your Stack** — определите ПО/ОС в вашей среде; все записи переоцениваются по релевантности
- **Реестр IOC** — доступный для поиска реестр всех извлечённых индикаторов с перекрёстными ссылками на записи и экспортом в STIX/CSV
- **Матрица MITRE ATT&CK** — тепловая карта покрытия TTP по всему загруженному threat intel
- **Дашборд состояния фидов** — статус опроса по каждому фиду, отслеживание последовательных сбоев и объём статей за 7 дней
- **Detections** — поверхность проверки из 9 вкладок (см. ниже), охватывающая всё, что зарегистрировано как детекция: сгенерированное ИИ, импортированное из ваших собственных файлов или синхронизированное из живого рабочего пространства Sentinel
- **Модульная аутентификация** — Microsoft Entra ID SSO с доступом на основе ролей или единый общий локальный API-ключ без какой-либо зависимости от Azure. Автоматически определяется фронтендом; см. [Режимы аутентификации](#auth-modes)
### Две связанные с детекциями возможности
Этот репозиторий фактически поставляет две связанные, но независимо используемые вещи под зонтиком «detections»:
1. **Вкладка `DETECTIONS`** — самодостаточная поверхность проверки, разделённая на девять подвкладок:
- **All Detections** — полный каталог зарегистрированных аналитик с фильтрацией по технике/диспозиции/состоянию проверки, каждая раскрывается до своего описания и полного KQL.
- **Defender Custom Detections** — тот же каталог, ограниченный детекциями, предназначенными для пользовательских правил обнаружения Microsoft Defender for Endpoint, а не для аналитических правил Sentinel.
- **Alignment Reviews** — всякий раз, когда аналитика детекции регистрируется против техники MITRE, AI-проверка сравнивает её фактическое покрытие с собственным описанием этой техники от MITRE. Когда оно расходится или покрывает технику лишь частично, это попадает сюда как элемент для человеческой проверки с обоснованием ИИ, предлагаемым исправлением KQL и собственным результатом валидации этого исправления (статический гейт + бэктест) — никогда не слепое предложение.
- **Disposition Alerts** — очередь обнаружения загнивания: одобренная аналитика, чья телеметрия угасает или чьё лежащее в основе правило начинает выдавать ошибки, помечается здесь для повторной проверки, с именем по собственной детекции, а не только по общей технике MITRE.
- **Generated Hunts** — детекции группируются в охоты (сегодня по одной на импортированный файл; по одной на исходную статью TI/проект detections.ai, когда эта интеграция появится), что соответствует собственной функции Hunts в Microsoft Sentinel. Охота может быть синхронизирована в реальное рабочее пространство Sentinel как объект `Microsoft.SecurityInsights/hunts` плюс составляющие его запросы сохранённого поиска (ограничено `SENTINEL_HUNTING_SYNC_ENABLED` и `mode` — off/manual/auto — настраиваемым для каждой команды в Settings > API Settings; никогда не молчаливый автопуш, если вы не согласитесь).
- **Sentinel Hunts** — живой инвентарь того, что фактически развёрнуто в функции Hunting вашего рабочего пространства Sentinel, полученный напрямую из ARM, а не из собственной истории синхронизации этого приложения; включает предложения по тестированию/настройке для каждого запроса, которые можно применить или отклонить на месте.
- **Sentinel Analytics Rules** — та же идея для Analytics Rules Microsoft Sentinel (`Microsoft.SecurityInsights/alertRules`) — отдельный тип ресурса Sentinel, отличный от Hunting, поскольку именно они фактически порождают инциденты/оповещения по расписанию — с тем же рабочим процессом применения/отклонения предложений по настройке.
- **Local Detections** — см. [Работа без Sentinel или AI-провайдера](#running-without-sentinel-or-an-ai-provider-local-detections-import) ниже.
- **Audit Log** (только для администраторов) — сквозная запись по всем конвейерам обо всех проверках, которые это приложение фактически выполняло: результаты гейта/контрольного зонда для AI-сгенерированных детекций, попытки синхронизации охот Sentinel и тестовые запуски запросов охот/аналитических правил Sentinel, объединённые в один пагинированный список с фильтрацией — намеренно охватывающий то, чего не делает ни одна отдельная вкладка проверки сама по себе.
Работает полностью внутри основного бэкенда, дополнительное развёртывание для самой поверхности проверки не требуется. Дизайн её собственного API намеренно следует соглашениям detections.ai, описанным ниже, хотя она полностью самодостаточна.
2. **Оркестратор конвейера detections.ai — скоро.** У detections.ai в разработке публичный API для AI-ассистированной генерации детекций, и в этом репозитории для него построена реальная интеграция (`backend/detection_pipeline/orchestrator.py`), которая берёт прошедший триаж threat intel, проверяет его против существующего покрытия детекций и генерирует черновики KQL для вашего рабочего пространства Sentinel как запланированную задачу. Эта интеграция будет поддерживать тот API, когда он станет доступен, и пока не является частью этого публичного релиза. Тем временем **она вам вообще не нужна для использования вкладки Detections** — [Local Detections Import](#running-without-sentinel-or-an-ai-provider-local-detections-import) ниже покрывает ту же цель «получить реальные детекции в это приложение» для конфигураций без AI-генерации и без Sentinel уже сегодня.
### Работа без Sentinel или AI-провайдера: Local Detections Import
Учитывая название приложения и его основной питч, самый частый вопрос от самостоятельного хостера на тарифе **Basic**, вероятно, будет таким: *«У меня не настроен Sentinel или AI-провайдер — смогу ли я всё ещё получить что-то полезное из вкладок Detections/Hunts?»* Ответ — да: укажите приложению папку с вашими собственными файлами правил обнаружения (написанными вручную, экспортированными из реального тенанта Sentinel/Defender или взятыми из публичного репозитория правил Sigma/Sentinel), и оно каталогизирует, проставит теги MITRE и статически провалидирует их — для всего этого не требуется ни подключение к Sentinel, ни ключ `DETECTIONS_AI_API_KEY`/Anthropic.
- **Поддерживаемые форматы, с первого дня:** необработанные файлы `.kql`/`.txt`/`.yar`/`.spl`-или-с-любым-расширением, каждый опционально в паре с сайдкаром `.json`/`.yaml` (`{"file": "myrule.kql", "title": "...", "description": "...", "technique_id": "T1059.001"}`) для метаданных, которые собственному экспорту Microsoft не нужно объявлять отдельно; YARA; Suricata; Sigma YAML (одно- или многодокументный); Splunk SPL; и собственный нативный экспортированный JSON Analytics Rule/Hunting Query от Microsoft (только правила вида `Scheduled` несут необработанный KQL-запрос, который это приложение может оценить — все остальные виды распознаются и сообщаются, а не молча пропускаются).
- **Что фактически выполняется для импортированного файла:** статическая валидация (тот же движок устойчивости/находок, который использует путь AI-генерации) для KQL-содержимого; проверка соответствия MITRE тоже, если у вас *есть* настроенный AI-провайдер (независимая ось от Sentinel — у вас может быть одна, обе или ни одной); всё, зависящее от Sentinel (бэктестинг, телеметрические зонды, отслеживание диспозиции), остаётся вне области и отображается как «no Sentinel connection configured», а не как вводящая в заблуждение пустая ячейка.
- **Где это появляется:** импортированное содержимое становится обычной строкой охоты/детекции — те же таблицы, тот же рабочий процесс проверки, то же отображение техники MITRE, что и у всего, что генерирует AI-конвейер — поэтому оно появляется и в обычных представлениях `ALL DETECTIONS`/`GENERATED HUNTS`, а не только на своей вкладке. Специальная подвкладка **Local Detections** (в разделе `DETECTIONS`, запуск импорта только для администраторов) — это место, где вы указываете на папку и наблюдаете прогресс/результаты по каждому файлу.
- **Настройка:** задайте `LOCAL_IMPORT_DIR` как абсолютный путь в файловой системе бэкенда (смонтированный том при контейнерном развёртывании) — всё импортируемое должно находиться под этим корнем; UI позволяет выбрать подпуть под ним, но никогда произвольное место в файловой системе. См. [Переменные окружения](#environment-variables).
- **Попробуйте сразу:** `examples/local-detections-samples/` поставляется с небольшой готовой к импорту папкой — два валидных правила KQL (одно в паре с сайдкаром `.json`, чтобы показать этот механизм), одно намеренно невалидное правило (чтобы увидеть баннер flagged-invalid) и один нераспознанный файл (чтобы увидеть баннер failed-import). Укажите `LOCAL_IMPORT_DIR` на неё, чтобы увидеть все три состояния результата уже при первом импорте, без необходимости писать правила.
**Local Detections** — завершённый запуск импорта: сводный баннер выделяет файлы, которые были каталогизированы, но помечены невалидными статическим анализом (здесь — правило, которое срабатывает по одному жёстко заданному хешу), прямо рядом с теми, что импортировались чисто, и каждый файл становится обычной строкой охоты/детекции ниже

---
## Скриншоты
Все скриншоты ниже используют синтетические данные (фальшивые названия организаций, примерные IP-адреса RFC 5737, домены `.example`), сгенерированные для документации — никакого реального threat intel или данных клиентов.
**Feed** — просмотр и фильтрация прошедших триаж записей threat intel по серьёзности, тегам, IOC и TTP

<br>
**Dashboard** — разбивка по серьёзности с первого взгляда и топ-техники MITRE ATT&CK

<br>
**MITRE ATT&CK** — полная тепловая карта матрицы покрытия техник по загруженному intel

<br>
**Your Stack** — определите вашу среду; записи фида переоцениваются по релевантности

<br>
**IOCs** — доступный для поиска реестр всех извлечённых индикаторов с экспортом в STIX/CSV

<br>
**Integrations** — обзор коннекторов для Sentinel, Defender и RunZero: статус настроено/включено и ярлыки в собственную вкладку каждого

<br>
**RunZero** — корреляция активов, отслеживание экспозиции на уровне организации и метрики устранения, всё из вашего инвентаря RunZero

<br>
**Exposure** — организации, ранжированные по числу совпадений угроз; нажмите на любую карточку, чтобы увидеть совпавшие записи

<br>
**Detections** — полный каталог зарегистрированных аналитик (как AI-сгенерированных, так и локально импортированных), каждая со своим статусом статического гейта/бэктеста/проверки и техникой MITRE

<br>
**Settings** — управление AI-триажем, мониторинг состояния фидов, оценки доверия к источникам и управление пользователями

---
## Архитектура```
┌─────────────────────────────────────────┐
│ Next.js 16 frontend (port 3000) │
│ Tailwind CSS · dark theme │
└──────────────┬──────────────────────────┘
│ REST API (Bearer token)
┌──────────────▼──────────────────────────┐
│ FastAPI backend (port 8000) │
│ APScheduler · slowapi rate limiting │
└──┬──────────┬──────────┬────────────┬───┘
│ │ │ │
Postgres AI provider RunZero API detections.ai
(modular: (asset sync) (coming soon --
Anthropic or see Features below)
Azure AI Foundry)
Backend (backend/) — Python 3.12 + FastAPI. Postgres для всего хранилища (SQLite и Azure Blob Storage полностью выведены из эксплуатации). AI-провайдер и метод аутентификации выбираются через переменные окружения, а не жёстко заданы — см. ниже.
Frontend (frontend/) — Next.js 16, чистый JavaScript, Tailwind CSS. Автоматически определяет режим аутентификации из backend при загрузке.
Infra (infra/) — шаблоны Azure Bicep для Container Apps, Key Vault и Container Registry (apps.bicep + platform.bicep + app-stack.bicep, развёртываются через provision.ps1). Актуально только для тарифа Azure + API.
AZURE_AD_TENANT_ID задан → режим Entra: Microsoft Entra ID SSO, роли для каждого пользователя (первый вход становится администратором, все остальные по умолчанию получают роль viewer).
AZURE_AD_TENANT_ID не задан → локальный режим: единый общий LOCAL_API_KEY предоставляет административный доступ любому, у кого он есть. Без управления пользователями, без зависимости от Azure. Frontend при загрузке вызывает GET /api/auth/mode и автоматически отображает соответствующий экран входа — на стороне frontend настраивать ничего не нужно.
Оба режима впоследствии выдают одинаковый JWT, подписанный приложением, поэтому все остальные маршруты (require_auth/require_admin) работают одинаково независимо от того, какой режим выдал токен.
Запустите scripts/setup-basic.sh или scripts/setup-basic-api.sh (см. Тарифы развёртывания) — они сами настроят Postgres и сгенерируют .env. Затем:```bash
cd backend && pip install -r requirements.txt && uvicorn main:app --reload --port 8000
cd frontend && npm install && npm run dev
### Ручная настройка```bash
cd backend
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp env.example .env # fill in required values — see Environment Variables below
uvicorn main:app --reload --port 8000
git clone https://github.com/offsec-ai/ReconRaptor.git
cd ReconRaptor
pip install -r requirements.txt
cp config/config.example.yaml config/config.yaml
# Отредактируйте config/config.yaml и добавьте свои API-ключи
python reconraptor.py --help
Выполните базовое разведывательное сканирование целевого домена:
python reconraptor.py -d example.com
Запустите комплексное сканирование со всеми модулями:
python reconraptor.py -d example.com --full-scan
Обработайте несколько доменов из файла:
python reconraptor.py -f targets.txt --output results/
| Параметр | Описание |
|---|---|
-d, --domain | Целевой домен для сканирования |
-f, --file | Файл, содержащий список целевых доменов |
-o, --output | Каталог вывода для результатов |
--full-scan | Запустить все доступные модули разведки |
--passive | Только пассивная разведка (без прямого взаимодействия) |
--threads | Количество одновременных потоков (по умолчанию: 10) |
--timeout | Тайм-аут запроса в секундах (по умолчанию: 30) |
--verbose | Включить подробное логирование |
--config | Путь к файлу конфигурации |
Собирает информацию о DNS-записях, включая записи A, AAAA, MX, NS, TXT и CNAME.
python reconraptor.py -d example.com --modules dns
Обнаруживает поддомены с использованием нескольких методов, включая перебор, сертификаты прозрачности и пассивный DNS.
python reconraptor.py -d example.com --modules subdomain
Выполняет сканирование портов и определение сервисов на обнаруженных хостах.
python reconraptor.py -d example.com --modules portscan
Собирает информацию о веб-технологиях, заголовках и потенциальных точках входа.
python reconraptor.py -d example.com --modules web
Собирает информацию из общедоступных источников, включая социальные сети и публичные базы данных.
python reconraptor.py -d example.com --modules osint
Инструмент использует файл конфигурации YAML для настройки API-ключей и параметров модулей.
# config/config.yaml
api_keys:
shodan: "YOUR_SHODAN_API_KEY"
virustotal: "YOUR_VIRUSTOTAL_API_KEY"
censys:
api_id: "YOUR_CENSYS_API_ID"
secret: "YOUR_CENSYS_SECRET"
scanning:
threads: 10
timeout: 30
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
modules:
dns:
enabled: true
resolvers:
- "8.8.8.8"
- "1.1.1.1"
subdomain:
enabled: true
wordlist: "wordlists/subdomains.txt"
portscan:
enabled: true
ports: "1-1000"
web:
enabled: true
follow_redirects: true
osint:
enabled: true
sources:
- "github"
- "twitter"
- "linkedin"
Результаты сохраняются в указанном выходном каталоге в нескольких форматах:
results.json — Структурированные результаты в формате JSONresults.csv — Результаты в табличном форматеreport.html — Интерактивный HTML-отчётraw/ — Необработанные выходные данные из каждого модуля{
"target": "example.com",
"timestamp": "2024-01-15T10:30:00Z",
"dns": {
"a_records": ["93.184.216.34"],
"mx_records": ["mail.example.com"],
"ns_records": ["ns1.example.com", "ns2.example.com"]
},
"subdomains": [
"www.example.com",
"mail.example.com",
"api.example.com"
],
"open_ports": [
{"port": 80, "service": "http", "state": "open"},
{"port": 443, "service": "https", "state": "open"}
]
}
``````bash
cd frontend
npm install
cp env.local.example .env.local # set NEXT_PUBLIC_API_URL=http://localhost:8000
npm run dev
cp backend/env.example backend/.env # fill in required values docker compose up --build
Frontend → http://localhost:3000
Backend API docs → http://localhost:8000/docs
---
## Переменные окружения
Скопируйте `backend/env.example` в `backend/.env` и заполните. Сгруппированы по тому, какому уровню они нужны:
**Всегда обязательные:**
| Переменная | Описание |
|----------|-------------|
| `PG_DSN` | Строка подключения к Postgres |
| `JWT_SECRET_KEY` | Секрет для подписи токенов сессии приложения (`python -c "import secrets; print(secrets.token_hex(32))"`) |
**Аутентификация — выберите один режим:**
| Переменная | Описание |
|----------|-------------|
| `LOCAL_API_KEY` | Локальный режим: общий ключ, предоставляющий доступ администратора. Оставьте `AZURE_AD_TENANT_ID` незаданным, чтобы активировать этот режим |
| `AZURE_AD_TENANT_ID` | Режим Entra: ID тенанта для SSO. Установка этого значения активирует режим Entra |
| `AZURE_AD_CLIENT_ID` | Режим Entra: client ID регистрации приложения |
| `AZURE_AD_CLIENT_SECRET` | Режим Entra: секрет регистрации приложения (только фронтенд) |
| `NEXTAUTH_SECRET` | Режим Entra: секрет шифрования сессии NextAuth (только фронтенд) |
**AI-триаж — опционально, выберите одного провайдера (пропустите оба, чтобы работать с отключённым триажем):**
| Переменная | Описание |
|----------|-------------|
| `AI_PROVIDER` | `anthropic` (по умолчанию) или `azure` |
| `ANTHROPIC_API_KEY` | Прямой API-ключ Anthropic |
| `AZURE_FOUNDRY_ENDPOINT` | Эндпоинт Azure AI Foundry, например `https://<resource>.services.ai.azure.com/anthropic` |
| `AZURE_FOUNDRY_API_KEY` | API-ключ Azure AI Foundry |
| `AZURE_FOUNDRY_DEPLOYMENT` | Имя развёртывания Foundry (по умолчанию `claude-haiku-4-5`) |
| `AZURE_FOUNDRY_API_VERSION` | Версия API Foundry (по умолчанию `2025-05-01`) |
**Опциональные:**
| Переменная | Описание |
|----------|-------------|
| `RUNZERO_API_TOKEN` | Включает синхронизацию и корреляцию активов RunZero |
| `ALLOWED_ORIGINS` | Разделённый запятыми список разрешённых источников CORS (по умолчанию `http://localhost:3000`) |
| `ENABLE_SCHEDULER` | Установите `false`, чтобы отключить фоновый опрос фидов (по умолчанию `true`) |
| `ARCHIVE_AFTER_DAYS` | Порог автоархивации в днях (по умолчанию `90`) |
| `PG_POOL_MIN` / `PG_POOL_MAX` / `PG_POOL_TIMEOUT` | Настройка пула подключений Postgres (по умолчанию `1` / `10` / `30`) |
| `LOCAL_IMPORT_DIR` | Включает [Local Detections Import](#running-without-sentinel-or-an-ai-provider-local-detections-import) — абсолютный путь в файловой системе бэкенда, которым ограничивается каждый импорт. Если не задано, функция полностью отключается (её вкладка показывает сообщение "not configured") |
**Фронтенд** (`frontend/.env.local` или `frontend/env.local.example`):
| Переменная | Описание |
|----------|-------------|
| `NEXT_PUBLIC_API_URL` | URL бэкенда, как его видит браузер. Встраивается в JS-бандл во время сборки. Оставьте **незаданным**, чтобы направлять API-вызовы через встроенный same-origin прокси (`frontend/pages/api/[...proxy].js`) — требуется всякий раз, когда у бэкенда нет публичного ingress (например, внутренний Container App уровня Azure + API) |
| `BACKEND_URL` | URL бэкенда, как его видит сам сервер Next.js. Используется обменом при входе NextAuth и, когда `NEXT_PUBLIC_API_URL` не задан, same-origin прокси, который перенаправляет каждый браузерный запрос `/api/*` на стороне сервера |
**Оркестратор detections.ai — скоро** (пока не является частью этого публичного релиза; задокументирован здесь на случай его выпуска. Уровень Azure + API, отдельное развёртывание — см. `backend/detection_pipeline/orchestrator.py`):
| Переменная | Описание |
|----------|-------------|
| `DETECTIONS_AI_API_KEY` | Требуется для запуска оркестратора вообще |
| `SENTINEL_WORKSPACE_ID` | Customer ID рабочей области Log Analytics (GUID), для бэктестинга. Опционально |
| `PIPELINE_BATCH_SIZE` | Записей за запуск (по умолчанию `5`) |
| `PIPELINE_DRY_RUN` | `true`, чтобы забирать и логировать без вызова API |
| `PIPELINE_LANGUAGE` | Язык запросов детекций (по умолчанию `kql`) |
**Синхронизация Sentinel Hunts** (опционально, по умолчанию выключена — см. Settings > API Settings для режима on/off/manual/auto):
| Переменная | Описание |
|----------|-------------|
| `SENTINEL_HUNTING_SYNC_ENABLED` | `true`, чтобы вообще разрешить любую попытку синхронизации hunt. Незаданное/false — чистый no-op, ноль вызовов ARM |
| `AZURE_SUBSCRIPTION_ID` | Подписка, содержащая рабочую область Sentinel |
| `AZURE_RESOURCE_GROUP` | Группа ресурсов, содержащая рабочую область Sentinel |
| `SENTINEL_WORKSPACE_NAME` | **Имя** рабочей области, а не её customer ID — другое значение, чем `SENTINEL_WORKSPACE_ID` выше, который вместо этого использует клиент плоскости данных для бэктестинга |
---
## Развёртывание в Azure
Реальный, актуальный IaC — это `infra/apps.bicep` + `infra/platform.bicep` + `infra/app-stack.bicep`, развёртываемый через `infra/provision.ps1` (или тонкую обёртку `scripts/setup-azure.ps1`). Он провизионит Container Apps, секреты на базе Key Vault и управляемые идентичности — сам Postgres этим репозиторием не провизионится; укажите `PG_DSN` (хранится как секрет Key Vault `pg-dsn`) на любой доступный сервер Postgres.```powershell
./scripts/setup-azure.ps1
# or directly:
cd infra
cp migration.psd1.example migration.psd1 # fill in your resource group, apps, etc.
./provision.ps1
provision.ps1 идемпотентен — его можно безопасно перезапускать после редактирования манифеста. Полное пошаговое описание (платформа → стек приложений → секреты → Easy Auth → импорт образов → приложения → пост-проверки) см. в комментарии в его заголовке.
Оркестратор detections.ai (запланированное задание Container Apps Job, управляемое блоком Orchestrator в migration.psd1 — форму см. в migration.psd1.example, а свой ключ сохраните как секрет Key Vault DETECTIONSAIAPIKEY) пока не входит в этот публичный релиз — см. Две функции, связанные с detections выше.
├── backend/ │ ├── main.py # FastAPI app, all endpoints │ ├── db.py # Postgres queries │ ├── pgcompat.py # connection pool + SQLite-style placeholder translation │ ├── feed_manager.py # RSS polling, AI triage (provider-modular), scheduler │ ├── enrichment.py # IOC extraction, KEV cache, stack rematch │ ├── runzero_sync.py # RunZero asset sync and correlation engine │ ├── dedup.py # CVE deduplication logic │ ├── auth.py # Entra ID SSO + local API-key auth, app JWT sign/verify │ ├── ioc_export.py # STIX 2.1 and CSV export │ ├── stack_presets.py # Pre-built tech stack templates │ ├── detection_pipeline/ # detections.ai orchestrator, MITRE alignment-check, │ │ # Sentinel hunts/analytics-rules sync + tuning, │ │ # audit log, local_import.py (Local Detections Import) │ └── tests/ # pytest test suite, incl. fixtures/local_import/ ├── frontend/ │ ├── pages/ │ │ ├── index.js # Main app shell + tab routing │ │ └── login.js # Entra ID or local API-key login, auto-detected │ ├── lib/ │ │ ├── authMode.js # GET /api/auth/mode, cached per page load │ │ ├── authFetch.js # Bearer auth + 401-retry wrapper │ │ └── authSession.js # token storage, JWT decode/expiry helpers │ └── components/ │ ├── layout/ # TopBar, Sidebar, TabBar, TopFilterBar, TimeRangeToggle │ ├── feed/ # FeedList, FeedCard │ ├── integrations/ # IntegrationsPanel, ExposurePanel, RunZeroPanel, │ │ # RunZeroMatchesPanel, RunZeroMetricsPanel │ ├── detections/ # DetectionsPanel (tab shell) + one component per │ │ # sub-tab: DetectionsCatalogPanel, AlignmentReviewPanel, │ │ # DispositionAlertsPanel, HuntsPanel, SentinelHuntsPanel, │ │ # SentinelAnalyticsRulesPanel, LocalDetectionsPanel, │ │ # AuditPanel, plus shared TuningSuggestionBadge │ ├── settings/ # SettingsPanel, CadencePicker, SeverityCards │ └── mitre/ # MitreMatrix ├── infra/ # Azure Bicep templates + provision.ps1 ├── scripts/ # Tiered setup scripts (see Deployment tiers) └── docker-compose.yml
---
## Источники фидов
63 фида по трём уровням:
- **Уровень 1** — CISA, Cisco Talos, Fortinet Threat Signal, ESET WeLiveSecurity, Microsoft Security Blog, SentinelOne Labs, Google Project Zero, Zero Day Initiative, Check Point Research, Talos Intelligence Blog, The DFIR Report, Oracle
- **Уровень 2** — Recorded Future, Malpedia, SANS ISC, Securelist, Unit42, Proofpoint TI, Malwarebytes TI, Wiz Blog, Datadog Security Labs, ReversingLabs, Sekoia, Cyble, ANY.RUN Blog и другие
- **Уровень 3** — BleepingComputer, Krebs on Security, Schneier on Security, The Hacker News, Dark Reading, CrowdStrike Blog, Snyk, Semgrep и другие
---
## Безопасность
- Все API-эндпоинты требуют `Authorization: Bearer <token>`
- Сравнение токенов с защитой от тайминговых атак (`secrets.compare_digest`) для локального ключа аутентификации
- Параметризованный SQL повсюду — никакой интерполяции строк в запросах
- CORS ограничен явным списком разрешённых источников
- Входные данные LLM санитизируются перед вызовами AI-провайдера; выходные данные валидируются перед сохранением
- Контейнеры запускаются от имени непривилегированного пользователя со сброшенными всеми Linux-возможностями
- Никаких секретов, встроенных в образы — загружаются во время выполнения из `.env` / Azure Key Vault
---
## Лицензия
MIT — см. [LICENSE](https://github.com/ethan-andrews/threatintel-aggregator/blob/main/LICENSE).