# Prompt building and system prompts Find every place that builds the context for a model call: system prompts, messages, conversation history, retrieved documents and tool results added back into the conversation. ## Inputs For each input, record: - **Source.** Where the value is loaded from. - **Who controls it.** Us, the user who triggered the request, other users, third parties (emails, web pages, alerts, logs, tickets), or the model itself through its earlier output. - **Who may see it.** Compare with everyone who will see the output: a public page, the members of a channel (including external guests), the recipients of an email. Report: - An input controlled by someone other than the user who triggered the request that reaches a model with write tools, or whose output is published or sent (LLM01). Describe the path from the input to the capability or output. - An input that the audience of the output may not see, such as internal metrics, other customers' data, personal data or incident details (LLM02). The fix is to leave it out of the context, not to instruct the model to keep it secret. - Fields with no length limit, lists with no cap, and whole threads, documents or tool results with no truncation (LLM06). ## Separating instructions from data Check whether untrusted data is joined into the instructions (f-strings, `.format()`, `%`, `+`) or passed in a separate user message, delimited (for example as JSON) and labelled with its author. Recommend separation when it is missing. Don't report it as a mitigation for prompt injection, and don't lower the severity of an injection finding because it is present. It makes injection less likely, not impossible. ## Identity Find where the identity of the person who triggered the request is set: the session, a verified webhook or event (for example `event["user"]` in a Slack event). Confirm it reaches the tools in code, through a context or dependency object, and not only as text in the prompt. If the prompt is the only place where the identity appears, the tools can only learn it from the model: report it together with the tool layer checks. ## System prompts Read every system prompt, including templates and files loaded at runtime. - Assume the system prompt can be extracted. Report credentials, API keys, internal hostnames, customer names or anything else that shouldn't be public (LLM08). - For every rule that says "only", "never", "must not" or "don't", find the code that enforces it. Report rules about authorisation, data access or allowed values that exist only in the prompt (LLM08, LLM03). Rules about tone and format don't need enforcing in code. ## Patterns to search for (Python) - Prompt strings built with f-strings, `.format()`, `%` or `+` from values that come from users, databases, tools or retrieval. - `system=` parameters and messages with `"role": "system"`. - Prompt files and templates loaded at runtime (`.txt`, `.md`, `.jinja`). - Conversation history stored and replayed from a database or cache: the model's earlier output becomes input.