prune.

Security model

Technical deep dive: encryption, fail-closed Shield, canary tokens, and audit findings — for teams evaluating Prune.

Quick answer

Prune protects provider API keys with AES-256-GCM encryption for vaulted provider API keys and key separation in the vault. Shield spend caps and rate limits run before every upstream call and fail closed — if policy cannot be verified, the request is blocked, not passed through.

AES-256-GCM vault encryption with key separation

When you store an OpenAI or Anthropic key in the Prune vault, we encrypt it with AES-256-GCM before writing to the database.

Key separation means the key that encrypts your provider credentials is not stored next to the ciphertext. The master key lives in a separate secrets manager; the database holds only encrypted blobs and metadata. A database-only breach does not expose plaintext API keys.

Prune API keys (prune_…) are never stored in recoverable form — only SHA-256 hashes, so a leak cannot be replayed.

Fail-closed Shield

Shield enforces rate limits, daily spend caps, model allowlists, and IP restrictions on every proxied request. Enforcement uses Redis-backed counters with atomic operations to prevent spend-cap race conditions.

Fail closed means: if Shield cannot load your policy (database timeout, Redis unavailable), the request returns an error — it does not bypass caps and call the provider. Spend caps enforced in under 10ms, before the provider call

Rejected requests include X-Prune-Shield-Code so your app can distinguish spend caps from auth failures.

Canary token injection (OWASP LLM07:2025)

Optional per-request canary tokens are embedded in system context. If the model echoes the canary in its output, Prune flags a possible system-prompt leakage event. Enable with X-Prune-Shield-Canary: true; block responses with X-Prune-Shield-Canary-Block: true.

Receipt fields: shield_canary_injected, shield_canary_leaked.

PII tokenization

When enabled, emails, phone numbers, and names are replaced with reversible placeholders before the request leaves Prune for the upstream provider. The model never sees raw PII; your app can detokenize responses if needed.

Spend cap race condition fix

Daily spend tracking uses atomic Redis INCRBYFLOAT operations so concurrent requests cannot overshoot a cap between read and write. Caps are checked before the upstream LLM call fires.

Pre-beta security audit

Before private beta, we ran an adversarial security pass across proxy routes, vault handling, and Shield enforcement. Findings included:

  • Pre-beta audit: 4 of 6 routes had Shield gaps — all fixed before private beta
  • Invalid Prune keys rejected before any upstream LLM call
  • Monthly plan limits fail closed in production on database errors
  • Constant-time API key hash verification
  • Provider keys excluded from logs and error responses

All identified Shield gaps were closed before beta users were onboarded. Report vulnerabilities to security@withprune.com.

Security policy → · How it works → · Privacy policy →