AI Security

Protecting Customer Documents in an AI Summarization Workflow with Cloudflare Workers AI

TL;DR: Store raw documents in Cloudflare R2 with bucket‑level encryption, use short‑lived signed URLs for the Workers AI request, enforce strict IAM policies, log every access, and delete the file immediately after the summary is generated.

Why a Dedicated Threat Model Matters

Even though Cloudflare Workers AI abstracts the model behind an HTTP endpoint, the data you send travels through the same edge network that serves your public site. A mis‑configured bucket or an overly permissive API token can expose confidential contracts, medical records, or financial statements to anyone who discovers the URL.

Step 1 – Store Documents in an Encrypted R2 Bucket

Create a dedicated R2 bucket for raw files. Enable bucket‑level encryption (AES‑256‑GCM) and disable public read access. Use a separate bucket for generated summaries so that the two data sets never share the same access policy.

Step 2 – Generate Short‑Lived Signed URLs

When a user uploads a document, generate a signed URL that expires after a few minutes (e.g., 300 seconds). The signed URL is the only value you pass to the Workers AI POST /v1/ai/summarize endpoint. This limits the window an attacker has to replay the request.

const url = await R2.getSignedUrl(bucket, key, { expiresIn: 300 })
await fetch('https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/run', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${AI_TOKEN}` },
  body: JSON.stringify({
    model: 'claude-3-5-sonnet',
    prompt: `Summarize the document at ${url}`
  })
})

Step 3 – Apply Least‑Privilege IAM Policies

Follow the principle of least privilege when creating API tokens:

Reference the official token‑scoping guide: Cloudflare API Tokens.

Step 4 – Secure the Prompt Itself

Never embed the raw document content in the prompt. Always reference the signed URL and add a clear instruction to the model not to retain the content. Example prompt:

Summarize the PDF located at {signed_url}. Do not store any part of the document after generating the summary.

This mitigates prompt‑injection attempts that try to trick the model into echoing the file.

Step 5 – Log Every Access Event

Use Cloudflare Logs (or a downstream logging service) to record:

  1. Upload event – user ID, bucket, object key, timestamp.
  2. Signed‑URL generation – token ID, expiry, IP address.
  3. AI request – model used, request ID, response status.
  4. Deletion event – object key, who performed the delete.

Store logs in an immutable bucket or a SIEM that complies with your audit requirements.

Step 6 – Delete the Source File Immediately After Summarization

Once the summary is stored, issue a DELETE request to the raw‑file bucket. Verify the delete succeeded before returning the summary to the user. This reduces the attack surface for any later breach.

Step 7 – Periodic Review and Rotation

Every 30 days rotate the API tokens used for the summarization flow. Re‑run a script that checks for any tokens with broader scopes than required and revoke them.

Putting It All Together – A Minimal Worker Script

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const { userId, fileKey } = await request.json()
  const signedUrl = await R2.getSignedUrl('raw-docs', fileKey, { expiresIn: 300 })
  const aiResp = await fetch('https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/ai/run', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${AI_TOKEN}` },
    body: JSON.stringify({
      model: 'claude-3-5-sonnet',
      prompt: `Summarize the document at ${signedUrl}. Do not retain any content.`
    })
  })
  const summary = await aiResp.json()
  await R2.put('summaries', `${fileKey}.txt`, summary.output)
  await R2.delete('raw-docs', fileKey) // immediate cleanup
  await logEvent(userId, fileKey, 'summarized')
  return new Response(JSON.stringify({ summary: summary.output }), { status: 200 })
}

Key Takeaways

Following these steps lets a solo founder or a five‑person startup leverage Cloudflare Workers AI without turning customer documents into a liability.

FAQ

Need a practical AI security review?

AISecAll reviews prompts, tool permissions, document flows, and agent behavior so small teams can use AI without guessing where the risk sits.

Book a call Discuss a project