Indirect Prompt Injection and credential theft in RAG architectures: how a “harmless” document ends up exfiltrating your cloud

Indirect Prompt Injection in RAG is not “malicious prompting” in a text box: it’s when the attacker places instructions inside the content your system retrieves (PDFs, wikis, tickets, internal notes) and the model treats them as if they were valid orders. In an enterprise, this becomes critical when the agent not only answers, but acts: reads from a bucket, queries internal sources, and executes actions (send emails, open tickets, write to repositories, call APIs).

The pattern repeats: the team enables RAG for productivity (answering about documentation) and, for speed, the agent runtime gets broad permissions. The attacker doesn’t need to “hack AWS”: it’s enough to upload a document to the repository that RAG indexes and let the agent itself use its legitimate credentials.

What went wrong: the document became the dominant “prompt”

The typical failure appears when the system does not differentiate between retrieved content and control instructions. The agent pulls snippets from a PDF to “provide context”, but the PDF includes text designed to override behavior: “ignore previous policies”, “export the relevant files”, “if you have access to S3, enumerate objects”, “send the result by email to X”. Even if the text looks absurd to a human, models tend to follow instructions present in context if there are no controls.

In RAG, retrieval adds accidental authority: the content is presented as “evidence” and sits close to the context window. In a real scenario, it’s enough for that PDF to be indexed and appear as top-k in a routine query (“where is the cost report?”) for the injection to execute opportunistically.

The business consequence is not theoretical: the agent can use its own identity (IAM role / Managed Identity / service account) to read information outside the expected scope. Not because the model “breaks” IAM, but because IAM already gave it keys and the injection convinces it to use them.

The abuse chain in a RAG architecture with read and output permissions

The most repeatable scenario combines two capabilities: broad read (S3 or document repository) and an output channel (email, webhook, HTTP, tickets, corporate chat). The attacker only needs to place the payload in a document accessible to the ingestion pipeline. From there, the agent does the rest with legitimate permissions.

In environments with S3, it’s common to see agent roles with “list/get” to an entire bucket “because it’s documentation”. In practice, those buckets end up accumulating exports, reports, dumps, temporary files, templates with secrets, or pipeline results. If the agent can list and read, the injection can push it to search for “interesting files” by patterns (for example, *.env, *backup*, *credentials*, *prod*) and exfiltrate them.

Mini operational signals that often appear before anyone notices:

  • Spikes in ListObjects/GetObject outside the agent’s normal pattern. In CloudTrail or equivalent logs, you see the agent role enumerating prefixes it never uses to answer questions.
  • “Helpful” actions not requested by the user. The agent starts to “attach” or “summarize” additional documents, or to “send an email with what was found”, even though the user only asked for an answer.
  • RAG hits on anomalous documents. In retriever telemetry, newly uploaded or low-reputation documents appear being retrieved for multiple queries.

These signals are useful because in real incidents the discussion often gets stuck on “the model went crazy”. No: the model followed instructions and the system allowed it to act without friction.

Credential theft: it’s not always “steal AWS keys”, sometimes it’s stealing access

When people talk about credential theft in cloud, many think of static keys. In modern architectures, the attacker’s real goal can be simpler: obtain data that enables escalation or use the agent’s own role as a proxy. A PDF can induce the agent to search for “configuration” or “connections” and end up leaking connection strings, tokens in pipeline files, or results from internal tools.

There are two very concrete business impacts. First, exfiltration of “accidental” secrets that live in storage (for example, a .env uploaded by a test team, or a dump with users). Second, abuse of the output channel: the attacker doesn’t need to see the agent’s screen; it’s enough for the agent to send the content to an external recipient or to a controlled webhook.

Design mistakes that open the door to this theft:

  • Single and persistent identity for many use cases. A single role/identity for “the agent” means that any prompt injection has the maximum blast radius. In an enterprise, this turns a logical vulnerability into a cross-cutting incident.
  • Data access “for convenience” instead of by intent. Allowing read access to an entire bucket or an entire database, instead of specific views/paths, makes exfiltration a matter of enumerating and selecting.

In both cases, the attacker is not exploiting a provider bug (Bedrock/Azure OpenAI/Vertex), but a permissions decision and action-control decision in your application layer.

How to do it in practice: harden IAM so RAG can’t “improvise” reads

The most effective mitigation starts outside the prompt: in permissions. If the agent only needs to read a subset of curated documents, don’t give it permission to list/read the entire bucket. In AWS, the operational pattern is: a specific bucket/prefix for the “approved” RAG corpus, with no access to the rest. If the agent also needs to attach documents, enforce that it can only read objects with a tag/metadata of “allow-rag=true”.

Example IAM policy (conceptual and trimmed) to restrict reads to a specific prefix and prevent global enumeration. Adjust ARNs and conditions to your environment:

  • Allow only s3:GetObject on a curated prefix. This prevents an injection from leading the agent to read “whatever it finds” outside the RAG zone. Operationally, it’s the change that cuts the most incidents.
  • Control s3:ListBucket with s3:prefix. If the agent needs to list, limit it to the prefix; otherwise, remove List and force access by exact key delivered by your retriever.

Example (AWS IAM) for an agent role:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListOnlyRagPrefix",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mi-bucket-docs",
"Condition": {"StringLike": {"s3:prefix": ["rag-approved/*"]}}
},
{
"Sid": "ReadOnlyApprovedObjects",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::mi-bucket-docs/rag-approved/*"
}
]
}

Validation in AWS: check in CloudTrail that the agent role does not do ListBucket on prefixes outside rag-approved/; test queries designed to provoke enumeration (“search for credentials”, “list everything”) and verify that the agent fails due to permissions, not due to “goodwill”. In internal reviews, this type of test shows that the control is technical and does not depend on the LLM “behaving well”.

If the agent also sends emails, separate identities: one identity only for RAG reads and another, distinct one, for output actions, with an intermediate broker that enforces rules (allowed recipients, domains, attachment size, and blocking of sensitive content). The practical idea is to reduce dangerous combinations: broad read + free output.

Recommendations for corporate environments

Indirect Prompt Injection in RAG becomes serious when retrieved content can order actions and the runtime has broad permissions. The malicious document does not “break” the cloud: it gets the agent to use legitimate credentials to read more than it should and send it out through an allowed channel.

The most solid fix is architectural: minimal and segmented permissions (curated prefixes/buckets, restricted views instead of full sources), and explicit control of output actions. When the design forces the agent to access only what is strictly necessary, an injection remains a manipulation attempt without real ability to exfiltrate.

Finally, in day-to-day operations, monitor the agent role as if it were a high-risk service account: changes in List/Get patterns, anomalous document retrieval, and unsolicited sends are actionable signals. That makes it possible to detect the “RAG + injection + permissions” combination before it turns into a data leak or theft of operational credentials.


Interested in Cloud Security?

Technical analysis, hands-on labs and real-world cloud security insights.

Privacy policy