← AdHorde|Security Architecture
Infrastructure Security

Built for advertisers
who don't take risks.

Your ad accounts generate real revenue. We treat their security accordingly. Seven isolation layers, zero password storage, AES-256 at rest, TLS 1.3 in transit. This is the architecture.

Auth.js v5 + Upstash

Authentication, sessions & rate limiting

Meta Marketing API

Official platform OAuth v21.0

Supabase / AWS RDS

AES-256 encrypted data at rest

Cloudflare

DDoS protection & rate limiting

Vercel Edge

TLS 1.3 global CDN delivery

Stripe

PCI DSS Level 1 payments

Defense in Depth

Seven security layers, end-to-end.

Each layer independently mitigates a distinct threat surface. Compromising one doesn't compromise the next.

01
IDENTITY LAYERAuth.js v5 + Upstash

Zero-trust authentication

Every session is authenticated via Auth.js v5 (NextAuth) — enforcing HS256-signed JWTs stored exclusively in httpOnly, Secure, SameSite=Lax cookies. Credentials are validated server-side against bcrypt hashes; Google OAuth uses the official PKCE flow. Brute-force lockouts are enforced at the route layer via Upstash Redis rate limiting — 5 attempts per email per minute, 20 per IP per minute, with fail-open on Redis outage. Unverified emails are blocked from accessing the dashboard.

  • JWT session stored in httpOnly + Secure cookie — invisible to JavaScript
  • bcrypt (cost 12) password hashing — no plaintext ever stored
  • Google OAuth via official PKCE flow — we never see your Google password
  • Upstash Redis rate limiting: 5 attempts/min per email, 20/min per IP
  • Email verification required before dashboard access
02
PLATFORM OAUTHMeta Marketing API

Official Meta OAuth — zero passwords stored

When you connect your Meta ad account, we initiate Meta's official OAuth 2.0 Marketing API flow. You authenticate directly on Meta's domain — we never see your password. The resulting access token is stored server-side as an httpOnly, Secure, SameSite=Lax cookie — invisible to JavaScript, immune to XSS injection. The same token is also persisted server-side in your isolated database row as a backup. You can revoke access from Meta's Security Settings at any time.

  • Official Meta Marketing API v21.0 — zero unofficial API calls
  • Scoped permissions: ads_management, ads_read, business_management
  • httpOnly + Secure cookie — tokens are XSS-unreachable by design
  • Dual persistence: cookie + server-side DB — no single point of failure
  • Instant revocation from Meta Security Settings
03
DATA AT RESTAWS eu-west-1

AES-256 encryption on AWS RDS

All user data is stored in Supabase PostgreSQL running on AWS infrastructure in eu-west-1 (Ireland). AWS RDS enforces AES-256-XTS encryption on every storage volume by default — keys managed via AWS KMS with automatic annual rotation. Our service role key, the only credential that can bypass row-level policies, lives exclusively in server-side environment variables — it has never touched a client bundle or browser context.

  • AES-256-XTS block-level encryption on all RDS volumes
  • AWS KMS key management — hardware-backed HSM key storage
  • eu-west-1 (Ireland) data residency — within the EU
  • Row-level user_id scoping on every query — logical tenant isolation
  • Service role key is server-only — never shipped to any client
04
TRANSPORT SECURITYVercel + Cloudflare

TLS 1.3 end-to-end. Every request.

All traffic between your browser and AdHorde's edge traverses Cloudflare and Vercel's global network over TLS 1.3 — the latest protocol, with removed legacy cipher suites, 0-RTT resumption guards, and perfect forward secrecy via ECDHE key exchange. HTTP Strict Transport Security headers with a 1-year max-age ensure your browser never falls back to plaintext. Every plaintext HTTP request is permanently redirected to HTTPS at the edge.

  • TLS 1.3 enforced — TLS 1.0/1.1 blocked at the edge
  • ECDHE key exchange — each session key is ephemeral
  • Perfect Forward Secrecy — past sessions can't be decrypted if keys leak
  • HSTS with 1-year max-age — browser enforces HTTPS preload
  • Certificate pinning via Vercel's managed cert infrastructure
05
ABUSE PREVENTIONCloudflare Network

Rate limiting and DDoS mitigation

Every API endpoint enforces per-IP rate limiting at the application layer, backed by Cloudflare's global anycast network absorbing volumetric attacks before they reach our origin. The AI copilot endpoint limits to 20 requests per minute per IP. Campaign creation, credit operations, and automation writes all have independent limits. Requests that exceed limits receive a 429 with a Retry-After header — they're never queued for delayed execution.

  • Per-IP rate limiting on every API endpoint independently
  • AI chat: 20 req/min — campaign create, credits, automation: separate limits
  • Cloudflare anycast DDoS absorption before origin contact
  • Bot detection and challenge pages for suspicious traffic patterns
  • 429 hard-stop with Retry-After — no silent queuing or degraded execution
06
PAYMENT SECURITYStripe PCI DSS L1

PCI DSS Level 1 via Stripe — card data never touches us

All payment processing is delegated to Stripe — a PCI DSS Level 1 Service Provider, the highest certification tier possible. Your card number, CVV, and expiry date are captured directly by Stripe's JavaScript SDK on Stripe's domain and are tokenized before any data reaches our servers. What we receive is a Stripe token reference, never raw card data. Webhook events are validated via HMAC-SHA256 signature verification on every delivery — spoofed events are cryptographically impossible to forge.

  • Stripe PCI DSS Level 1 — independently audited annual compliance
  • Card data tokenized at source — our servers never process raw PANs
  • Stripe.js handles card capture directly in Stripe's iframe context
  • Webhook HMAC-SHA256 signature validation — every event verified
  • Stripe customer IDs are the only payment reference stored in our DB
07
AUDIT & OBSERVABILITYPostgreSQL + CF KV

Every action logged. Immutably.

Admin operations generate immutable audit log entries in PostgreSQL: action type, timestamp (UTC), admin user ID, target user ID, email, and a full JSON diff of what changed. Automation rule events — rule created, edited, fired, paused, deleted — are logged in Cloudflare KV with millisecond-precision timestamps. Both logs are write-append-only from the application layer — there is no delete endpoint exposed to admin users.

  • Admin audit log: action, timestamp, admin ID, target ID, full change diff
  • Automation event log: every rule create, fire, pause, delete — per user
  • Cloudflare KV persistence — automation logs survive origin restarts
  • Write-only append pattern — no delete exposed at the application layer
  • Log export available: CSV download from the Automation Logs page

Data Handling

What we store. What we don't. Why.

We Store

  • Your email + nameRequired for account creation and Auth.js session
  • Stripe customer IDPayment reference only — no card data
  • Meta access tokenhttpOnly cookie + server-side DB, never in client JS
  • Campaign metadataRead from Meta API, displayed in your dashboard only
  • Subscription statePlan, credits, billing cycle — for feature gating
  • Admin audit eventsWho changed what and when — compliance only

We Never Store

  • Your Meta passwordOAuth only — not even technically possible
  • Raw card numbers (PANs)Stripe tokenizes before we see anything
  • Audience or customer listsWe never read targeting or audience data
  • Ad creative filesWe reference Meta CDN URLs, never host assets
  • Targeting demographicsWe don't access or store who you target
  • User behavior dataNo session recording, no keystroke logging

Infrastructure

Every vendor, enterprise-grade.

We don't build security from scratch — we compose it from best-in-class providers, each with independent third-party audits.

Auth.js v5 + Upstash Redis

Authentication & Rate Limiting

Self-hosted
  • httpOnly + Secure JWT session cookie — no client JS access
  • bcrypt cost-12 password hashing
  • Google OAuth PKCE flow — zero password exposure
  • Upstash Redis: 5 req/min per email, 20/min per IP on sign-in

AWS RDS (via Supabase)

Database

AWS Certified
  • AES-256-XTS encryption at rest
  • AWS KMS HSM-backed key management
  • eu-west-1 (Ireland) — EU data residency
  • Automated daily backups with point-in-time recovery

Stripe

Payments

PCI DSS Level 1
  • PCI DSS Level 1 Service Provider
  • Annual QSA audit by independent assessor
  • Card data never leaves Stripe's iframe context
  • HMAC-SHA256 webhook signature validation

Cloudflare + Vercel

Edge & CDN

Edge Network
  • TLS 1.3 enforced globally — older protocols blocked
  • ECDHE key exchange — perfect forward secrecy
  • Anycast DDoS mitigation at network layer
  • HSTS preload — browsers refuse HTTP connections
Responsible Disclosure

Found a vulnerability?

We take security reports seriously. If you've identified a vulnerability in our platform, please disclose it responsibly. We'll acknowledge your report within 24 hours and keep you updated throughout the resolution process.

Report a Vulnerability →

contact@adhorde.com · We respond within 24 hours