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
| Property | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
name | string | Bucket name (unique per project) |
project_id | UUID | Parent project |
file_size_limit | integer | Maximum file size in bytes (null = unlimited) |
allowed_mime_types | string[] | Allowed MIME types (empty = all types) |
created_at | timestamp | Creation time |
updated_at | timestamp | Last 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-uploadsLocal 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-uploadsDeclarative 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.yamlvolcano 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_idIf -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 explicitpolicies: []deletes all policies. - Omitting the
policieskey 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_idExample: 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_idApply with:
volcano config deploy
volcano local config deployCreating 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:
avatarsuser-uploadspublic_assetsfiles-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.pngPublic 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:
| Size | Bytes |
|---|---|
| 1 KB | 1024 |
| 1 MB | 1048576 |
| 10 MB | 10485760 |
| 100 MB | 104857600 |
| 1 GB | 1073741824 |
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:
| Type | MIME |
|---|---|
| JPEG image | image/jpeg |
| PNG image | image/png |
| GIF | image/gif |
| WebP | image/webp |
application/pdf | |
| JSON | application/json |
| Plain text | text/plain |
| CSV | text/csv |
| ZIP | application/zip |
| MP4 video | video/mp4 |
| MP3 audio | audio/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
- Use descriptive names - Choose bucket names that reflect their purpose
- Set appropriate limits - Configure file size and MIME type restrictions
- Private by default - Only mark files as public when they need to be shared without authentication
- Separate concerns - Use different buckets for different file types
- Apply policies - Always configure access policies for security