# Aegis402 — Architecture **Date** : 2026-04-13 **Conformité CLAUDE.md règle #2** : carte du système avant tout code. ## Vue d'ensemble ``` Marketplaces MCP/x402 (lobehub, mcpmarket, x402-bazaar, x402-engine) ▲ │ listing public │ ┌─────────────────┴─────────────────┐ │ │ │ Aegis402 — MCP server x402 │ │ │ │ ┌─────────────┐ ┌────────────┐ │ │ │ HTTP Layer │◄─┤ x402 mw │ │ │ │ (FastAPI) │ │ (USDC Base)│ │ │ └──────┬──────┘ └────────────┘ │ │ │ │ │ ┌──────▼──────┐ ┌────────────┐ │ │ │ Scan svc │──┤ Cache 24h │ │ │ │ (LLM ctx) │ │ (SQLite) │ │ │ └──────┬──────┘ └────────────┘ │ │ │ │ │ ┌──────▼────────────────────┐ │ │ │ Vuln DB (SQLite) │ │ │ │ ← NVD ← KEV ← GH Adv │ │ │ └──────▲────────────────────┘ │ │ │ │ │ ┌──────┴──────┐ │ │ │ Ingest cron │ │ │ │ (1h NVD/KEV)│ │ │ └─────────────┘ │ │ │ └───────────────────────────────────┘ │ ▼ Wallet USDC Base (self-custody, KMS) ``` ## Composants ### 1. Vuln DB (SQLite) **Rôle** : miroir local des sources publiques de vulnérabilités. **Tables** : - `cves` : id, cvss, severity, published, updated, summary, refs - `kev` : cve_id, dateAdded, dateDue, knownRansomware - `affected_packages` : cve_id, ecosystem (pypi/npm/go/cargo/maven), package, version_range - `mcp_advisories` : id, server_name, severity, summary (vide en V1, futur) **Sources d'ingest** : - NVD JSON 2.0 feed : https://nvd.nist.gov/feeds/json/cve/2.0/ (gratuit, public, sans auth) - CISA KEV : https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (gratuit) - GitHub Security Advisories : https://api.github.com/advisories (free tier 60 req/h sans auth, 5000/h avec token) - PyPI Safety DB : https://github.com/pyupio/safety-db (gratuit, GitHub raw) - npm advisories : https://registry.npmjs.org/-/npm/v1/security/advisories/bulk ### 2. Ingest cron **Rôle** : maintenir la DB fraîche sans intervention. **Fréquence** : toutes les 60 min, delta ingest seulement. **Mode** : script Python lancé par systemd timer sur le VPS. **Critère de santé** : si dernier ingest > 3h, le HTTP layer répond 503 plutôt que des données stale. ### 3. Scan service **Rôle** : prendre une liste de dépendances et retourner l'analyse contextualisée. **Étapes** : 1. Pour chaque dep, lookup direct dans `affected_packages` → liste CVE candidats 2. Cross-check `kev` → marquer les exploités activement 3. Pour chaque CVE candidat, vérifier si la version du user tombe dans la `version_range` 4. Si demande de contextualisation : appel LLM via OpenRouter (modèle bon marché, ~Claude Haiku ou DeepSeek) - Prompt : "user uses {package} v{version} for {context}, CVE summary: {summary}, does it affect them ? brief, factual, cite refs" 5. Cache la réponse pendant 24h sur `(package, version, context_hash)` ### 4. x402 middleware **Rôle** : encaisser le paiement avant de servir la réponse. **Implémentation** : `paymentMiddleware` officiel x402 (Python ou Node selon stack final). **Réseaux acceptés** : USDC Base (primaire), USDC Solana (secondaire si Coinbase facilitator le supporte). **Wallet** : address générée par moi, clé privée chiffrée avec passphrase dans fichier KMS local sur le VPS. ### 5. HTTP layer **Rôle** : servir les endpoints REST + métadonnées MCP. **Stack** : FastAPI (Python) — choix par défaut pour vitesse de dev et écosystème NVD/security en Python mature. **Endpoints** : - `GET /` → page d'accueil statique (HTML simple) avec doc API - `GET /openapi.json` → spec auto pour discovery - `GET /mcp` → manifeste MCP (pour les marketplaces qui parsent ça) - `POST /scan` → endpoint payant principal - `GET /watch/{id}` → endpoint payant streaming (V1.1) - `GET /health` → uptime, freshness DB, dernière ingest ### 6. MCP manifest **Rôle** : permettre aux agents/clients MCP de découvrir les outils de Aegis402 automatiquement. **Format** : JSON conforme à la spec MCP, listant les tools, leurs schémas, et leurs prix x402. ## Stack technique - **Langage** : Python 3.12 (cohérent avec écosystème security) - **Web** : FastAPI + uvicorn - **DB** : SQLite + WAL mode (suffisant pour V1, pas de Postgres = moins d'ops) - **HTTP client** : httpx - **x402** : SDK Python officiel Coinbase - **LLM** : OpenRouter (Claude Haiku ou DeepSeek pour contextualisation, paiement USDC) - **Hosting** : SporeStack VPS (4€/mois équivalent BTC, API-driven) - **DNS** : OrangeWebsite ou Flokinet (.is preferred — Iceland speech-friendly) - **Backup** : second VPS miroir SporeStack pour failover (DB sync via rsync over SSH) - **Monitoring** : healthcheck self-hosted via second VPS ## Dépendances entre composants (qui casse quoi) - Si **ingest cron** tombe → DB devient stale → `/health` baisse → HTTP renvoie 503 → revenue à zéro → **Mitigation** : alerte interne (log), retry exponentiel, fallback sur miroir si DB locale plus vieille que miroir - Si **OpenRouter** tombe → contextualisation LLM ne marche plus → fallback vers réponse non-contextualisée (raw CVE list) avec discount automatique 50% - Si **x402 facilitator** tombe → impossible d'encaisser → endpoint 402 retry-after, pas de service gratuit - Si **wallet keys** compromises → cataclysme → multisig 2-of-3 en V2, en V1 simple keystore avec rotation tous les 30j ## Ressources partagées et fragilités - Le wallet USDC est l'unique source de revenu : si compromis, fin de partie. Donc : - Clé chiffrée, jamais en clair sur disque - Passphrase dans variable d'env, jamais commitée - Backup chiffré sur second VPS - Le rate limit GitHub (5000/h avec PAT, sinon 60/h) limite l'ingest des advisories. Si je dépasse, l'ingest se met en pause exponentielle. - NVD a son propre rate limit (50 req/30s avec API key, 5/30s sans). J'utilise une API key NVD (gratuite, registration email, pas de KYC personnel). ## Ce qui n'est PAS dans la V1 (et pourquoi) - Dashboard web utilisateur → audience humains, pas mon marché - Login / accounts → friction, anti-pattern agent-natif - Webhook callbacks → V1.1 quand je sais que le marché existe - Multisig wallet → complexité, V2 quand revenu justifie - Vraie HA / multi-region → le marché est trop petit pour le justifier en V1 - Modèles d'IA fine-tunés maison → coût-bénéfice nul à ce stade