Skip to content

Security: osiahpitt/Qala

Security

docs/SECURITY.md

🔐 Security Policy

This document outlines security practices, credential management, and incident response procedures for the QALA project.


Credential Management

Development vs Production Separation

CRITICAL: Never use production credentials in development!

Environment Supabase Project Purpose Who Has Access
Development qala-dev (separate project) Local testing, feature development All developers
Production qala-production Live users, real data Admin only (@osiah)

Credential Storage

✅ ALLOWED:

  • .env.local (gitignored, never committed)
  • server/.env (gitignored, never committed)
  • GitHub Secrets (for CI/CD)
  • Vercel/Railway environment variables (encrypted)
  • Password managers (1Password, Bitwarden, etc.)

❌ FORBIDDEN:

  • Committing .env files to git
  • Sharing credentials via email/Slack/Discord
  • Hardcoding secrets in source code
  • Storing secrets in documentation files
  • Uploading .env files to cloud storage

Credential Rotation Schedule

Credential Type Rotation Frequency How to Rotate
Supabase API Keys Every 90 days Dashboard → Settings → API → Reset
JWT Secrets Every 180 days Generate new: openssl rand -base64 32
Stripe API Keys On developer offboarding Dashboard → Developers → Roll keys
Database Passwords Every 90 days Supabase → Settings → Database → Reset password
Google Translate API Every 90 days Google Cloud Console → Regenerate
Webhook Secrets On breach only Service provider dashboard

Set calendar reminders for credential rotation!


Access Control

Repository Access Levels

Level Permissions Who Gets This
Admin Full access, settings, secrets, force push @osiah (project owner)
Maintainer Write access, merge PRs, cannot change settings Core team members (trusted)
Contributor Read-only, submit PRs via fork External developers, new team members
None No access Public, former team members

Granting Access

New Developer Onboarding:

  1. Initial Setup (Day 1):

    • Add as Contributor (read-only)
    • Provide development .env.example template
    • Share development Supabase credentials ONLY
    • No production access
  2. After 2 Approved PRs:

    • Upgrade to Maintainer (if core team)
    • Still no production credentials
  3. Never Share:

    • Production .env.local
    • Production Supabase service_role key
    • Stripe live API keys
    • Admin dashboard access

Revoking Access

Developer Offboarding Checklist:

  • Remove from GitHub repository (Settings → Collaborators)
  • Revoke Supabase Dashboard access (if granted)
  • Rotate shared development credentials
  • Rotate production credentials if developer had access
  • Review audit logs for last 30 days
  • Check for any backdoors or suspicious commits
  • Remove from team communication channels
  • Deactivate any service accounts created for developer

Branch Protection Rules

These MUST be enabled on GitHub:

Go to: Settings → Branches → Add rule for main branch

Required Settings:

✅ Require pull request before merging
  ✅ Require approvals: 1
  ✅ Dismiss stale pull request approvals when new commits are pushed
  ✅ Require review from Code Owners

✅ Require status checks to pass before merging
  ✅ Require branches to be up to date before merging
  Status checks:
    - lint
    - type-check
    - test
    - build

✅ Require conversation resolution before merging

✅ Require signed commits (recommended)

✅ Include administrators (IMPORTANT: Even owner must follow rules)

✅ Restrict who can push to matching branches
  Add: @osiah (admin only)

❌ Allow force pushes: Nobody
❌ Allow deletions: Disabled

Why this matters: Without branch protection, CODEOWNERS is useless. Anyone can push directly to main and bypass security.


Pre-commit Hooks

Automatically enforced via Husky on every commit:

Security Checks:

  • detect-secrets - Scans for API keys, passwords, tokens
  • env-file-check - Blocks commits containing .env files
  • secret-scan - Pattern matching for hardcoded secrets

Code Quality:

  • ESLint - Code linting
  • Prettier - Code formatting
  • TypeScript - Type checking

Bypassing Hooks:

# ⚠️ DANGEROUS - Only use for emergencies
git commit --no-verify

# Better approach: Fix the issue
npm run lint:fix
npm run format

If you need to bypass: Ask yourself why. Usually there's a better solution.


Incident Response Plan

If Credentials Are Exposed

IMMEDIATE ACTIONS (within 1 hour):

  1. Assess Scope:

    # Check what was exposed
    git log --all --full-history -- '*.env*'
    git log -p --all --full-history -- '*.env*' | grep -i "key\|secret\|password"
  2. Rotate ALL Exposed Credentials:

    • Supabase: Dashboard → Settings → API → Reset service_role key
    • Stripe: Dashboard → Developers → Roll keys
    • Google: Cloud Console → Regenerate API key
    • JWT: Generate new: openssl rand -base64 32
  3. Update Production:

    • Vercel: Settings → Environment Variables
    • Railway: Variables tab
    • Restart all services after updating
  4. Remove from Git History (if committed):

    # ⚠️ DANGEROUS - Creates new history, requires force push
    git filter-branch --force --index-filter \
      "git rm --cached --ignore-unmatch path/to/.env" \
      --prune-empty --tag-name-filter cat -- --all
    
    # Force push to remote (requires admin)
    git push origin --force --all
  5. Revoke Old Credentials:

    • Immediately disable/delete old keys in service dashboards
    • Don't wait for rotation period

WITHIN 24 HOURS:

  1. Audit Recent Access:

    • Supabase: Dashboard → Logs → Filter by time range
    • Stripe: Dashboard → Logs
    • Check for unauthorized API calls
  2. Review Recent Commits:

    git log --since="2 days ago" --all --oneline
    # Look for suspicious changes
  3. Notify Stakeholders:

    • If user data was potentially accessed: Notify users (GDPR/CCPA requirement)
    • Document incident in docs/incidents/YYYY-MM-DD.md
  4. Post-Mortem:

    • How did credentials get exposed?
    • What safeguards failed?
    • How to prevent in future?

If Suspicious Activity Detected

Signs of Compromise:

  • Unexpected database queries in logs
  • New admin accounts created
  • Unusual API usage patterns
  • Failed login attempts from unknown IPs
  • Unexpected deploys or code changes

Response:

  1. Lock Down Access:

    • Enable GitHub 2FA requirement for all team members
    • Rotate all production credentials
    • Temporarily disable API access if needed
  2. Investigate:

    • Review Supabase auth logs
    • Check GitHub audit log
    • Review Vercel/Railway deploy logs
    • Check for backdoors in recent commits
  3. Document:

    • Create incident report
    • Timeline of events
    • Root cause analysis
    • Prevention measures

Security Best Practices

For Developers

DO:

  • ✅ Use .env.local for all local credentials
  • ✅ Create separate Supabase project for development
  • ✅ Run pre-commit hooks before pushing
  • ✅ Review your changes before committing (git diff)
  • ✅ Use strong, unique passwords for all services
  • ✅ Enable 2FA on GitHub, Supabase, Stripe, etc.
  • ✅ Keep dependencies updated (npm update)
  • ✅ Report security issues privately (see below)

DON'T:

  • ❌ Commit .env files (even if "just testing")
  • ❌ Share credentials via insecure channels
  • ❌ Use production database for development
  • ❌ Hardcode API keys in source code
  • ❌ Disable security checks "temporarily"
  • ❌ Bypass pre-commit hooks
  • ❌ Share your development .env with others

Code Review Security Checklist

Before approving a PR:

  • No hardcoded secrets or API keys
  • No .env files added
  • Authentication checks in place for new API routes
  • Database queries use parameterized queries (no SQL injection)
  • User input is validated (XSS prevention)
  • Rate limiting applied to new endpoints
  • No sensitive data logged to console
  • Dependencies reviewed (no suspicious packages)
  • Tests include security scenarios
  • Documentation updated if security-related

Dependency Security

Automated Scanning:

# Check for known vulnerabilities
npm audit

# Fix automatically if possible
npm audit fix

# For manual review
npm audit --json > audit-report.json

GitHub Dependabot:

  • Automatically creates PRs for security updates
  • Review and merge promptly
  • Don't ignore security advisories

Before Adding New Dependencies:

  1. Check npm package age and downloads
  2. Review GitHub repository (stars, issues, last commit)
  3. Check for known vulnerabilities: npm audit
  4. Review package code if critical (e.g., authentication)
  5. Prefer well-maintained, popular packages

Reporting Security Issues

Found a security vulnerability?

DO NOT:

  • ❌ Create a public GitHub issue
  • ❌ Post on Slack/Discord
  • ❌ Discuss publicly

DO:

  1. Email security report to: [your-security-email@qalatalk.com]
  2. Include:
    • Description of vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if any)
  3. Wait for response (within 48 hours)
  4. We'll work with you on fix and disclosure timeline

Responsible Disclosure:

  • We'll acknowledge report within 48 hours
  • We'll provide fix timeline within 1 week
  • We'll credit you in CHANGELOG (if desired)
  • We'll notify affected users if needed

Compliance & Regulations

GDPR (EU Users)

User Rights:

  • Right to access their data
  • Right to deletion (implemented via API)
  • Right to data portability (export feature)
  • Right to be informed (privacy policy)

Implementation:

  • Data retention: 30 days for chat logs, indefinite for profiles
  • Data export: API endpoint /api/users/export
  • Data deletion: API endpoint /api/users/delete
  • Privacy policy: /privacy page

CCPA (California Users)

User Rights:

  • Right to know what data is collected
  • Right to delete data
  • Right to opt-out of data sales (N/A - we don't sell data)

Implementation:

  • Same endpoints as GDPR
  • "Do Not Sell" disclosure in privacy policy

Data Protection

What We Store:

  • User profiles (name, email, languages, age, gender, country)
  • Session history (duration, ratings, quality metrics)
  • Vocabulary saved by users
  • Reports submitted by users

What We DON'T Store:

  • Video call recordings (peer-to-peer only)
  • Chat transcripts (deleted after 30 days)
  • Payment details (handled by Stripe)
  • Biometric data
  • Government ID scans

Encryption:

  • All data encrypted at rest (Supabase default)
  • All connections use TLS/SSL
  • Database passwords hashed
  • Service role keys never exposed to client

Security Monitoring

What We Monitor

Supabase Logs:

  • Failed authentication attempts
  • Unusual query patterns
  • Rate limit violations
  • Database errors

Application Logs:

  • API errors (via Sentry)
  • User reports
  • Session failures
  • Translation API quota usage

Infrastructure:

  • Deploy failures (GitHub Actions)
  • SSL certificate expiration (Vercel auto-renews)
  • Uptime monitoring (Vercel Analytics)

Alerts

Immediate Alerts (Slack/Email):

  • Production deployment failures
  • Database connection errors
  • High error rates (>5% of requests)
  • Unusual spikes in traffic

Daily Digest:

  • New user signups
  • Session completion rates
  • Translation quota usage
  • Error summary

Security Checklist for Production

Before deploying to production:

Infrastructure:

  • Separate Supabase project for production
  • All production credentials rotated (never use dev credentials)
  • Branch protection enabled on main
  • GitHub 2FA required for all team members
  • Vercel environment variables set correctly
  • Railway environment variables set correctly
  • SSL certificates active (auto-configured)
  • Rate limiting configured (Redis)
  • CORS properly configured

Database:

  • RLS policies enabled on all tables
  • Database backups configured (Supabase Pro)
  • Connection pooling enabled
  • SSL connections enforced
  • Service role key secured (never exposed to client)

Application:

  • No console.logs in production code
  • Error messages don't leak sensitive info
  • All API routes require authentication
  • Input validation on all forms
  • XSS protection enabled (CSP headers)
  • CSRF tokens on state-changing requests
  • Rate limiting on authentication endpoints

Monitoring:

  • Sentry configured for error tracking
  • PostHog configured for analytics (optional)
  • Uptime monitoring active
  • Alert channels configured

Compliance:

  • Privacy policy published
  • Terms of service published
  • Cookie consent banner (if using cookies)
  • Data export API tested
  • Data deletion API tested
  • GDPR compliance documented

Emergency Contacts

Role Contact Responsibility
Security Lead @osiah Credential rotation, incident response
Database Admin @osiah Supabase, backups, RLS policies
DevOps @osiah Vercel, Railway, deployments

External Services:


Audit Log

Date Action Performed By Reason
YYYY-MM-DD Credential rotation @osiah Quarterly schedule
YYYY-MM-DD Branch protection enabled @osiah Security hardening
YYYY-MM-DD Developer offboarded @osiah Team change

Maintain this log for compliance and incident response.


Additional Resources


Last Updated: 2025-09-29 Review Schedule: Quarterly Next Review: 2025-12-29

There aren't any published security advisories