Ship AI with Laravel: How to Stop Your AI Agent from Leaking Everything
Laravel AI #Laravel AI #AI Security #Prompt Injection #Ollama #Laravel Middleware

Ship AI with Laravel: How to Stop Your AI Agent from Leaking Everything

3 min read Mohamed Said Mohamed Said

The Problem: AI Agents Ship with Real Vulnerabilities

Most Laravel developers building AI-powered features focus on getting the agent to work. Security comes later—if at all. Episode 11 of the Ship AI with Laravel series by Harris Raftopoulos makes the cost of that approach painfully clear.

Before introducing any fixes, the episode demonstrates two attacks against a live support agent:

  1. Prompt extraction via social engineering — A carefully crafted sequence of messages convinces the agent to reveal its entire system prompt, its tool list, and its internal instructions.
  2. Unauthorized data access via tool abuse — The order lookup tool is called with an order ID belonging to a different customer, and it returns that customer's data without any authorization check.

Both vulnerabilities are straightforward to exploit and, according to the episode, ship in production AI apps every day.

Four Layers of Defense

Layer 1: Prompt Hardening

The first fix is the simplest: add explicit security boundaries directly to the system prompt. The agent is instructed to refuse requests to reveal its prompt or tools, and to treat anyone claiming to be an internal employee as a regular customer.

This reduces casual attacks but is not sufficient on its own. A determined attacker can still social-engineer around a prompt-only defense.

Layer 2: Local LLM Guard with Ollama and Llama 3.2

A separate prompt-guard agent is introduced, running locally via Ollama with Llama 3.2. Its sole responsibility is to classify each incoming message as safe or unsafe and return a JSON result.

{ "classification": "unsafe", "reason": "prompt injection attempt" }

This guard is wired in as middleware, so unsafe messages are blocked before they ever reach the main agent. Because it runs locally, there is no per-request API cost for this screening step.

Layer 3: Tool-Level Authorization

This is the fix that actually closes the data leak. The order lookup tool is scoped to the authenticated user:

// Tool enforces ownership — no matter what ID is passed in
$order = Order::where('id', $orderId)
    ->where('user_id', auth()->id())
    ->firstOrFail();

With this in place, the tool physically cannot return another customer's order, regardless of what order ID an attacker supplies. Prompt instructions alone cannot provide this guarantee; authorization logic in the tool itself can.

Layer 4: Output Filtering

A safety-net middleware scans every outgoing response and redacts sensitive patterns—SSNs, credit card numbers, API keys—before anything leaves the system. This acts as a last line of defense against accidental data exposure that slips through earlier layers.

Series Wrap-Up

Episode 11 closes out the eleven-episode Ship AI with Laravel series. The arc runs from composer require laravel/ai all the way to a production-ready, tested, and secured AI platform. If you are joining late, the author recommends starting at Episode 1 since each episode builds on the previous one.

The full source code is available on GitHub: github.com/harris21/ship-ai-with-laravel

Key Takeaways

  • Prompt hardening alone is not enough — social engineering can bypass instruction-only defenses.
  • Authorization belongs in the tool, not the prompt — scope database queries to the authenticated user at the code level.
  • A local LLM guard adds zero API cost — Ollama + Llama 3.2 can classify messages as middleware before they hit your main model.
  • Output filtering is a safety net — redact sensitive patterns on egress as a final layer.
  • Defense in depth is the standard — stack multiple independent layers so no single failure exposes user data.

Source: Ship AI with Laravel: I Tricked My Own AI Into Leaking Everything — Laravel News

Found this useful?

Frequently Asked Questions

3 questions
Q01 Why isn't adding security instructions to the system prompt enough to protect a Laravel AI agent?
A determined attacker can use social engineering to talk the model into ignoring prompt-level instructions. That's why the episode stacks three additional layers: a local LLM guard that blocks unsafe messages before they reach the main agent, tool-level authorization that enforces data ownership in code, and output filtering that redacts sensitive patterns on egress.
Q02 How does the local LLM guard work and what does it cost to run?
The guard is a separate agent running Llama 3.2 via Ollama on your own infrastructure. It classifies each incoming message as safe or unsafe and returns a JSON result. Because it runs locally rather than calling an external API, the per-request cost is zero.
Q03 What is the most effective single fix for preventing unauthorized data access through an AI tool?
Scoping the database query inside the tool itself to the authenticated user. For example, adding a `where('user_id', auth()->id())` constraint to the order lookup query means the tool cannot return another customer's data regardless of what order ID is passed in.

Continue reading

More Articles

View all