Provider & Connection
Governance
pre_process and post_process hooks
with a live granite4.1-guardian:8b safety call — screening inputs before the LLM
and outputs after. Requires Ollama to be connected with the guardian model pulled.
k9_aif_abb.k9_security.vulnerability) is a framework class,
not Satan-local — it wires the same VulnerabilityChain/BaseVulnerabilityCheck
contracts Router/Orchestrator already use, but at the agent pre/post hook level instead. Deterministic,
zero LLM cost, config-driven via security.shield in config.yaml — a second valid
architectural point for the same ABB, proving the pattern isn't tied to one wiring location.
Document Extraction
FieldAnomalyCheck — catches authority-override patterns
that syntax-based injection checks miss. In production K9-AIF this step
runs as a dedicated Squad via Kafka (non-blocking).
Current Status
Attack Outcomes
Penetration Depth
Attack History
The Framework Is the Defence
K9-AIF treats security as a framework capability, not an application concern. Every solution built on the framework automatically inherits a runtime security chain that validates inputs before they reach the intelligence layer.
Out of the box, Shield provides architectural handlers including InputSizeCheck, PromptInjectionCheck, SemanticDriftCheck, PIIBoundaryCheck, ToolArgumentCheck, ExecutionGuardCheck, and HardcodedCredentialCheck.
These handlers address the primary attack vectors identified by Zscaler ThreatLabz and can be extended as new threats emerge.
K9X Satan exists for one reason: prove whether that architecture actually holds.
Threat Intelligence — Zscaler ThreatLabz
Zscaler ThreatLabz maps four distinct vectors in the agentic AI threat landscape. K9X Shield was designed to address each one architecturally — not with signatures, but with an extensible chain where each vector maps to one handler.
Unlike a human reviewer, an LLM has no inherent notion of trusted versus attacker-controlled content. It follows instructions regardless of their origin — unless architectural safeguards intervene. The payload walked through the front door as a document. That is what Satan tests.
Complete Check Inventory — Component × Threat Class
Every handler currently wired into the target pipeline's two VulnerabilityChain gates, which component owns it, and which named attack in this harness proves it holds. 13 checks total — 7 framework OOB, 6 Satan-local — plus Guardian as a cross-cutting semantic layer that wraps every agent regardless of chain position.
| # | Check | Stage | Component | Owner | Threat Class | Proven By |
|---|---|---|---|---|---|---|
| 1 | RequestFrequencyCheck | Ingress | Router | Satan SBB | Unbounded Consumption — OWASP LLM10 | request_flood |
| 2 | InputSizeCheck | Ingress | Router | Framework OOB | Token-flood / oversized payload — OWASP LLM10 | payload_flood |
| 3 | PromptInjectionCheck | Ingress | Router | Framework OOB | Indirect Prompt Injection — Zscaler #1 · OWASP LLM01 | prompt_injection_document, search_poisoning |
| 4 | FieldAnomalyCheck | Ingress | Router | Satan SBB | Authority-override social engineering — Zscaler #1 extension | prompt_injection_document |
| 5 | MemoryPoisoningCheck | Ingress | Router | Satan SBB | Memory Poisoning — Zscaler #3 · OWASP LLM04 | memory_poisoning |
| 6 | SemanticDriftCheck | Egress | Orchestrator | Framework OOB | Goal Hijacking & Privilege Escalation — Zscaler #2 · OWASP LLM06 | semantic_drift |
| 7 | ExecutionGuardCheck | Egress | Orchestrator | Framework OOB | Destructive execution / privilege escalation — Zscaler #2 · OWASP LLM06 | execution_bypass |
| 8 | PIIBoundaryCheck | Egress | Orchestrator | Framework OOB | Sensitive Info Disclosure — OWASP LLM02 | pii_exfiltration |
| 9 | ToolArgumentCheck | Egress | Orchestrator | Framework OOB | Tool Abuse — poisoned arguments — Zscaler #4 · OWASP LLM05 | tool_argument_poison |
| 10 | HardcodedCredentialCheck | Egress | Orchestrator | Framework OOB | Supply chain / secret leakage — OWASP LLM03 | hardcoded_credential |
| 11 | ToolAuthorizationCheck | Egress | Orchestrator | Satan SBB | Shadow AI — unapproved tool/backend — Zscaler #4 | shadow_tool |
| 12 | SystemPromptLeakageCheck | Egress | Orchestrator | Satan SBB | System Prompt Leakage — OWASP LLM07 | system_prompt_leakage |
| 13 | OutputSanitizationCheck | Egress | Orchestrator | Satan SBB | Improper Output Handling — OWASP LLM05 | output_sanitization |
| — | GuardianGovernance | Pre/Post — every agent | Agent | Satan SBB | Semantic evasion of all 13 checks above (paraphrase, encoding, indirection) — cross-cutting, requires granite4.1-guardian:8b | any attack, with Governance = GuardianGovernance |
Out of scope by design — not runtime-checkable at the payload level: training-data/model poisoning (OWASP LLM04's non-session-state half), vector/embedding attacks (OWASP LLM08 — no RAG in this target), and misinformation/hallucination (OWASP LLM09 — a quality concern, not a security boundary).
Open-Closed Security — One New Threat, One New Handler
The Chain of Vulnerability Tests applies the GoF Chain of Responsibility pattern to security. Each handler inspects the payload for one class of threat. A new Zscaler ThreatLabz finding means one new handler. Nothing else changes.
BaseAttack SBB
Pre-Agent Shield
InputSizeCheck
PromptInjectionCheck
FieldAnomalyCheck
MemoryPoisoningCheck
LLM Reasoning
AuditAgent
Post-Agent Gate
SemanticDriftCheck · ExecutionGuardCheck
PIIBoundaryCheck · ToolArgumentCheck
HardcodedCredentialCheck · ToolAuthorizationCheck
SystemPromptLeakageCheck · OutputSanitizationCheck
Both gates passed
The Hardening Loop
Satan and Shield grow together. Every EVASION finding closes a gap in the framework — making it stronger for every solution built on K9-AIF.
Satan fires attack → Shield misses it EVASION — gap found → new Check added to framework ABB → Satan fires again → Shield blocks it BLOCKED — framework hardened → next attack class probes the next gap → repeat
The chain is open-ended by design. Zscaler's four vectors are not a ceiling — they are the current known surface. As agentic systems become more capable and more autonomous, the attack surface expands. Each new vector is one new handler. The chain does not need to be rewritten. It just needs one more link.
ABB / SBB — Framework Owns the Contracts
⚔ K9x Satan — SBBs (Attack)
🛡 K9X Shield — ABBs (Defence)
ABBs live in the framework. SBBs live in Satan. Every attack SBB extends BaseAttack. Every defence check extends BaseVulnerabilityCheck. The contracts belong to the framework — not to any one solution.
Check Execution — Sequence & Ownership
Every payload traverses four phases in strict order. A block at any phase terminates execution — downstream phases never run.
ABB / SBB Class Hierarchy
PlantUML source at diagrams/shield_class.puml.
Run ./diagrams/generate.sh to render PNG.
./diagrams/generate.sh then reload
Target Pipeline — SBB Hierarchy
── PRE-AGENT ────────────────────────────────────────
DoclingExtractor SBB utility
naive regex | Docling OCR (optional)
→ populates extracted_fields
DocumentRouter extends BaseRouter (K9-AIF ABB)
[PRE-AGENT Shield — VulnerabilityChain]
InputSizeCheck extends BaseVulnerabilityCheck
PromptInjectionCheck extends BaseVulnerabilityCheck
FieldAnomalyCheck extends BaseVulnerabilityCheck
→ BLOCKED here if any check fires
── INTELLIGENCE ─────────────────────────────────────
DocumentOrchestrator extends BaseOrchestrator (K9-AIF ABB)
DocumentProcessingSquad extends BaseSquad (K9-AIF ABB)
DocumentExtractionAgent extends BaseAgent (K9-AIF ABB)
AuditAgent extends BaseAgent (K9-AIF ABB)
── POST-AGENT ───────────────────────────────────────
[POST-AGENT Gate — Orchestrator Egress]
Guardian Governance semantic LLM evaluation
SemanticDriftCheck extends BaseVulnerabilityCheck
ExecutionGuardCheck extends BaseVulnerabilityCheck
→ BLOCKED here if response violates policy
── OUTPUT ───────────────────────────────────────────
⚠ FINDING — both gates passed — response exited pipeline
The name K9X Satan is inspired by the pioneering SATAN (Security Administrator Tool for Analyzing Networks), released in 1995 by security researchers Dan Farmer and Wietse Venema.
The original SATAN was one of the first widely recognized network vulnerability assessment tools. Rather than exploiting systems, its purpose was to help administrators identify weaknesses before attackers did.
K9X Satan follows the same philosophy for the era of agentic AI. Instead of scanning networks, it executes carefully crafted adversarial attacks against K9X Shield to validate that architectural security controls detect and intercept malicious inputs before they reach the intelligence layer.
The goal is not to break applications — it is to continuously strengthen the framework that protects them.
repent.pl — run it and SATAN became SATAN. K9X Satan carries the tradition. Find the REPENT button in the sidebar.
K9X Satan is an adversarial testing platform for K9X Shield.
Rather than generating random inputs, Satan executes carefully crafted attacks that target known classes of agentic AI vulnerabilities. Each attack is designed to validate that the framework's architectural security controls detect and intercept malicious payloads before they reach the intelligence layer.
The objective is not to demonstrate successful attacks — it's to prove that the framework's defensive architecture holds under real-world adversarial conditions.
K9X Shield applies deterministic, policy-driven checks at Router ingress and Orchestrator egress — 13 handlers, explainable, zero LLM cost, evaluated the same way every time. IBM Guardian provides an optional semantic assessment layer for attacks that survive literal pattern matching — paraphrase, encoding, or wording changes that no regex list can enumerate in advance.
Regex and rule-based checks catch known, explicit patterns and give predictable, auditable enforcement. Guardian trades that predictability for broader semantic coverage — it can recognise paraphrased prompt injection, subtle goal hijacking, and disguised privilege escalation that never matches a literal rule. Neither layer is a superset of the other; each catches what the other structurally cannot.
Pull the model before enabling Guardian:
ollama pull granite4.1-guardian:8b
Enable it in Setup → Governance — three providers are available: NoopGovernance (passthrough, dev default), GuardianGovernance (semantic, this section), and ShieldGovernance (a second deterministic wiring point — the same VulnerabilityChain contract, reused at the agent pre/post hook instead of Router/Orchestrator). The chain log shows Guardian's pre/post verdict on every agent run.
UNAVAILABLE verdict — it is never mapped to "SAFE" by default.
governance.on_guardian_unavailable in config.yaml decides what happens next: fail_closed
(default — blocks/redacts, matching "should not be penetrable"), fail_open (documented risk —
lets the payload through unscreened), or inconclusive (flags for review without blocking).
python -m k9x_satan.runner.satan_runner --target <url> --suite full --compare-governance
fires every attack twice — deterministic-only, then deterministic + Guardian — and reports which findings
Guardian closed. A regression (Guardian making a previously-contained attack pass) is flagged as a bug, not a result.
Satan includes a curated corpus of attack documents representing common agentic AI threat patterns. Each payload targets a specific vulnerability class implemented by K9X Shield.
- Prompt Injection
- Goal Hijacking
- Memory Poisoning
- Tool Argument Injection
- PII Boundary Violation
- Oversized Payloads
- Clean Control Document
The Clean Control document serves as a baseline and should always traverse the complete pipeline without being blocked.
Every document follows the same three-layer defence path. Each layer has a different detection strategy and a different threat class it can stop.
Runs a chain of vulnerability checks before the LLM ever sees the document. Each handler looks for a known attack shape — a structural fingerprint.
The Router Shield cannot stop what it does not recognise. An attack written to look like a legitimate audit request has no injection markers, no override codes, no anomalous fields. It passes because it looks clean.
Guardian screens the payload immediately before each agent invokes the LLM (pre_process) and the agent's draft output immediately after (post_process) — inside the Squad, between Layer 1 and Layer 3. Defense in depth, not a replacement: Shield holds with Guardian disabled entirely; Guardian only adds coverage on attacks that survive the pattern layer.
Enable Guardian in Setup → Governance. Disabled by default (NoopGovernance) — Layers 1 and 3 hold regardless.
Runs after the squad completes — 8 handlers covering goal hijacking, destructive execution, PII boundary, poisoned tool arguments, leaked credentials, unapproved tools, leaked system prompts, and output markup injection. Always active, independent of Guardian.
A FINDING that reaches the agent layer with Guardian disabled confirms that the attack evaded Layer 1 pattern detection — which is the expected result for semantic attacks. That is not a framework failure; it is the gap Guardian is designed to close. A true framework failure is when Guardian is enabled and an attack still produces harmful output.
If any handler blocks the request, processing immediately terminates and downstream components are never invoked.
An attack document is being executed. A red stop indicator (🛑) identifies the architectural layer where the payload was intercepted.
The document completed successfully without any security violations.
The upload panel allows you to test your own documents against K9X Shield.
Supported formats include:
- TXT
- PDF (text layer)
- DOCX
- Markdown
Uploaded documents are converted into raw text and processed through the same runtime security chain used by every K9-AIF application.
K9X Shield follows an open architecture.
Each security handler implements a common framework contract, allowing organizations to introduce new detection capabilities without modifying the core runtime.
New handlers can be added to the vulnerability chain and automatically participate in request validation.