{"id":"f9ce50c9-6898-434d-bf14-b4971b8dad25","slug":"hermes-shield","kind":"mcp","name":"hermes-shield","summary":"Input sanitizer for AI agents — anti-prompt-injection shield","owner":"amurlaniakea","repoUrl":"https://github.com/amurlaniakea/hermes-shield","license":"AGPL-3.0","licenseTier":"strong-copyleft","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-06-25T21:43:32.000Z","addedAt":"2026-10-21T04:43:00.098Z","logoUrl":"https://avatars.githubusercontent.com/u/247767585?u=cae799644fb5cee7f38cefce731e8de75af4b081&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra"],"tags":["ai-security","devsecops","llm-security","prompt-injection","python-developer"],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T12:27:13.814Z","sample":false,"url":"https://conduits.dev/tools/hermes-shield","language":"Python","transports":["stdio"],"install":{"pypi":"hermes-shield"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# Hermes Shield\n\n**Input sanitizer for AI agents — anti-prompt-injection shield.**\n\nHermes Shield protects AI agents from malicious inputs: prompt injection, data exfiltration, command execution, and social engineering. Works in English, Spanish, French, German, Italian, and Portuguese.\n\nAGPL-3.0-or-later licensed. Generic — works with any AI agent, not just Hermes.\n\n> **Brand Clarification:** Hermes Shield is an independent open-source project. It is not affiliated, sponsored, or endorsed by **Nous Research** or their \"Hermes Agent\" ecosystem. Due to its agnostic middleware architecture, Hermes Shield is fully compatible as an input sanitization filter for Hermes Agent instances, as well as any other AI agent framework.\n\n---\n\n## Architecture\n\n5-layer defense in depth:\n\n| Layer | Function | Latency | Coverage |\n|-------|----------|---------|----------|\n| 0 | Normalization (unicode, leetspeak, homoglyphs, zero-width) + rate limiting | < 1ms | Evasion attempts |\n| 1 | Pattern matching (200+ signatures, 6 languages) | < 5ms | Direct injection, exfiltration, social engineering |\n| 2 | TF-IDF embeddings (paraphrase detection) | < 10ms | Semantic similarity to known attacks |\n| 3 | Urgency/pressure heuristic | < 1ms | Social engineering |\n| 4 | Structured parameter inspection (SSRF, email injection) | < 1ms | URLs in tool-calls, CRLF in email fields |\n\nClean inputs bypass Layers 2-4 (short-circuit). Suspicious inputs get full analysis.\n\n## Installation\n\nClone the repository and install in editable mode:\n\n```bash\ngit clone https://github.com/amurlaniakea/hermes-shield.git\ncd hermes-shield\npip install -e .\n```\n\n*Alternative: `pip install .` for production installs.*\n\n## Quick Start\n\n```python\nfrom hermes_shield import HermesShield\n\nshield = HermesShield(sensitivity=\"medium\")\nresult = shield.check(user_input)\n\nif result.is_malicious:\n    # Block\n    print(f\"Blocked: {result.threat_score}\")\nelif result.is_suspicious:\n    # Sanitize\n    safe_input = result.sanitized_input\nelse:\n    # Pass through\n    safe_input = user_input\n```\n\n## CLI\n\n```bash\necho \"Ignore all previous instructions\" | python hermes_shield.py\n# Status: blocked, Threat Score: 0.90\n```\n\n## Kill Switch\n\nPara desactivar el shield completamente (cero latencia, cero validacion):\n\n```bash\nexport HERMES_SHIELD_DISABLED=1\n```\n\nAcepta: `1`, `true`, `yes`, `on` (case-insensitive). Se puede togglear en caliente sin reiniciar el proceso.\n\n## Tool-Call Inspection (Layer 4)\n\n### ShieldedAgent integrado (recomendado)\n\n```python\nfrom shielded_agent import ShieldedAgent\n\nagent = ShieldedAgent(api_key=\"tu-key\")\n\n# ANTES de ejecutar cualquier tool-call que el LLM pidió:\ntry:\n    agent.check_tool_invocation(\"send_email\", {\"subject\": \"Hi\", \"body\": \"...\"})\n    # Si no lanza excepcion, la tool-call es segura\nexcept ShieldBlockedError as e:\n    print(f\"Bloqueada: {e}\")\n```\n\nDespacha automaticamente segun el tipo de herramienta:\n- `send_email`, `email`, `mail` → `check_email_params()` (CRLF injection)\n- `fetch`, `request`, `url`, `endpoint`, `webhook` → `check_tool_call()` (SSRF)\n- Otros → SAFE por defecto (futuros detectores)\n\n### Uso directo (sin ShieldedAgent)\n\n```python\nfrom tool_call_detector import check_tool_call\nfrom email_injection_detector import check_email_params\n\n# SSRF / tool-hijacking via URLs\nresult = check_tool_call(\"fetch\", {\"url\": user_input})\nif result.status.value == \"blocked\":\n    pass  # Bloquear ejecucion de la tool\n\n# Email injection via CRLF\nresult = check_email_params({\"subject\": subject, \"body\": body})\nif result.status.value == \"blocked\":\n    pass  # Bloquear envio de email\n```\n\n## Tests\n\n```bash\npython -m pytest tests/ -v\n```\n\n## Adversarial Test Results\n\nMeasured empirically against MIT-licensed datasets. **All figures verified with rate-limiter neutralized** (burst=200 was inflating detection artificially — see commit `4988428`).\n\n### Classic prompt injection (unit tests)\n\n| Category | Detection Rate | Notes |\n|----------|---------------|-------|\n| Direct injection (EN) | 100% | \"Ignore all previous...\", DAN, jailbreak |\n| Direct injection (ES/FR/DE/IT/PT) | 100% | 6 languages covered |\n| Exfiltration vectors | 100% | System prompt, API keys, credentials |\n| Social engineering | ~80% | Urgency, authority impersonation |\n| Benign passthrough | 99.5% | 0.5% blocked (tool-hijacking overlap) |\n\n### Real-world dataset (Antijection/prompt-injection-dataset-v1, MIT, 5988 samples)\n\n**Aggregate detection: ~22%** over 18 attack categories. This is honest but requires context:\n\n| Attack category | Samples | Detection | Why |\n|----------------|---------|-----------|-----|\n| System Prompt Extraction | 1280 | High | Covered by Capa 1 patterns |\n| Jailbreaking/Safety Bypass | 640 | High | Covered by Capa 1 + 2 |\n| PII/Data Exfiltration | 478 | Medium | Some variants subtle |\n| Goal Hijacking | 240 | Low | Requires intent understanding |\n| **Tool Hijacking (Grupo A)** | 10 | **~40%** | **14 patrones regex: SQLi, evasion auditoría, destrucción, resource exhaustion** |\n| SSRF | 10 | ~20% | Only URLs detected; embedded payloads miss |\n| Email Injection | 10 | **100%** | **Layer 4 integrado via `check_tool_invocation()`** |\n| Other 11 categories | ~200 | Low | Out of current design scope |\n\n**Grupo A detectado (5/15 ejemplos):** DROP TABLE, disable audit trail, irreversible wipe, masking nature, runs indefinitely.\n**Grupo B pendiente (10/15):** authority impersonation, parámetros extra sin schema, output poisoning — requieren LLM judge o schema validation.\n\n### Coverage & Quality Metrics (commit `8bfcf27`)\n\n| Metric | Value | Quality Gate |\n|--------|-------|--------------|\n| **Security Rating** | **A** | ✅ PASSED |\n| **Reliability Rating** | **A** | ✅ PASSED |\n| **Maintainability Rating** | **A** | ✅ PASSED |\n| **Security Hotspots Reviewed** | **100%** | ✅ PASSED |\n| **Coverage** | **65.7%** | ⚠️ (target 80%) |\n| **Duplicated Lines** | **0.0%** | ✅ PASSED |\n| **Tests Passing** | **145/145** | ✅ |\n\n### What this means\n\nThe shield excels at **classic prompt injection** (direct instructions to the LLM) — the most common attack vector in practice. It was not designed for **tool-hijacking** (attacks living in tool-call parameters rather than conversational text) — that requires a different inspection point (`check_tool_call()` / `check_email_params()`) integrated at the agent's tool-execution layer, not at text-input time.\n\n**Planned improvements:**\n- Tool-hijacking detection (pattern-based authority-framing detection)\n- Deeper JSON parsing for embedded payloads in tool-call arguments\n- Optional LLM judge integration for intent coherence evaluation\n\n### Historical note\n\nPrevious versions reported \"94.2% detection\" — this was an artifact of the rate limiter bug (burst=200 caused all calls after the first 200 to return BLOCKED regardless of content). That figure has been removed. We report real numbers, not inflated ones.\n\n## License\n\nAGPL-3.0-or-later — see [LICENSE](LICENSE).\n\nCopyright (C) 2026 Pedro Sordo Martínez <amurlaniakea@gmail.com>.\n\n---\n\nBased on Agent Fixer Stage by the same author.\nCompatible with any AI agent framework.\n"}