Docs

Preview Vault Architecture (Option 1)

Back to docs

Preview Vault stores only encrypted content. The server never sees plaintext.

Data layout in MinIO/S3

projects/
  <projectId>/
    project.json       # Project metadata + PBKDF2 salt
    manifest.enc       # Encrypted manifest wrapper (iv + ciphertext)
    files/
      <fileId>         # Encrypted file bytes

Project metadata (project.json)

Unencrypted fields used for bootstrapping decryption.

  • projectId: Unique project ID.
  • projectName: Optional label for the UI.
  • salt: Base64 PBKDF2 salt to derive the AES-GCM key.
  • createdAt: ISO timestamp.

Manifest (manifest.enc)

JSON wrapper with two fields:

  • iv: Base64 AES-GCM IV for the manifest payload.
  • ciphertext: Base64 encrypted manifest payload.

The decrypted manifest contains:

  • version: Schema version.
  • projectId, projectName, createdAt.
  • files: Array of files with name, type, size, and per-file IV.

Crypto choices

  • Key derivation: PBKDF2 (SHA-256, 250k iterations).
  • Encryption: AES-GCM (256-bit) with random 12-byte IVs.
  • Where encryption happens: In the browser/CLI before upload.

API responsibilities

  • Create project metadata.
  • Issue presigned upload URLs.
  • Store encrypted manifest.
  • Serve encrypted blobs back to the viewer.

No plaintext is handled by the server.

GitHub sync (automation)

The GitHub Action downloads preview-sync.js from /api/preview-sync on every push to a selected folder. It encrypts files in the runner and posts ciphertext + manifest to /api/sync. The Preview Vault server stores the encrypted blobs in MinIO and serves them back to viewers.

Sync requests authenticate with a per-project sync token stored (hashed) in Postgres. Only ciphertext is transmitted.

Auth + database

NextAuth with GitHub OAuth is used for authentication. Project metadata, collaborators, and sync logs are stored in Postgres via Prisma.

Security levels

  • ZERO_TRUST: passphrase never stored.
  • LOCAL_DEVICE: passphrase stored in the browser only.
  • TEAM_SHARED: per-user encrypted project keys stored in Postgres.
  • SERVER_MANAGED: passphrase encrypted with PROJECT_KEY_SECRET.
  • PUBLIC_LINK: server-managed passphrase available via a public endpoint.