Skip to content

Security Architecture, Threat Modeling & Row-Level Security ​


1. Executive Summary & Security Philosophy ​

Debelu manages student commerce, digital escrow, bank accounts, and personal identification data. The platform implements a Zero-Trust Defense-in-Depth Architecture:

  1. Never Trust the Client: All financial calculations, fee determinations, delivery state transitions, and identity assertions execute server-side or inside database stored procedures.
  2. Fail-Closed Security: Any configuration ambiguity, unrecognized campus alias, or stale revision triggers an immediate 403 Forbidden (42501) or 409 Conflict (40001).
  3. Storage-Engine Isolation: Data protection does not rely solely on application middleware. PostgreSQL Row-Level Security (RLS) policies enforce cryptographic and user-bound isolation at the database layer.

2. STRIDE Threat Model & Marketplace Defenses ​

The system architecture addresses threats mapped across the STRIDE methodology:

STRIDE Threat CategoryMarketplace Attack VectorArchitectural MitigationCodebase Implementation
Spoofing IdentityAttacker forges JWT or impersonates another campus vendor.Cryptographically signed Supabase JWTs with auth.uid() binding; dynamic role degradation engine.[auth.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/middleware/auth.ts)
Tampering with DataBuyer tampers with product price or modifies category commission.Immutable fee_snapshot JSON frozen at checkout; client prices ignored; server queries DB.[db-order-fee-snapshot-checks.mjs](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/scripts/db-order-fee-snapshot-checks.mjs)
RepudiationVendor claims delivery was made; buyer falsely claims non-receipt.Secret 4-digit Delivery PIN displayed only on buyer screen; atomic PIN verification trigger.[escrow-lifecycle.md](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/docs/architecture/escrow-lifecycle.md)
Information DisclosureCampus operator inspects orders or customer data from another university.Scoped tenant isolation via admin_roles.campus_scope text[]; cross-campus queries return 0 rows.[CampusOrderService.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/services/CampusOrderService.ts)
Denial of ServiceFlooding checkout intents or exhausting LLM tokens.Tiered IP and user rate limiters; 7-layer Nduzi optimization caching; BullMQ concurrency caps.[rateLimiters.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/middleware/rateLimiters.ts), [aiRateLimiter.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/middleware/aiRateLimiter.ts)
Elevation of PrivilegeCompromised staff account attempts unilateral fee or balance modification.The 4-Eyes Principle (Maker-Checker); AAL2 MFA enforcement; table privilege revocations.[PlatformConfigurationProposalService.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/services/PlatformConfigurationProposalService.ts)

3. Row-Level Security (RLS) Policy Matrix ​

PostgreSQL RLS ensures that even if an application SQL injection vulnerability occurs, data isolation remains impenetrable at the engine layer:

mermaid
graph TD
    subgraph Client Roles
        ANON[anon role]
        AUTH_USER[authenticated role: Buyer / Vendor]
        SERVICE[service_role - Background Workers]
    end

    subgraph RLS Execution Gate
        RLS{PostgreSQL RLS Evaluator}
    end

    subgraph Tables & Isolations
        PROD[(public.products<br/>Public SELECT if status='active')]
        ORD[(public.orders<br/>Isolated by user_id or vendor_id)]
        WALLET[(public.user_private_info<br/>Isolated by id = auth.uid())]
        AUDIT[(public.audit_logs<br/>Append-only; Direct mutation revoked)]
    end

    ANON --> RLS
    AUTH_USER --> RLS
    SERVICE -->|BYPASSRLS| ORD

    RLS -->|USING status='active'| PROD
    RLS -->|USING user_id = auth.uid()| ORD
    RLS -->|USING id = auth.uid()| WALLET
    RLS -->|DENIED to authenticated| AUDIT

3.1 Policy Specifications ​

TableOperationTarget RolePolicy DefinitionSecurity Rationale
productsSELECTanon, authenticatedstatus = 'active'Unapproved, draft, or quarantined items remain invisible to public queries.
ordersSELECTauthenticateduser_id = auth.uid() OR vendor_id = auth.uid()Prevents IDOR (Insecure Direct Object Reference); buyers and sellers only see their own transactions.
ordersUPDATEauthenticatedDENIEDDirect updates to order total, status, or campus are rejected. All mutations mandate Security Definer RPCs.
user_private_infoSELECTauthenticatedid = auth.uid()Users can only inspect their own wallet balance and private financial ledger.
payout_requestsINSERTauthenticatedvendor_id = auth.uid() AND auth.jwt()->>'role' = 'vendor'Only verified merchants can initiate withdrawal requests.
audit_logsINSERT/UPDATE/DELETEALLREVOKEDImmutable append-only audit trail; mutations rejected at PostgreSQL engine level.

4. API Perimeter Defenses ​

Backend services on Fly.io are fortified with defense-in-depth HTTP middlewares:

mermaid
graph LR
    REQ[Inbound HTTP Request] --> HELMET[Helmet Security Headers]
    HELMET --> CORS[CORS Origin Whitelist]
    CORS --> RATE[Tiered Rate Limiter]
    RATE --> IDEMP[Idempotency Middleware]
    IDEMP --> CIRCUIT[Circuit Breakers]
    CIRCUIT --> VALIDATE[Zod Schema Validator]
    VALIDATE --> HANDLER[Domain Route Handler]

4.1 Security Headers (Helmet & CSP) ​

  • Content-Security-Policy: Strict script-src with dynamic cryptographic nonces ([vite.csp-nonce.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/apps/storefront/vite.csp-nonce.ts)). Prevents Cross-Site Scripting (XSS) and malicious third-party script injection (Magecart defense).
  • Strict-Transport-Security: max-age=63072000; includeSubDomains; preload (enforces HSTS).
  • X-Frame-Options: DENY across API and admin; SAMEORIGIN on storefront.
  • X-Content-Type-Options: nosniff.

4.2 Idempotency Middleware (idempotency.ts) ​

Financial POST endpoints mandate an Idempotency-Key header:

  1. When a key is received, Redis acquires an exclusive distributed lock (TTL: 120s).
  2. If a duplicate request arrives while processing $\to$ Returns 409 Conflict ("Operation in progress").
  3. When processing completes $\to$ Cached response status and body are saved in Redis (TTL: 24h).
  4. Subsequent identical requests return the cached response immediately without re-debiting funds or duplicating orders.

4.3 Circuit Breakers (circuitBreakers.ts) ​

Protects backend infrastructure from cascading failure when upstream services (Paystack, Gemini AI, Resend) degrade:

  • Failure Threshold: Trips open after 5 consecutive failures or timeouts ($> 15\text{s}$).
  • Half-Open Probe: Tests upstream recovery with canary traffic after a 60-second cooldown window.
  • Fallbacks: Gracefully degrades UI features (e.g., switches campus orders to pickup payment, disables AI chat tools) while maintaining platform uptime.

5. Webhook Integrity & Replay Mitigation ​

Inbound webhooks (Paystack, WhatsApp Business API) undergo cryptographic verification before entering application memory:

  • Timing-Safe HMAC Verification: crypto.timingSafeEqual prevents timing attacks on SHA-512 signatures.
  • Replay Protection: The database maintains a unique constraint on processed_webhook_events(event_id). If Paystack retries a webhook that has already committed, the database detects the collision and returns HTTP 200 without re-executing escrow locks or balance updates.

6. Secret Isolation & Environment Segmentation ​

Debelu enforces zero secret leakage across client and server boundaries:

  • Client Bundles: Storefront and marketing codebases access ONLY environment variables prefixed with VITE_ or NEXT_PUBLIC_ (e.g., VITE_SUPABASE_ANON_KEY, VITE_PAYSTACK_PUBLIC_KEY).
  • Server-Only Secrets: PAYSTACK_SECRET_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_JWT_SECRET, and GEMINI_API_KEY are provisioned strictly as encrypted runtime machine secrets on Fly.io.
  • CI/CD Validation: Automated pre-commit hooks and GitHub Actions workflows run static analysis scans to detect and prevent accidental secret commits.

Released under Proprietary Enterprise License.