Storage driver
STORAGE_DRIVER and the filesystem driver: Oxagen's blob storage without a Vercel Blob token.
Overview
Binary assets (avatars, generated images, video, and documents, and uploaded workspace
files) go through @oxagen/storage, one adapter interface with two
drivers. One environment variable picks the driver:
STORAGE_DRIVER=vercel-blob # default — requires BLOB_READ_WRITE_TOKEN
STORAGE_DRIVER=fs # local filesystem — no token requiredThe row that references the stored object (URL and metadata) stays in Postgres. Only the bytes move between drivers.
vercel-blob (default)
The production driver, backed by Vercel Blob. It requires BLOB_READ_WRITE_TOKEN.
When this driver is selected and the token is missing, storage calls throw an
error at startup that names it.
fs: the filesystem driver
The filesystem driver stores bytes on local disk instead of Vercel Blob, with no credential. Use it for local development, or in a CI or e2e container that has no Blob token.
STORAGE_DRIVER=fs
STORAGE_FS_ROOT=/tmp/oxagen-storage # optional — see default below| Variable | Required | Default |
|---|---|---|
STORAGE_DRIVER | No | vercel-blob |
STORAGE_FS_ROOT | No | An absolute path under the OS temp directory (<tmpdir>/oxagen-storage) |
Why the default root is an absolute temp path, not a path relative to cwd:
the app (next start, cwd = apps/app) and the API (tsx, cwd = repo root)
run as separate processes with different working directories. Both must
resolve to the SAME directory, or an object one process writes is
invisible to the other. An absolute path makes them match, and the temp directory is
writable inside the CI e2e container. A relative STORAGE_FS_ROOT works,
but it resolves against process.cwd(), so use it only for
a single-process script.
Path safety. The driver confines every object key to the storage root. It rejects an
absolute key, a key with .. traversal, and a key with a null byte
before any file operation runs. A key cannot read or write outside
STORAGE_FS_ROOT.
Adding a driver
To add a third storage driver, implement the StorageAdapter interface, add
the driver name to the STORAGE_DRIVER enum in packages/config/src/env.ts,
and add a case in packages/storage/src/client.ts that reads that driver's
own environment variables. Each driver's credentials stay separate, so adding one
never touches another's configuration.
Local development
How Oxagen detects a developer machine through OXAGEN_LOCAL_DEV and relaxes deployed-only controls the same way every time, and which signals must stay out of deployment configuration.
Connect GitHub
Connect GitHub to your workspace so Oxagen can ingest repository and delivery metadata and open governed pull requests, without uploading your source-code graph.