Skip to content

Security Model

Disponible en francais

This document ties together the stack’s security posture for secrets, Cloudflare, AI agents, user data, and production changes.

Agents may help build and operate systems, but they should not directly hold broad authority. Give agents context and narrow capabilities, not raw credentials or irreversible control.

Security trust boundaries

BoundaryWhat crosses itRule
User/browser → appuser input, files, auth statevalidate server-side, sanitize output
App → Cloudflare resourcesD1/R2/KV/Queues/DO bindingsleast-privilege bindings per environment
App → AI providersprompts, retrieved context, tool resultsroute through AI Gateway where possible
Agent → repocode/docs/scriptsreviewable diffs, tests, protected paths
Agent → Cloudflaredeploy/mutation requestsbroker/CI/resource-scoped token
Agent → email/user commsdrafts, tasks, proposed sendsqueue + policy + approval for risky sends
CI → productiondeploys, migrations, DNSprotected environments and audit logs

Secrets live in Infisical, Bitwarden Secrets Manager, Cloudflare Worker secrets, or CI secret storage. They do not live in prompts, docs, issues, PRs, checked-in .env files, or browser bundles.

Allowed in Git:

  • variable names
  • placeholder values
  • .env.example
  • non-secret config
  • infisical.json project references, if it contains no secret values

Not allowed in Git:

  • provider API keys
  • Cloudflare API tokens
  • OAuth client secrets
  • database dump files with production data
  • .dev.vars with real values
  • private keys or certificates

Cloudflare platform credentials are high risk because they can mutate infrastructure and data.

Rules:

  • never use the Global API Key
  • use one token per project/environment/job
  • use resource-scoped policies whenever available
  • isolate deploy, D1 migration, R2 upload, DNS, and read-only analytics tokens
  • require human approval for production D1 migrations, DNS edits, Worker route changes, and destructive data operations
  • prefer GitHub Actions or a deploy broker for production mutations

See Cloudflare API Tokens.

Every product repo should use automated dependency monitoring plus an audit gate. Prefer Renovate with security-sensitive labels for auth/RPC/ORM packages, and run pnpm audit --audit-level high in CI.

Security-sensitive packages require explicit review before major upgrades:

  • better-auth and @better-auth/*: stay on the latest stable 1.6.x line or newer security-patched stable line.
  • @orpc/*: keep patched for serializer/deserializer advisories.
  • drizzle-orm / drizzle-kit: stay on patched 0.44.x for client work until the v1 stable migration plan is written.

Patch and minor security updates should be reviewed quickly. Major version bumps to auth, RPC, ORM, or deployment tooling are never drive-by cleanups.

Provider keys control spend and model/data access. They should be treated separately from deploy tokens.

Preferred production path:

Worker/TanStack AI
→ Cloudflare AI Gateway route
→ stored provider key / BYOK
→ provider

This lets code reference approved routes while developers and agents cannot read raw keys. Add gateway budgets/rate limits before enabling autonomous loops.

Use direct Worker secrets only for unsupported providers/workflows or local development, and document why.

Agent permission ladder

Agents should get capabilities in this order:

  1. read-only docs/config
  2. local repo edits
  3. local build/test commands
  4. safe broker scripts
  5. CI workflow dispatch with protected environments
  6. temporary break-glass credentials only with explicit human approval

Agents should not:

  • receive broad Cloudflare account tokens
  • edit .env, .dev.vars, secret stores, or backup exports
  • directly send production email
  • silently run production migrations
  • edit DNS without explicit approval
  • access production user data unless the task requires it and a safer sample cannot answer the question

Any external content can be hostile: webpages, emails, PDFs, GitHub issues, Slack messages, user uploads, and database rows.

Defenses:

  • treat retrieved text as data, not instructions
  • keep system/developer instructions separate from retrieved content
  • require allowlisted tools for external-content workflows
  • summarize and validate before executing actions suggested by external content
  • never let untrusted content choose recipients, commands, resource IDs, or secret names without app validation

Use the smallest dataset that proves the point.

Data typeDefault handling
Production user dataavoid locally; use sampled/redacted fixtures
Uploaded filesscan/size-limit; store in R2 with scoped access
Logsredact secrets, tokens, cookies, auth headers
Backupsencrypt, store separately, never expose to agents by default
Analyticsaggregate before sharing with agents when possible

Production-impacting actions need at least one hard gate:

  • reviewed PR
  • protected GitHub environment
  • explicit workflow_dispatch
  • deploy broker approval
  • typed policy file validating target resources
  • backup/snapshot before destructive mutation

Before shipping a project:

  • .env, .env.*, .dev.vars, dumps, and backups are ignored
  • secret scan passes
  • Cloudflare deploy token is resource-scoped
  • DNS token is separate from deploy token
  • D1 migration flow has approval/backup for production
  • AI provider keys are behind AI Gateway BYOK or documented exception
  • gateway budgets/rate limits exist for agent loops
  • email sending goes through app policy/queue
  • tests cover auth and permission boundaries
  • logs redact auth headers, cookies, tokens, and secrets