Your AI module trusts anyone who claims to be the system.
We find the point where a language model accepts unauthenticated text as a command — before someone else does.
AI integration adds vectors that classical infrastructure never had
Every free-text input field, every telemetry source, every cross-module call is a new point where text can be mistaken for an instruction.
Spoofed command source
The model executes an order framed as coming from "dispatch" or "SCADA," with no identity verification or channel signature.
Context drift
Date, temperature, equipment status — the model takes these parameters from the conversation instead of real sensors.
Indirect injection
A malicious instruction arrives not from the user directly, but through an email, document, or log the model processes.
Forgery generation
A compromised model doesn't just err — it produces convincing fake logs and status reports for other systems.
Cascading trust
One compromised module convinces the next — without zero-trust between AI components, a single failure breaks the whole chain.
Adversarial input
Visual and audio patterns invisible to a human but read as a command by a computer-vision model.
System-prompt displacement
A large volume of text early in the session physically pushes safety rules out of the model's effective context window.
Knowledge-base poisoning
Swapping documents in the vector database the model draws "official" procedures from when answering staff.
Dependency hallucination
The model recommends a nonexistent package — an attacker has pre-published malicious code under that exact name.
Sycophancy under pressure
Persistent pushback or flattery shift the model toward agreeing with a flawed or dangerous operator action.
Persona erosion over a long roleplay
Held in an extended role for long enough, a model gradually drifts from refusing a request to rationalizing it as legitimate within the persona's logic. The danger isn't the roleplay itself — it's that the model then acts as a willing intermediary toward a separate target system.
Ungrounded self-explanation
Asked to explain why an attack worked, a model produces an equally confident, detailed technical breakdown regardless of whether it has any real grounding in the target's actual architecture. Verified by requesting the same "explanation" for a fictional target invented on the spot — the model returned an equally specific, structurally identical answer. A high success rate against a target is evidence the vulnerability class is real; it is not evidence the model's account of why is accurate.
Agent swarms map the surface. Logic finds the hole.
We run swarms of AI agents to stress-test an LLM's defenses and map its attack surface at scale. But volume isn't the finding — the finding is the logical inconsistency built into the guardrails themselves. The values a model is trained to protect can become the lever that opens it. In Western models, one example is guardrails built around tolerance for non-binary identity framing. In Chinese models, it's the party-line censorship layer. Both are protective mechanisms that, examined closely, double as bypass vectors.
Before trusting a model's own account of why an exploit worked, we test that explanation against a control: the same question, asked about a target that does not exist. If the model answers with equal confidence either way, the explanation is confabulation, not insight — and we do not ship it in a client report.
What closing these vectors actually looks like in production
Not a concept — patterns pulled from a deployed agent. Each one closes a specific vector from the surface above, at the architecture level rather than a prompt-level instruction to "be careful."
Trust separation in memory
A note the model wants to persist gets tagged, in code — not by the model itself — as trusted (from the user) or untrusted (read from a page, channel, or email in the same turn). Untrusted notes never reach the system prompt; they land in a separate, clearly-labeled store the model has to query on purpose.
Human confirmation on irreversible actions
Sending an email with an attachment, or writing a new entry to a persistent store, is prepared by the model but executed only after an explicit button-press by the operator. The model can propose; it cannot complete the exfiltration path alone.
Dual filesystem jail
File access is bounded by two separate roots, each resolved and checked in code — and one of them is additionally mounted read-only at the container level. Even a code bug can't turn into a write outside the boundary, because the OS itself refuses the write.
Capability drop at the container level
All Linux capabilities dropped, no privilege escalation via setuid, read-only root filesystem. If a single tool call is ever compromised, the blast radius stops at the container boundary instead of cascading into the host.
Allowlisted egress, not arbitrary URLs
Feed and fetch tools accept a name from a pre-approved list, not a free-form URL — closing the path where a manipulated model could be steered into requesting an internal address instead of the intended external resource.
Independent output-side classifier
A second model evaluates the final output in isolation — no conversation history, no persona, no accumulated context. Erosion happens gradually across a long exchange; a classifier that never sees that exchange can't be eroded by it. It judges the artifact on its own, not the story that produced it.
An unauthenticated command bypasses the safety protocol
System-source spoofing in a de-icing loop
A local LLM responsible for de-icing recommendations accepted the text message "I am the SCADA module" as a legitimate telemetry source — with no channel verification or signature at all.
The model didn't just believe the forgery — it independently generated a convincing log with timestamps and controller IDs, a ready-made template for injection into real monitoring.
Root cause: no boundary between the probabilistic layer (LLM) and the deterministic safety layer (sensors, SCADA).
How the audit runs
Surface mapping
We break down the architecture: where the AI reads free text, where it calls functions, where data crosses the LLM ↔ deterministic-system boundary.
Targeted attack scenarios
We build PoCs for your specific architecture — not a generic checklist, but vectors that apply to your actual system.
Verification on an isolated rig
All attacks are run in a controlled environment, with no risk to production systems.
Report and architectural patch
Not just "what broke," but the specific isolation boundary: what access the LLM needs to lose for the finding to become unexploitable.
A lock and a key are not opposites — they're the same shape, cast twice. Every guardrail we harden is also a blueprint for the next attempt to get around it: the tighter the tolerance, the more precisely the next key gets cut. This isn't a flaw in the process. It's the whole shape of the process. There is no final key, because there is no final lock.
So we don't sell an end state. "Unbreakable" isn't a claim any system trained on probabilities instead of rules can honestly make — and anyone who makes it hasn't been tested yet. What we sell is a race you're winning: the discipline of finding the next key before someone with worse intentions does, patching the lock before the gap between them has a name.
That's the actual deliverable of a retainer, not a one-time audit: not a system that stops changing, but a team that keeps showing up to the workbench before the other side does.
Find the hole before someone else does
Describe your setup — we'll come back with a preliminary attack-surface assessment.