Skip to main content
BunShip provides an S3-compatible file storage service that works with AWS S3, Cloudflare R2, MinIO, and any S3-compatible provider. Files are scoped to organizations with metadata tracked in the database and binary data stored in your chosen object store.

Upload Flow

Upload a file by passing the binary data along with organization and metadata options:
API call:

What happens during upload

1

Size validation

The file is checked against MAX_FILE_SIZE (default: 50 MB). Empty files are rejected.
2

Filename sanitization

The filename is cleaned to prevent path traversal and restricted to safe characters:
3

S3 key generation

Files are stored with an organization-scoped key to ensure tenant isolation:
4

Upload to S3

The file is uploaded with the appropriate MIME type and cache headers.
  • Public files: Cache-Control: public, max-age=31536000 (1 year)
  • Private files: Cache-Control: private, no-cache
5

Database record

A record is created in the files table with the file ID, S3 key, bucket, size, MIME type, and metadata.

Response

Storage Backends

BunShip uses the AWS SDK S3Client, which supports any S3-compatible service. Configure the backend through environment variables:
The S3 client is initialized once at startup:

Presigned URLs

Generate time-limited download URLs for private files. The default expiration is 15 minutes:
API call:
Response:
The URL grants temporary read access without requiring authentication. Expired files return a 404 Not Found error.

File Management

List files

Retrieve files for an organization with optional MIME type filtering and pagination:

Get file metadata

Returns the database record without downloading the binary data. Use getSignedUrl to generate a download link.

Delete files

BunShip supports both soft delete and hard delete:
Soft-deleted files are excluded from list queries by default. Pass includeDeleted: true to include them.

Check existence

Verify a file exists in both the database and S3:

Path Traversal Protection

Filenames are sanitized before use as S3 keys. The service strips directory traversal sequences and restricts characters:
Files are stored under an organization-specific prefix ({orgId}/{fileId}/{name}), which prevents one organization from accessing another’s files even if a collision were to occur.

Temporary Files

Upload files with an expiration time for temporary use cases like export downloads or preview links:
Expired files are automatically cleaned up by the background jobs system every 6 hours.

Configuration