Skip to main content

Security Architecture

Security Architecture

Overview

Security is a fundamental aspect of the MOOD MNKY ecosystem, designed to protect user data, business operations, and system integrity. Our security architecture follows industry best practices and implements multiple layers of protection.
Our security approach is based on the principle of defense in depth, with multiple security controls distributed throughout the application stack.

Security Principles

Zero Trust Model

All access requests are fully authenticated, authorized, and encrypted regardless of source

Least Privilege

Users and services have the minimum permissions necessary to perform their functions

Defense in Depth

Multiple layers of security controls throughout the architecture

Secure by Design

Security considerations integrated into the development lifecycle from the beginning

Authentication System

Our authentication system is built on Supabase Auth, providing secure user authentication across all MOOD MNKY applications.
  • Authentication Methods
  • Implementation
// Available authentication methods
export const authMethods = {
  email: {
    enabled: true,
    requiresVerification: true,
  },
  oauth: {
    google: {
      enabled: true,
      clientId: process.env.GOOGLE_CLIENT_ID,
      redirectUrl: process.env.GOOGLE_REDIRECT_URL,
    },
    apple: {
      enabled: true,
      clientId: process.env.APPLE_CLIENT_ID,
      redirectUrl: process.env.APPLE_REDIRECT_URL,
    },
  },
  passwordless: {
    enabled: true, // Magic link authentication
  },
  mfa: {
    enabled: true, // Multi-factor authentication
    methods: ['totp', 'sms'],
  },
}

Authorization Model

Authorization is implemented through a combination of role-based access control (RBAC) and row-level security (RLS) in Supabase.

Role-Based Access Control

// User roles
export enum UserRole {
  CUSTOMER = 'customer',
  ADMIN = 'admin',
  SUPPORT = 'support',
  CONSULTANT = 'consultant',
}

// Permission mapping
export const permissions = {
  [UserRole.CUSTOMER]: {
    products: ['read'],
    orders: ['read', 'create'],
    account: ['read', 'update'],
    consultations: ['read', 'book'],
  },
  [UserRole.ADMIN]: {
    products: ['read', 'create', 'update', 'delete'],
    orders: ['read', 'update', 'cancel'],
    users: ['read', 'create', 'update', 'delete'],
    consultations: ['read', 'update', 'delete'],
    analytics: ['read'],
  },
  [UserRole.SUPPORT]: {
    orders: ['read', 'update'],
    users: ['read'],
    consultations: ['read', 'update'],
  },
  [UserRole.CONSULTANT]: {
    consultations: ['read', 'update'],
    customers: ['read'],
    products: ['read'],
  },
}

// Authorization hook
export function useAuthorization() {
  const { user } = useAuth()
  
  const hasPermission = (resource, action) => {
    if (!user) return false
    
    const role = user.app_metadata?.role || UserRole.CUSTOMER
    return permissions[role]?.[resource]?.includes(action) || false
  }
  
  return {
    hasPermission,
    isAdmin: user?.app_metadata?.role === UserRole.ADMIN,
    isSupport: user?.app_metadata?.role === UserRole.SUPPORT,
    isConsultant: user?.app_metadata?.role === UserRole.CONSULTANT,
  }
}

Row-Level Security Policies

-- Example RLS policies for the orders table

-- Enable RLS on the orders table
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;

-- Customers can only view their own orders
CREATE POLICY "Customers can view their own orders"
ON public.orders
FOR SELECT
USING (auth.uid() = user_id);

-- Customers can only create orders for themselves
CREATE POLICY "Customers can create orders for themselves"
ON public.orders
FOR INSERT
WITH CHECK (auth.uid() = user_id);

-- Admins can view all orders
CREATE POLICY "Admins can view all orders"
ON public.orders
FOR SELECT
USING (
  EXISTS (
    SELECT 1 FROM public.users
    WHERE users.id = auth.uid()
    AND users.role = 'admin'
  )
);

-- Support can view all orders
CREATE POLICY "Support can view all orders"
ON public.orders
FOR SELECT
USING (
  EXISTS (
    SELECT 1 FROM public.users
    WHERE users.id = auth.uid()
    AND users.role = 'support'
  )
);

-- Admins can update all orders
CREATE POLICY "Admins can update all orders"
ON public.orders
FOR UPDATE
USING (
  EXISTS (
    SELECT 1 FROM public.users
    WHERE users.id = auth.uid()
    AND users.role = 'admin'
  )
);

-- Support can update all orders
CREATE POLICY "Support can update all orders"
ON public.orders
FOR UPDATE
USING (
  EXISTS (
    SELECT 1 FROM public.users
    WHERE users.id = auth.uid()
    AND users.role = 'support'
  )
);

Data Protection

All sensitive data is encrypted at rest using industry-standard encryption algorithms:
  • Database: Encrypted using AES-256
  • File Storage: Encrypted using server-side encryption
  • Backups: Encrypted using the same level of protection as the original data
Encryption keys are managed through a secure key management system with regular rotation.
All data transmitted between services and clients is encrypted using TLS 1.3:
  • API Endpoints: HTTPS with TLS 1.3
  • Database Connections: TLS-encrypted connections
  • Service-to-Service Communication: mTLS (mutual TLS) for authenticated and encrypted communication
We enforce HSTS (HTTP Strict Transport Security) to prevent downgrade attacks.
We follow data minimization principles:
  • Only collect data necessary for application functionality
  • Implement automated data retention policies
  • Provide users with data export and deletion capabilities
  • Use data anonymization for analytics and reporting
Example implementation:
// Example of data anonymization for analytics
function anonymizeUserData(userData) {
  return {
    // Generate a stable hash for user ID
    userHash: sha256(userData.id + process.env.ANONYMIZATION_SALT),
    
    // Retain only country information, not full address
    country: userData.address?.country,
    
    // Age bracket instead of exact age
    ageBracket: getAgeBracket(userData.birthDate),
    
    // Activity metrics
    activityMetrics: {
      orderCount: userData.orders?.length,
      lastActivityDate: userData.lastActive ? 
        new Date(userData.lastActive).toISOString().split('T')[0] : 
        null,
      preferredCategories: getTopCategories(userData.orders, 3),
    }
  }
}

Network Security

Firewall Configuration

Multi-layered firewall protection with web application firewall (WAF) for application-specific threats

DDoS Protection

CloudFlare protection against distributed denial of service attacks with traffic filtering

API Gateway Security

API rate limiting, request validation, and JWT verification at the gateway level

Network Segmentation

Isolated network segments with controlled communication paths between services

Application Security

Input Validation

// Example input validation with Zod
import { z } from 'zod'

// User input schema
const userProfileSchema = z.object({
  name: z.string().min(2).max(100),
  email: z.string().email(),
  phone: z.string().regex(/^\+?[0-9]{10,15}$/).optional(),
  birthDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
  preferences: z.object({
    newsletter: z.boolean(),
    marketingEmails: z.boolean(),
    textNotifications: z.boolean(),
  }),
})

// Validate user input
export async function updateUserProfile(req, res) {
  try {
    // Validate request body against schema
    const validatedData = userProfileSchema.parse(req.body)
    
    // Proceed with update if validation passes
    const { data, error } = await supabase
      .from('profiles')
      .update(validatedData)
      .eq('id', req.user.id)
    
    if (error) throw error
    
    return res.status(200).json({ success: true, data })
  } catch (error) {
    if (error instanceof z.ZodError) {
      // Return validation errors
      return res.status(400).json({ 
        success: false, 
        error: 'Validation error', 
        details: error.errors 
      })
    }
    
    // Handle other errors
    return res.status(500).json({ 
      success: false, 
      error: 'Server error' 
    })
  }
}

CSRF Protection

// Example CSRF protection middleware
import { csrf } from 'next-csrf'

// CSRF configuration
const csrfConfig = {
  cookieName: 'csrf-token',
  cookieOptions: {
    httpOnly: true,
    sameSite: 'strict',
    path: '/',
    secure: process.env.NODE_ENV === 'production',
  },
  secretKey: process.env.CSRF_SECRET,
}

// Create CSRF middleware
const { csrfToken, setupCSRF } = csrf(csrfConfig)

// Apply middleware to API routes
export default async function apiHandler(req, res) {
  // Initialize CSRF protection
  await setupCSRF(req, res)
  
  // Handle different HTTP methods
  switch (req.method) {
    case 'GET':
      // For GET requests, include the CSRF token in the response
      return res.status(200).json({
        csrfToken: await csrfToken(req, res),
        // Other response data
      })
    case 'POST':
    case 'PUT':
    case 'DELETE':
      // For mutation operations, CSRF token is verified automatically by the middleware
      // Continue with the handler logic
      return handleMutation(req, res)
    default:
      return res.status(405).json({ error: 'Method not allowed' })
  }
}

Content Security Policy

// Content Security Policy configuration
const cspConfig = {
  'default-src': ["'self'"],
  'script-src': ["'self'", "'unsafe-inline'", 'https://analytics.moodmnky.co'],
  'style-src': ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
  'img-src': ["'self'", 'data:', 'https://storage.moodmnky.co', 'https://res.cloudinary.com'],
  'font-src': ["'self'", 'https://fonts.gstatic.com'],
  'connect-src': [
    "'self'",
    'https://*.supabase.co',
    'https://analytics.moodmnky.co',
    'https://api.moodmnky.co',
  ],
  'frame-src': ["'self'", 'https://js.stripe.com'],
  'object-src': ["'none'"],
  'base-uri': ["'self'"],
  'form-action': ["'self'"],
  'frame-ancestors': ["'self'"],
  'upgrade-insecure-requests': [],
}

// Convert config to CSP header string
const cspString = Object.entries(cspConfig)
  .map(([key, values]) => {
    if (values.length === 0) return key
    return `${key} ${values.join(' ')}`
  })
  .join('; ')

// Add to Next.js config
module.exports = {
  async headers() {
    return [
      {
        // Apply to all routes
        source: '/(.*)',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: cspString,
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff',
          },
          {
            key: 'X-Frame-Options',
            value: 'DENY',
          },
          {
            key: 'X-XSS-Protection',
            value: '1; mode=block',
          },
          {
            key: 'Referrer-Policy',
            value: 'strict-origin-when-cross-origin',
          },
          {
            key: 'Permissions-Policy',
            value: 'camera=(), microphone=(), geolocation=()',
          },
        ],
      },
    ]
  },
}

Vulnerability Management

1

Dependency Scanning

Automated scanning of dependencies for known vulnerabilities using tools like Dependabot and Snyk.
# .github/workflows/dependency-check.yml
name: Dependency Security Scan

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    - cron: '0 0 * * 0'  # Weekly scan

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Snyk Setup
        uses: snyk/actions/setup@master
      
      - name: Node.js Setup
        uses: actions/setup-node@v3
        with:
          node-version: '20'
      
      - name: Install Dependencies
        run: npm ci
      
      - name: Snyk Test
        run: snyk test
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      
      - name: Snyk Monitor
        if: github.event_name != 'pull_request'
        run: snyk monitor
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
2

Static Application Security Testing (SAST)

Code analysis to identify security vulnerabilities in the codebase.Tools used:
  • ESLint Security Plugin
  • SonarQube
  • GitHub CodeQL
3

Dynamic Application Security Testing (DAST)

Testing the running application for security vulnerabilities.Tools used:
  • OWASP ZAP
  • Burp Suite
4

Penetration Testing

Regular penetration testing by security professionals to identify vulnerabilities.Frequency:
  • Major releases
  • Annually for the entire platform
  • After significant infrastructure changes

Secure Development Lifecycle

Security Requirements

Security requirements defined during planning phase

Threat Modeling

Systematic analysis of potential threats and vulnerabilities

Secure Coding Standards

Documented secure coding practices and guidelines

Code Reviews

Security-focused code reviews before merging

Security Testing

Automated and manual security testing

Deployment Verification

Security verification before production deployment

Incident Response

Multiple detection mechanisms are in place:
  • Real-time monitoring and alerting
  • Log analysis with anomaly detection
  • User-reported issues through support channels
  • Vulnerability disclosure program
Documented incident response procedures:
  1. Identification: Confirm and classify the incident
  2. Containment: Limit the impact of the incident
  3. Eradication: Remove the threat from the environment
  4. Recovery: Restore systems to normal operation
  5. Lessons Learned: Document findings and improve processes
Communication plan for different types of incidents:
  • Internal communication channels
  • Customer notification procedures
  • Regulatory reporting requirements
  • Public disclosure guidelines

Compliance

GDPR Compliance

  • Data processing agreements
  • Privacy impact assessments
  • User data access and deletion
  • Data breach notification procedures

PCI DSS

  • Secure payment processing
  • Cardholder data protection
  • Vulnerability management
  • Regular security assessments

SOC 2

  • Security controls documentation
  • Monitoring and alerting
  • Access control procedures
  • Change management processes

HIPAA

  • PHI data protection
  • Access controls and audit logs
  • Business associate agreements
  • Breach notification procedures

Security Training

1

Onboarding

New team members receive security training as part of onboarding, covering:
  • Security policies and procedures
  • Secure coding practices
  • Handling sensitive data
  • Reporting security concerns
2

Ongoing Education

Regular security training for all team members:
  • Quarterly security workshops
  • Monthly security bulletins
  • Security awareness campaigns
3

Role-Specific Training

Specialized training for different roles:
  • Developers: Secure coding techniques
  • DevOps: Secure infrastructure management
  • Customer Support: Data handling procedures
4

Incident Drills

Regular security incident response drills to test readiness:
  • Simulated security incidents
  • Table-top exercises
  • Post-drill reviews and improvements

Resources


For questions about our security architecture, please contact the MOOD MNKY security team.