Your Cloud Database is a Security Theater

Published: (January 15, 2026 at 01:03 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

The Problem with Traditional Multi‑Tenant SaaS Storage

Multi‑tenant SaaS storage is fundamentally compromised at the architectural level. Vendors promise row‑level security, tenant IDs in every query, and encryption at rest, but a single SQL injection or privilege‑escalation vulnerability can expose all tenants’ data. One breach can affect thousands of victims.

Traditional SaaS Architecture

┌─────────────────────────────────┐
│      Application Layer          │
│  (trusted, handles isolation)   │
└─────────────────────────────────┘

┌─────────────────────────────────┐
│  Database (ALL tenant data)     │
│  WHERE tenant_id = ?            │
└─────────────────────────────────┘
  • A single missing WHERE clause, a compromised API endpoint, or an IDOR flaw compromises every tenant.
  • “Encryption at rest” is ineffective because the encryption keys reside on the same system that serves queries. It only protects against physical theft, not attackers with database access.

BSFS: Cryptographic Isolation at the Storage Layer

BSFS (Block Storage File System) eliminates shared databases and trust boundaries inside the application. If you don’t have the key, the data doesn’t exist.

Core Concepts

  • No shared databases – each tenant works with its own encrypted partition.
  • Cryptographic isolation – metadata and data are encrypted with tenant‑specific keys; there are no access‑control checks needed.

Atomic Commit via Encrypted Block Allocation Table (BAT)

  1. Allocate random block addresses.
  2. Write new file data to those blocks.
  3. Update the encrypted BAT.
  4. Mark old blocks free.

The BAT update is the commit point. If a process crashes mid‑write, readers continue to see the old file; new blocks become garbage. No corruption, no partial writes, no “eventually consistent” nonsense.

// The atomic commit point
bsfs_encrypt_bat(partition_key, bat, encrypted_bat);
fseek(blob_file, partition_offset, SEEK_SET);
fwrite(encrypted_bat, sizeof(bsfs_bat_t), 1, blob_file);
fflush(blob_file);
// Transaction committed. Readers see new file.
  • Crash before fwrite → old file intact.
  • Crash after fwrite → new file committed.

Key Derivation

Each tenant receives a master key. Partition keys are derived via HKDF:

Master Key → HKDF(partition_id) → Partition Key
  • The master key can derive any partition key.
  • Partition keys cannot derive sibling keys.

This provides true cryptographic isolation, not just access‑control checks.

Random Block Allocation

BSFS deliberately randomizes block placement using a Fisher‑Yates shuffle. Files are scattered across the partition, preventing attackers from inferring file structure or relationships through block‑access patterns.

What BSFS Is (and Isn’t)

Not a Replacement For

  • PostgreSQL or any relational database
  • Distributed filesystems
  • Key‑value stores
  • Systems optimized for millions of tiny files or range queries

Intended Use Cases

  • True tenant isolation
  • Atomic file updates
  • Encrypted metadata
  • Predictable performance for SaaS application storage

Think of it as encrypted object storage (e.g., S3 buckets with cryptographic boundaries) rather than rows with tenant_id columns.

API Examples

C Example

uint8_t master_key[32];
bsfs_tenant_t tenant;

bsfs_tenant_init(&tenant, "storage.blob", master_key);
bsfs_write_file(&tenant, file_id, data, size);
bsfs_read_file(&tenant, file_id, &data, &size);
bsfs_delete_file(&tenant, file_id);
bsfs_tenant_cleanup(&tenant);

Python Example

from bsfs import BSFS, generate_master_key
import uuid

master_key = generate_master_key()
with BSFS('storage.blob', master_key) as fs:
    file_id = uuid.uuid4()
    fs.write_file(file_id, b'confidential data')
    data = fs.read_file(file_id)
    fs.delete_file(file_id)

Operational Limits

  • 64 files per partition
  • 512 MiB max file size (2 MiB blocks × 256 blocks)
  • Single‑partition implementation (multi‑partition planned)
  • No streaming I/O – full file is loaded into memory
  • Single‑threaded

When to Use BSFS

  • Building a multi‑tenant SaaS product
  • Regulatory compliance requires strict data isolation
  • Past experience with row‑level security bugs
  • Need provable cryptographic boundaries for files, documents, or blobs

When Not to Use BSFS

  • Need relational queries or complex joins
  • Storing millions of tiny records
  • Requiring distributed consensus or high‑availability replication
  • Threat model does not include database compromise

Cost Comparison

Cloud databases charge for IOPS, storage, and compute. BSFS runs on local NVMe, uses raw disk I/O, and encrypts only metadata. You avoid:

  • Database connection overhead
  • Query optimizer runtime
  • Replication lag
  • “Serverless” markup fees
  • Per‑tenant database instances

A single 2 TB NVMe drive can serve dozens of tenants with true cryptographic isolation for less than the cost of a single managed RDS instance per month.

Conclusion

Most security in SaaS is enforced by access‑control lists—social conventions. BSFS makes cross‑tenant data access cryptographically impossible, not merely unauthorized. This returns to first principles after decades of compromised shortcuts.

Further Resources

  • Video walkthrough (implementation, copy‑on‑write semantics, encrypted metadata)
  • Source code repository:
Back to Blog

Related posts

Read more »

Rapg: TUI-based Secret Manager

We've all been there. You join a new project, and the first thing you hear is: > 'Check the pinned message in Slack for the .env file.' Or you have several .env...

Technology is an Enabler, not a Saviour

Why clarity of thinking matters more than the tools you use Technology is often treated as a magic switch—flip it on, and everything improves. New software, pl...