Skip to main content
All projects
Infrastructure & DevOps
/projects/merchant-platform

Multi-Tenant Merchant Platform

project.merchant-platform.local
Multi-Tenant Merchant Platform project screenshot
  1. Problem:

    FTP ingress was a bottleneck with frequent downtime, costing clients money.

  2. Solution:

    Built a 99.99% available multi-tenant SFTP gateway with automated AWS provisioning.

  3. Impact:

    Zero unplanned downtime; supports 500+ merchants simultaneously.

Overview

Multi-tenant SFTP ingress with automated provisioning and strong isolation so merchant onboarding doesn't compromise reliability.

Results & metrics

  • 99.99% platform availability
  • $40k/year AWS cost reduction
  • 500+ merchants with zero unplanned downtime
  • Automated tenant provisioning in <5 minutes

Before / after

  • Ingress reliability

    Before: Fragile FTP paths, painful incidents

    After: Standardized SFTP gateway with automated fleet patterns

  • Scale

    Before: Onboarding friction for new tenants

    After: 500+ concurrent merchants supported

  • Tenant Security

    Before: Shared storage buckets risking cross-tenant data exposure

    After: Strict IAM prefix isolation per merchant with KMS per-tenant keys

What I built

Chroot-jailed SFTP gateway

Merchants share one SFTP gateway on EC2, each jailed to its own folder by chroot.

Automated tenant provisioning

A supplier's new feed auto-creates user, password and chroot, in under 5 minutes.

VPC endpoints for S3

S3 traffic moved off the NAT Gateway onto VPC endpoints; AWS costs fell $40k/year.

Stack

  • AWS Transfer Family, SFTP
  • Amazon S3, with KMS Encryption
  • AWS Lambda, Ingestion Router
  • Amazon DynamoDB
  • Terraform IaC

Decisions

Key trade-offs and design calls that shaped the final delivery.

  • EC2 over managed SFTP

    Why
    Context
    AWS Transfer Family was expensive for multi-tenant use case with many users
    Decision
    Self-managed SFTP on EC2 with custom user isolation logic using chroot—significantly lower cost for high user count
  • chroot over containerization

    Why
    Context
    Needed lightweight isolation without Docker overhead on a single EC2 instance
    Decision
    Linux-level chroot jails with chmod for directory restrictions—simpler, lower resource footprint than containers

Architecture

The primary system boundaries, runtime pieces, and how the project was structured in production.

Diagram, 8 connections:
  1. External Merchants → AWS Transfer SFTP Gateway
  2. AWS Transfer SFTP Gateway → IAM Role & Key Authentication
  3. IAM Role & Key Authentication → DynamoDB Tenant Registry
  4. AWS Transfer SFTP Gateway → Lambda Ingestion Router
  5. Lambda Ingestion Router → S3 Bucket: Tenant Prefixes
  6. Lambda Ingestion Router → SQS Batch Queue
  7. SQS Batch Queue → Payment Settlement Workers
  8. Payment Settlement Workers → S3 Processed Archive
Groups: Merchant Ingestion: External Merchants, AWS Transfer SFTP Gateway; Tenant Isolation & Metadata: IAM Role & Key Authentication, DynamoDB Tenant Registry, Lambda Ingestion Router; Encrypted Object Store: S3 Bucket: Tenant Prefixes, S3 Processed Archive; Downstream Settlement: SQS Batch Queue, Payment Settlement Workers.
  • AWS EC2 SFTP Server

    FTP Gateway

    How

    Self-managed SFTP on EC2 with chroot jail isolation—merchants and suppliers connect to shared infrastructure with strict boundaries.

  • chroot + chmod

    Tenant Isolation

    How

    Linux-level chroot jails enforce directory boundaries—merchants cannot escape their dedicated folders, access controlled at OS level.

  • Auto-generated credentials

    Credential Management

    How

    1 supplier can have multiple merchants. Only suppliers can create passwords and users. Custom feed creation generates user/password pairs auto-assigned to respective tenant directories, shareable with specific suppliers.

Mermaid source

Paste into mermaid.live to edit the diagram.

flowchart TB
  subgraph Client [Merchant Ingestion]
    M[External Merchants]
    SFTP[AWS Transfer SFTP Gateway]
  end
  subgraph Routing [Tenant Isolation & Metadata]
    AUTH[IAM Role & Key Authentication]
    DYNAMO[(DynamoDB Tenant Registry)]
    ROUTER[Lambda Ingestion Router]
  end
  subgraph Storage [Encrypted Object Store]
    S3RAW[(S3 Bucket: Tenant Prefixes)]
    S3PROC[(S3 Processed Archive)]
  end
  subgraph Pipeline [Downstream Settlement]
    SQS[SQS Batch Queue]
    WORKER[Payment Settlement Workers]
  end
  M --> SFTP
  SFTP --> AUTH
  AUTH --> DYNAMO
  SFTP --> ROUTER
  ROUTER --> S3RAW
  ROUTER --> SQS
  SQS --> WORKER
  WORKER --> S3PROC

Pipeline

How changes moved from development through validation and deployment.

Select a step for its detail

Incidents

Operational failures, rehearsals, or recovery moments that changed how the system was run.

  • P1

    API endpoints exposed without authentication

    Resolution

    Implemented private API authentication and integrated with backend for proper access control

    Lesson: All APIs must be authenticated by default—never assume internal-only access is safe

  • P2

    Backend integration breaking on user creation

    Resolution

    Standardized API contracts and added validation for supplier-merchant relationship creation

    Lesson: Multi-tenant systems need strict relationship validation between entities