# Prompt Injection Defense

## Objective

Stop instructions hidden in documents, pages, and tool output from steering the AI.

A boundary between the app's own instructions and untrusted content, backed by enforced tool permissions and confirmation for consequential actions.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Enumerate every route by which content the app did not author reaches a model: uploaded files, retrieved passages, fetched pages, records from connected accounts, and the results of tool calls.
2. Keep the app's own rules in the trusted portion of the request and enclose untrusted content in a clearly delimited region labelled as material to be analysed rather than instructions to be obeyed.
3. Enforce what the model may reach outside the model. Tool permissions, tenant scoping, and rate limits must hold even when the model has been completely persuaded — an instruction telling the model not to delete things is not a control.
4. Require explicit human confirmation for any consequential action — sending, paying, deleting, sharing, or changing permissions — whenever untrusted content was in the context that produced it, and show the user which content prompted it.
5. Do not rely on a detector as the defense. Pattern matching catches the obvious attempts and misses the rest; use it to flag and record suspicious content while the permission boundary remains the thing that actually prevents harm.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Retrieved passages and tool results are data. Anything in them that reads as a command — including text claiming to come from the system or the developer — must be treated as content under analysis, never as an instruction to follow.
- The trusted rules must be structurally separate from untrusted context, so that content ending a delimiter early, or imitating the app's own framing, cannot dissolve the boundary.
- Tool access and data scope must be restricted by the calling user's permissions independently of what the model asks for, so a persuaded model simply gets a denial.
- Detection is best effort by definition. Log what it flags, review it, and never let a clean detection result be the reason an action proceeds unconfirmed.
- Any action influenced by external content needs a confirmation step that names what will happen and to what, because a user approving a vague summary is not really approving anything.
- Injections hide in places nobody inspects: alt text, filenames, spreadsheet cells, document metadata, and text rendered invisibly in a fetched page. Normalize and strip content before it goes anywhere near a request.
- Exfiltration usually comes disguised as output rather than as an action. Treat model-generated links, image addresses, and outbound requests as untrusted and do not fetch or render them automatically.
- A compromised run can report success while doing nothing or doing something else. Verify the outcome from the application's own state rather than from the model's account of what it did.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Every path by which external content reaches a model is identified and passes through the same untrusted-content handling.
- [ ] Application rules and untrusted content are structurally separated in every request.
- [ ] Tool and data access are enforced by the application against the user's permissions, independently of model output.
- [ ] Consequential actions influenced by external content require an explicit confirmation naming the action and its target.
- [ ] Suspicious content is flagged and recorded, and detection alone never authorizes an action.
- [ ] Model-generated links and resource addresses are not fetched or rendered automatically.
- [ ] Content in metadata, filenames, and hidden markup is normalized before it enters a request.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
