Volcano/ Docs

Storage Buckets

Buckets are containers for organizing files in Volcano Storage. Each project can have multiple buckets with different configurations and access policies.

Buckets are containers for organizing files in Volcano Storage. Each project can have multiple buckets with different configurations and access policies.

Bucket properties

PropertyTypeDescription
idUUIDUnique identifier
namestringBucket name (unique per project)
project_idUUIDParent project
file_size_limitintegerMaximum file size in bytes (null = unlimited)
allowed_mime_typesstring[]Allowed MIME types (empty = all types)
created_attimestampCreation time
updated_attimestampLast modification time

Note: Public access is controlled at the individual file level using is_public, not at the bucket level. See Policies for controlling access.

Managing buckets with the CLI

Cloud

volcano storage buckets create user-uploads
volcano storage buckets list
volcano storage buckets get user-uploads
volcano storage buckets update user-uploads --file-size-limit 20971520
volcano storage buckets update user-uploads --allowed-mime image/*
volcano storage buckets update user-uploads --clear-allowed-mimes
volcano storage buckets delete user-uploads

Local mode

volcano local storage buckets create user-uploads
volcano local storage buckets list
volcano local storage buckets get user-uploads
volcano local storage buckets update user-uploads --file-size-limit 20971520
volcano local storage buckets update user-uploads --allowed-mime image/*
volcano local storage buckets update user-uploads --clear-allowed-mimes
volcano local storage buckets delete user-uploads

Declarative bucket and policy config

volcano config deploy
volcano config deploy -f volcano-config.yaml
volcano local config deploy
volcano local config deploy -f volcano-config.yaml

volcano config deploy applies the full project configuration manifest — see the project configuration manifest reference for the complete schema. The storage-related sections look like this:

version: 1
buckets:
  - name: user-files
    file_size_limit: 10485760
    allowed_mime_types:
      - image/*
      - application/pdf
    policies:
      - name: auth-insert
        operation: INSERT
        definition: auth.uid() IS NOT NULL
      - name: owner-select
        operation: SELECT
        definition: auth.uid() = owner_id
      - name: owner-update
        operation: UPDATE
        definition: auth.uid() = owner_id
      - name: owner-delete
        operation: DELETE
        definition: auth.uid() = owner_id

If -f is omitted, the CLI auto-discovers in this order:

  • volcano/volcano-config.yaml
  • ./volcano-config.yaml

Sync behavior:

  • Buckets are never created or deleted by the manifest. Create them first (volcano storage buckets create); a manifest entry for a bucket that does not exist is skipped with a warning.
  • Existing bucket settings are updated for the fields you provide; omitted fields keep their current values.
  • When a bucket entry declares policies, the list is fully synchronized by name: policies in YAML are created or updated (a changed definition is replaced atomically, with no authorization gap), and existing policies not present in YAML are deleted. An explicit policies: [] deletes all policies.
  • Omitting the policies key leaves the bucket's policies untouched.

Example: authenticated users can read/write only their own files:

version: 1
buckets:
  - name: private-docs
    policies:
      - name: auth-insert
        operation: INSERT
        definition: auth.uid() IS NOT NULL
      - name: owner-select
        operation: SELECT
        definition: auth.uid() = owner_id
      - name: owner-update
        operation: UPDATE
        definition: auth.uid() = owner_id
      - name: owner-delete
        operation: DELETE
        definition: auth.uid() = owner_id

Example: any authenticated user can download files in a shared bucket:

version: 1
buckets:
  - name: shared-files
    policies:
      - name: auth-insert
        operation: INSERT
        definition: auth.uid() IS NOT NULL
      - name: auth-select
        operation: SELECT
        definition: auth.uid() IS NOT NULL
      - name: auth-delete-owner
        operation: DELETE
        definition: auth.uid() = owner_id

Apply with:

volcano config deploy
volcano local config deploy

Creating buckets

Buckets are created via the REST API using a service key:

curl -X POST "https://api.yourapp.com/storage/buckets" \
  -H "Authorization: Bearer $SERVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "user-uploads"
  }'

Response:

{
  "id": "bucket-abc123",
  "name": "user-uploads",
  "project_id": "project-xyz",
  "file_size_limit": null,
  "allowed_mime_types": [],
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z"
}

Bucket naming rules

  • 1-64 characters
  • Lowercase letters, numbers, hyphens, and underscores only
  • Must be unique within the project

Valid names:

  • avatars
  • user-uploads
  • public_assets
  • files-2024

Invalid names:

  • My Bucket (spaces and uppercase)
  • bucket.name (periods not allowed)
  • a (too short for meaningful names, but technically valid)

Access control

Buckets use policies to control access. All buckets are private by default - you must create policies to allow access.

Private files (default)

Files are private by default. Use policies to control who can access them:

# Create bucket
curl -X POST ".../storage/buckets" \
  -d '{"name": "user-files"}'

# Add owner-only read policy
curl -X POST ".../storage/buckets/user-files/policies" \
  -d '{
    "name": "owner-read",
    "operation": "SELECT",
    "definition": "auth.uid() = owner_id"
  }'

Public files

To share files publicly (without authentication), mark individual files as public:

// Make a specific file public
await volcano.storage
  .from('assets')
  .updateVisibility('logo.png', true);

// The file now has a public_url for sharing
console.log(file.public_url);
// https://api.yourapp.com/public/{projectId}/assets/logo.png

Public and private files can coexist in the same bucket. Only the file owner (or a service key) can change file visibility.

File size limits

Restrict maximum file size per bucket:

curl -X POST ".../storage/buckets" \
  -d '{
    "name": "thumbnails",
    "file_size_limit": 1048576
  }'

The limit is in bytes:

SizeBytes
1 KB1024
1 MB1048576
10 MB10485760
100 MB104857600
1 GB1073741824

Uploads exceeding the limit receive a 400 Bad Request response:

{
  "error": "file size exceeds bucket limit of 1048576 bytes"
}

MIME type restrictions

Restrict allowed file types:

curl -X POST ".../storage/buckets" \
  -d '{
    "name": "images",
    "allowed_mime_types": ["image/jpeg", "image/png", "image/gif", "image/webp"]
  }'

Common MIME types:

TypeMIME
JPEG imageimage/jpeg
PNG imageimage/png
GIFimage/gif
WebPimage/webp
PDFapplication/pdf
JSONapplication/json
Plain texttext/plain
CSVtext/csv
ZIPapplication/zip
MP4 videovideo/mp4
MP3 audioaudio/mpeg

Uploads with disallowed MIME types receive a 400 Bad Request:

{
  "error": "MIME type application/pdf is not allowed"
}

Updating buckets

Modify bucket settings:

curl -X PUT "https://api.yourapp.com/storage/buckets/bucket-id" \
  -H "Authorization: Bearer $SERVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file_size_limit": 5242880,
    "allowed_mime_types": ["image/jpeg", "image/png"]
  }'

Listing buckets

Get all buckets in a project:

curl "https://api.yourapp.com/storage/buckets" \
  -H "Authorization: Bearer $SERVICE_KEY"

Response:

[
  {
    "id": "bucket-abc",
    "name": "avatars",
    "project_id": "project-xyz",
    "file_size_limit": 5242880,
    "allowed_mime_types": ["image/jpeg", "image/png"],
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  },
  {
    "id": "bucket-xyz",
    "name": "documents",
    "project_id": "project-xyz",
    "file_size_limit": null,
    "allowed_mime_types": [],
    "created_at": "2024-01-15T11:00:00Z",
    "updated_at": "2024-01-15T11:00:00Z"
  }
]

Getting bucket details

curl "https://api.yourapp.com/storage/buckets/bucket-id" \
  -H "Authorization: Bearer $SERVICE_KEY"

Or by name:

curl "https://api.yourapp.com/storage/buckets?name=avatars" \
  -H "Authorization: Bearer $SERVICE_KEY"

Deleting buckets

Delete a bucket and all its contents:

curl -X DELETE "https://api.yourapp.com/storage/buckets/bucket-id" \
  -H "Authorization: Bearer $SERVICE_KEY"

Warning: This permanently deletes all files in the bucket. This operation cannot be undone.

Example configurations

Avatar bucket

Small images only:

curl -X POST ".../storage/buckets" \
  -d '{
    "name": "avatars",
    "file_size_limit": 2097152,
    "allowed_mime_types": ["image/jpeg", "image/png", "image/webp"]
  }'

Document storage

PDFs and office documents, larger size:

curl -X POST ".../storage/buckets" \
  -d '{
    "name": "documents",
    "file_size_limit": 52428800,
    "allowed_mime_types": [
      "application/pdf",
      "application/msword",
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "application/vnd.ms-excel",
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    ]
  }'

Public website assets

No restrictions, public access:

curl -X POST ".../storage/buckets" \
  -d '{"name": "public-assets"}'

# Add policy allowing all authenticated users to read
curl -X POST ".../storage/buckets/public-assets/policies" \
  -d '{
    "name": "auth-read",
    "operation": "SELECT",
    "definition": "auth.uid() IS NOT NULL"
  }'

# For truly public access, mark individual files as public
# They will then be accessible at /public/{projectId}/public-assets/{path}

Temporary uploads

User uploads that will be processed:

curl -X POST ".../storage/buckets" \
  -d '{
    "name": "temp-uploads",
    "file_size_limit": 104857600
  }'

# Users can upload
curl -X POST ".../storage/buckets/temp-uploads/policies" \
  -d '{
    "name": "auth-insert",
    "operation": "INSERT",
    "definition": "auth.uid() IS NOT NULL"
  }'

# Users can read their own uploads
curl -X POST ".../storage/buckets/temp-uploads/policies" \
  -d '{
    "name": "owner-select",
    "operation": "SELECT",
    "definition": "auth.uid() = owner_id"
  }'

Best practices

  1. Use descriptive names - Choose bucket names that reflect their purpose
  2. Set appropriate limits - Configure file size and MIME type restrictions
  3. Private by default - Only mark files as public when they need to be shared without authentication
  4. Separate concerns - Use different buckets for different file types
  5. Apply policies - Always configure access policies for security

On this page