Skip to content

Security: sivaprakashtech/GrowthPilot-AI

Security

docs/SECURITY.md

Security

Threat Model

GrowthPilot AI is a multi-tenant SaaS platform handling business-critical data (client PII, financial records, API credentials). The primary threats are:

  1. Tenant data leakage — one workspace accessing another's data
  2. Credential exposure — API keys, OAuth tokens, payment data
  3. Unauthorized access — privilege escalation within a workspace
  4. Injection attacks — SQL injection, XSS, CSRF

Defense-in-Depth Layers

Layer 1: Network (Transport)

  • HSTS enforced (max-age 2 years, includeSubDomains, preload)
  • All connections via HTTPS (Vercel terminates TLS at edge)
  • Supabase connections use TLS 1.3

Layer 2: Authentication

Mechanism Implementation
Email/password Supabase Auth with bcrypt hashing (server-side)
OAuth Google, GitHub via PKCE flow
Magic Link OTP via email; 5-minute expiry
MFA (TOTP) Supabase Auth MFA with challenge/verify flow
Session tokens httpOnly, SameSite=Lax cookies via @supabase/ssr
JWT verification Middleware calls getUser() (server-validated, not just decoded)

Layer 3: Authorization (RBAC)

  • 4 system roles: owner > admin > editor > viewer
  • 35 granular permissions mapped to roles
  • Server-side enforcement via requirePermission() / hasWorkspaceRole()
  • Database-level enforcement via RLS policies on every table

Layer 4: Data Isolation (Multi-Tenancy)

  • Row-Level Security (RLS) enabled on all 70+ tables
  • Helper functions (is_workspace_member, has_workspace_role) use SECURITY DEFINER to prevent infinite recursion
  • Organization → workspace → member hierarchy with cascading deletes
  • No application-code-only tenant filtering — RLS is the source of truth

Layer 5: API Security

  • Public API keys: SHA-256 hashed before storage; raw key shown exactly once at creation
  • Key prefix format (gp_live_) for easy identification without exposing the full key
  • Scope-based authorization per key
  • Expiration and revocation support
  • Rate limiting: 100 requests/minute per key

Layer 6: Webhook Security

  • Stripe: HMAC signature verification via constructEvent()
  • Shopify: Timing-safe HMAC comparison (crypto.timingSafeEqual)
  • All inbound webhook endpoints validate signatures before processing

Layer 7: HTTP Headers

X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Powered-By: (removed)

Layer 8: Input Validation

  • All user inputs validated with Zod schemas in server actions
  • UUID format enforcement for entity IDs
  • String length limits on all text fields
  • Enum constraints for status/type fields

Layer 9: Secret Management

Secret Storage Access Pattern
Supabase keys Env vars (Vercel secrets) getServerEnv() with Zod validation
Service role key Env var + server-only guard createAdminClient() — cannot be imported from client
OAuth tokens integrations.credentials JSONB (RLS admin-only) Auto-refreshed before expiry
API key raw values Never stored — SHA-256 hash only Shown once at creation
Stripe webhook secret Env var Used only in webhook route

Layer 10: Audit Trail

  • audit_logs table records all security-sensitive operations
  • Actor ID, action, entity type/ID, old/new values, IP address, timestamp
  • Admin-only read access (RLS enforced)
  • Immutable — no UPDATE or DELETE policies for regular users

Vulnerability Disclosure

Report security vulnerabilities to: security@growthpilot.ai

We commit to:

  • Acknowledging receipt within 24 hours
  • Providing a timeline within 72 hours
  • Not pursuing legal action for good-faith research

Compliance Considerations

Standard Status Notes
OWASP Top 10 Addressed Injection (Zod + RLS), Auth (Supabase), XSS (React escaping), CSRF (SameSite cookies)
SOC 2 Type II Infrastructure-level via Supabase + Vercel Application-level audit logging in place
GDPR Data isolation + soft deletes Data export/erasure endpoints can be built on the existing framework
PCI DSS Delegated to Stripe No card data touches GrowthPilot servers

Security Checklist for Deployment

  • Verify RLS is enabled on every table (Supabase dashboard → Tables)
  • Confirm SUPABASE_SERVICE_ROLE_KEY never appears in client bundles
  • Test HSTS header with curl -I https://yourdomain.com
  • Run supabase db lint to check for tables missing RLS
  • Verify Stripe webhook signature in test mode before going live
  • Enable Supabase Auth email rate limiting in dashboard
  • Review OAuth redirect URIs — no wildcards

There aren't any published security advisories