Aurabase Logo
aurabasedocs
docs›Guides›Store and serve files (SDK)

Store and serve files with the JavaScript SDK

The everyday flows of `aura.storage`, with the access rules observed against a running stack.

8 min read·Level intermediate·Revised on Oct 12, 2026
This English text was generated automatically from the French original and has not been reviewed yet.
#
Buckets

1. Buckets

A bucket groups files and decides whether they are public. Creating and deleting buckets needs a service_role key. Listing them needs a signed-in user or a service_role key; the public key alone gets 403.

server/buckets.tstypescript
await admin.storage.createBucket('avatars', { public: true })   // anyone can read the files
await admin.storage.createBucket('invoices', { public: false })  // only their owner can
const { data: buckets } = await admin.storage.listBuckets()

A bucket also accepts fileSizeLimit (in bytes) and allowedMimeTypes. An upload that is too large returns 413, and a type that is not allowed returns 400.

#
Files

2. Upload, download, list, remove

files.tstypescript
const bucket = aura.storage.from('invoices')

// Upload: a Blob, a File or an ArrayBuffer
const { data, error } = await bucket.upload(`${user.id}/2026-10.pdf`, file, {
  contentType: 'application/pdf',
})
// → { key, bucket, url, size, content_type, etag }

// Replace an existing file
await bucket.upload(`${user.id}/2026-10.pdf`, newFile, { upsert: true })

// List a folder, download, remove
const { data: files } = await bucket.list(user.id)
const { data: blob } = await bucket.download(`${user.id}/2026-10.pdf`)
await bucket.remove([`${user.id}/2026-10.pdf`])

What to expect:

  • Uploading an existing path returns 409 unless you pass upsert: true.
  • Uploading needs a signed-in user or a service_role key. The public key alone gets 403, even for a public bucket.
  • A path with .. is refused with 400.
  • Paths are shared inside a bucket. If another user already has the path, you get 409. Put each user's files under their own folder, such as ${user.id}/….
#
Share

3. Share a file

share.tstypescript
// A file in a public bucket: a permanent URL, built without a request
const { data } = aura.storage.from('avatars').getPublicUrl('ada.png')
// → { publicUrl: 'https://my-app.aurabase.cloud/v1/storage/avatars/ada.png' }

// A private file: a temporary link
const { data: signed } = await aura.storage.from('invoices').createSignedUrl(`${user.id}/2026-10.pdf`, 60)
// → { url, expires_in: 60 }

Both links were fetched without any key and returned the file. A signed link stops working after expires_in seconds. To let a browser upload without a key, a server mints createSignedUploadUrl(path) (a service_role call).

#
Access

4. Who can do what

ActionPublic keySigned-in userservice_role
Read a file in a public bucketyesyesyes
Read, list a file in a private bucketnoits owner onlyyes
Uploadnoyesyes
Replace or remove a filenoits owner onlyyes
List bucketsnoyesyes
Create, delete bucketsnonoyes

The owner is the user who uploaded the file. In a real run, a second user could not list, download or remove the first user's file in a private bucket, and could not replace it either.

#
Server

5. Move and copy, from a server

server/organise.tstypescript
await admin.storage.copy('invoices', 'a/hello.txt', 'a/copy.txt')
await admin.storage.move('invoices', 'a/copy.txt', 'a/moved.txt')
const { data: meta } = await admin.storage.getMetadata('invoices', 'a/hello.txt')

Image resizing is described in the storage reference.

Last updated · Oct 12, 2026