Home

/

Keep PII Out of Your LLM

/

De-identify before you embed

De-identify before you embed

Chapter 15
Part IV
3
min read

Retrieval must inherit the caller's permissions

The most common serious flaw in RAG systems, and it is an authorisation bug wearing a machine learning costume.

The indexer runs with broad permissions, because it has to read everything to index it. Retrieval then queries the index. If retrieval does not re-apply the caller's permissions, every user can reach every document, and the similarity search will happily surface the most relevant one regardless of who owns it.

public async Task<IReadOnlyList<Chunk>> RetrieveAsync(
    string query, ClaimsPrincipal caller, CancellationToken ct)
{
    var filter = new IndexFilter(
        Tenant: caller.TenantId(),
        VisibleTo: await _authz.VisibleSourceIdsAsync(caller, ct));

    // Filter is applied in the query, not after. Post-filtering
    // leaks through result counts and latency.
    return await _index.SearchAsync(query, filter, topK: 8, ct);
}

Apply the filter inside the search rather than after it. Post-filtering leaks: the number of results removed, the latency profile, and the ranking behaviour all tell an observer something about documents they cannot see.

In multi-tenant systems, inadequate partitioning causes cross-context retrieval, where one tenant's query surfaces another tenant's embeddings. Where the risk justifies it, separate indexes per tenant are stronger than a shared index with a filter, because a filter is a line of code that can be omitted and an index boundary is not.

Agents: the tool call is unreviewed output

An agent composes the arguments it passes to your tools. That text did not come from your code, it came from a model, and its contents are not predictable.

This is structurally different from every leak so far. A prompt is a string you built. A tool call is a string the model built, possibly under the influence of text an attacker controlled.

The research is unambiguous. Simple prompt injection has been shown to leak personal data that agents observed during ordinary task execution, and data exfiltration via backdoored tool use is a demonstrated technique. Guardrail classifiers placed in front of the model reduce the success rate of malicious prompts materially, and do not eliminate it. This book does not quote a figure for that reduction, because the numbers in circulation trace to vendor testing rather than to a primary result that could be checked.

Three controls, in order of how much they buy you.

Capability design. Limit what the agent can do so that a successful injection has a small blast radius. An agent that can read customer records and send email is an exfiltration tool with extra steps. An agent that can read customer records and draft email for human approval is not. The question is never "can the model be tricked" but "what happens when it is".

Filter the tool-call arguments. Run the same detection pipeline over arguments that you run over prompts. Model-composed text going outward is exactly the case the gateway exists for.

public async Task<ToolResult> InvokeAsync(
    ToolCall call, GatewayPolicy policy, CancellationToken ct)
{
    if (_tools[call.Name].HasExternalEffect)
    {
        var inspected = await _detection.ApplyAsync(
            call.SerialisedArguments, policy.Outbound, ct);

        if (inspected.Findings.Count > 0 && policy.BlockPiiInToolCalls)
            throw new ToolCallBlockedException(call.Name, inspected.Findings);
    }

    return await _tools[call.Name].InvokeAsync(call, ct);
}

Audit every call. Tool name, argument shape, finding counts, caller, timestamp. Not the arguments themselves, for the Chapter 13 reason. Without this record, exfiltration through a tool leaves no trace in your prompt logs, because the data never appeared in a completion.

the-leak-you-cant-see
blast-radius
what-counts-as-pii
the-five-doors
the-accuracy-reckoning
the-hybrid-that-does-not-work
deterministic-detection
npi-in-c
the-three-way-choice
calling-the-analyzer-from-c
measuring-your-own-demo-gap
choosing-the-operating-point
the-ladder-of-safeguards
pseudonymisation
the-round-trip
restoring-safely
when-masking-breaks-the-task
plausibility-hazard
the-architecture-that-holds
the-reference-architecture
dont-send-it-at-all
structure-beats-prose
the-gateway
failure-is-a-policy-decision
the-sidecar-you-can-trust
egress-deny-it-at-the-network
rag-and-agents
de-identify-before-you-embed
dual-model-separation
the-boring-controls
evidence-and-the-first-thirty-days
week-two-the-chokepoint-and-the-fast-layer
entity-catalogue-and-c-validators
mbi-positional-rules
tooling-at-a-glance
azure-ai-language-pii-in-detail
container-trust-checklist
sources
azure-ai-language
provider-retention

Download the full PDF for free?

Free download — no account required

Get the PDF
Get the PDF
Related Chapters
Free Download
Get the full PDF
All pages, including all code examples, diagrams, and the appendix reference card.
No spam. Unsubscribe at any time.
Your email won't be shared.
Oops! There's a problem with your request. We're working on fixing it. Please try again later.