mybasev1.0.21

Storage (S3)

Use a project's S3 bucket with any S3 client; serve public files from the public/ prefix.

Every project has a bucket on Garage, an S3-compatible store. mybase project create prints the endpoint, region (garage), bucket, access key id, and secret key (once).

Use it from an app

Any S3 client works. Use path-style addressing:

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: process.env.S3_REGION, // "garage"
  forcePathStyle: true,
  credentials: { accessKeyId: process.env.S3_ACCESS_KEY_ID!, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY! },
});

await s3.send(new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: "public/logo.png", Body: bytes }));

Bun's built-in S3Client and aws4fetch work too.

Public files

Objects whose key starts with public/ are readable by anyone at:

https://mybase.example.com/storage/<project>/public/<rest of key>

Everything else needs the S3 credentials (or a presigned URL from your app).

Public files are served from the same origin as the dashboard, so they're sandboxed: every response has X-Content-Type-Options: nosniff and Content-Security-Policy: … sandbox. Types a browser could run or render as a page (HTML, SVG, XML, JavaScript, WebAssembly, or no type at all) are sent as application/octet-stream downloads instead. Images, video, audio, fonts, PDFs, CSS, JSON, and text are shown inline as usual. To show an SVG, serve it from your app or convert it to PNG.

Browse files

Dashboard → Storage, or GET /projects/<p>/files?prefix=<folder/> with storage:read (MCP list_files).

Security

  • Everything under public/ is readable by anyone. Keep private files elsewhere and serve them through your app.
  • Keep S3 keys server-side; use presigned URLs for browser uploads. Over the internet, use the tunnel's HTTPS endpoint, not raw :3900.

More: Security best practices.

Agent notes

  • The bucket name is the project name with _ replaced by -.
  • Set forcePathStyle: true (AWS SDK) or the client tries <bucket>.<host> and fails.
  • Through a Cloudflare Tunnel, single requests over 100 MB fail; use multipart uploads.
  • HTML/SVG/JS under public/ download instead of rendering (security). Don't host a website from the bucket.

On this page