Security

Security is not a feature we added. It's the way we built everything else.

Encryption at rest

Every secret stored in Fülkit's database is encrypted with AES-256-GCM — the same standard used by banks, governments, and security-critical infrastructure.

OAuth tokens, API keys, and refresh tokens are encrypted before they touch the database. Even if someone breached the database directly, they'd get ciphertext — not keys.

Format: base64(iv):base64(authTag):base64(ciphertext) — 12-byte random IV per encryption, 128-bit authentication tag, AES-256-GCM authenticated encryption.

Encryption in transit

All traffic to fulkit.app is HTTPS-only. There are no plaintext endpoints. API routes, OAuth callbacks, webhook receivers — everything runs over TLS.

Authentication

  • Google OAuth with PKCE — prevents authorization code interception
  • Server-validated tokens — every API request verified server-side via JWT signature and expiry
  • Fresh-token pattern — client fetches a fresh token before every API call. No stale tokens, no replay window
  • No dev mode bypass in production

Row-level security

Every user-facing table in the database has RLS policies. Users can only read and write their own data — enforced at the database level, not just the application layer.

Even if an API route had a bug, RLS prevents cross-user data access.

Rate limiting

Every API route is rate-limited to prevent abuse. Limits are enforced via distributed Redis — shared across all serverless instances. Limits survive deploys, cold starts, and instance scaling.

Chat15 req/min
Checkout5 req/min
Referrals3 req/min
API keys5 req/min
All other routes60 req/min

Content Security Policy

Fülkit enforces a strict CSP that controls what the browser is allowed to load.

  • Scripts — only from fulkit.app and required SDKs. No eval()
  • Connections — only to fulkit.app's own API. The browser never talks to third-party APIs directly
  • Framing — frame-ancestors 'none'. Prevents clickjacking

Prompt injection defense

User-provided data is injected into AI prompts as context — never as instructions.

  • XML isolation boundaries separate user data from system instructions
  • Explicit instruction boundary tells the AI to never follow directives found inside user data
  • System prompts are assembled server-side. The client sends messages — the server decides what context to include

Webhook integrity

Payment webhooks are verified using HMAC-SHA256 with timing-safe comparison. Unverified payloads are rejected. No exceptions.

Data deletion

Users can delete all their data through Settings. Messages, conversations, actions, notes, preferences, integrations — atomic cascade, scoped by user. When you delete, it's gone.

What we don't do

  • We don't store passwords — authentication is delegated to Google OAuth
  • We don't log API keys, tokens, or secrets to any file, console, or monitoring service
  • We don't make client-side calls to third-party APIs — everything routes through our server
  • We don't trust user-provided data as instructions — context is context, not code
  • We don't retain data after deletion — when you delete, it's gone

Contact

Questions about security? Reach us at security@fulkit.app