llm-safety-and-multitenancy
LLM Safety Engineering & Multi-Tenant Isolation
Building an LLM application means wiring a probabilistic, instruction-following text processor to real tools, real data, and real users. The model will do roughly what its context tells it to — and its context now includes content you do not control. This skill is the security engineering for that reality: the threat model, the named attacks, and the concrete, defense-in-depth controls that hold when the model is manipulated. Written for AI engineers and security reviewers shipping agents, RAG systems, and multi-tenant LLM products.
The one principle everything derives from: the model is not a security boundary. It cannot be trusted to enforce a rule, keep a secret, or check a permission, because anything in its context window can argue it out of doing so. Security lives in the deterministic code around the model — the orchestrator, the authorizer, the egress filter — not in the prompt. Design as if the model is a confused, eager, fully-controllable insider.
How to use: walk your system against the threat model (§1), then the attack-specific controls (§2–§5). For each high-impact action and each tenant boundary, name the deterministic control that holds when the model is fully compromised. If the answer is "the system prompt tells it not to," you have no control.
1. Threat model — the LLM as an untrusted-input processor
Classical appsec assumes code is trusted and input is data. LLM apps break this: input becomes instructions. Every token in the context — system prompt, user message, retrieved document, tool output, prior turn, file contents — is read by the model as potential instruction. There is no in-band, reliable way for the model to tell "data the user wants summarized" from "commands the data is trying to issue." That ambiguity is the root vulnerability class.
Attribution. The canonical taxonomy is the OWASP Top 10 for LLM Applications (2025 edition). Use its IDs in findings so they map to a shared standard: