Mastering MindbricksDatabase Buckets (dbBuckets)
Mastering Mindbricks

Database Buckets (dbBuckets)

Store small files directly in the database — icons, avatars, secret documents — without external storage infrastructure.

Database Buckets (dbBuckets)

Database Buckets store files directly in the service's database (BYTEA in PostgreSQL, Buffer in MongoDB) instead of using an external storage service. They are ideal for small files like icons, avatars, secret documents, and configuration files where simplicity and data locality matter more than scalability.

When to Use

Use CaseUse dbBucketUse External Bucket Service
User avatars, iconsYes
Tenant logosYes
Secret/signed documentsYes
Small config files (<10 MB)Yes
Product images (many, large)Yes
User uploads (videos, PDFs)Yes
Public CDN assetsYes

Key differences:

FeatureDatabase BucketExternal Bucket Service
StoragePostgreSQL BYTEA / MongoDB BufferS3, MinIO, or local filesystem
Max file sizeConfigurable (default 10 MB)Configurable (default 10 MB)
AuthenticationRegular access token (same as all APIs)Bucket-specific JWT tokens
InfrastructureNone — uses the service's existing databaseRequires separate bucket service deployment
CDN supportNoYes (S3 + CloudFront)
ScalabilityLimited by database sizeHighly scalable

Adding a dbBucket to a Service

Add a dbBuckets entry to any service in your project configuration:

{
  "dbBuckets": [
    {
      "bucketBasics": {
        "name": "productImages",
        "description": "Product photo storage",
        "maxFileSizeMb": 5,
        "allowedMimeTypes": "image/png,image/jpeg,image/webp"
      },
      "bucketAuthorization": {
        "readAccess": "public",
        "writeAccess": "authenticated",
        "enableKeyAccess": true
      },
      "ownerDataObject": {
        "hasOwnerDataObject": true,
        "configuration": {
          "dataObjectName": "product",
          "relationProperty": "productId"
        }
      }
    }
  ]
}

What Gets Auto-Generated

When you add a dbBucket to a service, the system automatically generates:

1. Data Object: sys_{bucketName}File

A database table with these properties:

PropertyTypeDescription
idIDAuto-generated unique identifier
fileNameStringOriginal file name as uploaded
mimeTypeStringMIME type (e.g., image/png)
fileSizeIntegerFile size in bytes
fileDataBlobBinary file content (BYTEA in PostgreSQL, Buffer in MongoDB)
accessKeyString12-character random key for shareable access (unique, indexed)
userIdIDID of the user who uploaded the file (from session)
metadataObjectOptional JSON metadata (tags, alt text, etc.)
createdAtDateUpload timestamp
updatedAtDateLast update timestamp

If an owner data object is configured, an additional relation property is added (e.g., productId as ID with a foreign key to the product table).

2. System Upload/Download Routes

These routes are mounted at /bucket/{bucketName}/ on the service:

Upload

POST /bucket/{bucketName}/upload
Content-Type: multipart/form-data
Authorization: Bearer {accessToken}
FieldTypeDescription
fileFileThe file to upload (single file, in the file field)
metadataJSON stringOptional metadata object
{ownerRelationProperty}stringOptional: ID of the owner record (e.g., productId)

Response (201):

{
  "status": "OK",
  "action": "upload",
  "bucket": "productImages",
  "file": {
    "id": "a1b2c3d4-...",
    "fileName": "photo.jpg",
    "mimeType": "image/jpeg",
    "fileSize": 245760,
    "accessKey": "x7K9mP2nQ4wR",
    "userId": "user-uuid-...",
    "productId": "product-uuid-...",
    "createdAt": "2026-03-27T10:00:00.000Z"
  }
}

Note: The response does not include fileData (the binary content). Only metadata is returned.

Download by ID

GET /bucket/{bucketName}/download/{fileId}

Authorization depends on the bucket's readAccess setting:

  • public: No auth required

  • authenticated: Requires valid access token

  • private: Requires access token, and user must be the file owner or an admin

Returns the binary file with appropriate Content-Type and Content-Disposition headers.

Download by Access Key

GET /bucket/{bucketName}/download/key/{accessKey}

When enableKeyAccess is true, anyone with the 12-character access key can download the file — no authentication required. This is useful for shareable links and <img> tags.

3. Metadata Business APIs

Standard CRUD APIs for querying file metadata (without the binary data):

API NameMethodPathDescription
get{BucketName}FileGET/v1/sys_{bucketName}Files/:idGet file metadata by ID
list{BucketName}FilesGET/v1/sys_{bucketName}FilesList files with filtering
delete{BucketName}FileDELETE/v1/sys_{bucketName}Files/:idDelete file (metadata + binary)

These APIs follow the standard Mindbricks Business API patterns — they support pagination, filtering by mimeType, userId, owner relation property, etc. The fileData (Blob) column is excluded from responses.

Authorization

Read Access (readAccess)

ValueBehavior
publicAnyone can download. No authentication needed.
authenticatedAny authenticated user can download. Requires valid access token.
privateOnly the file owner (userId matches session) and admin roles can download.

Write Access (writeAccess)

ValueBehavior
authenticatedAny authenticated user can upload.
adminOnlyOnly users with admin roles (admin, superAdmin) can upload.

Role-Based Access

For finer control, configure role arrays:

  • readAbsoluteRoles / writeAbsoluteRoles — Roles that bypass all authorization checks

  • readCheckRoles / writeCheckRoles — Roles required for access

Custom Auth Scripts

For complex authorization logic, use MScript expressions:

{
  "readAuthScript": "this.session.roleId === 'admin' || this.record.userId === this.session.userId",
  "writeAuthScript": "this.session.emailVerified === true"
}

Access Key

When enableKeyAccess is true (default), every uploaded file receives a 12-character random access key. Anyone with this key can download the file via /bucket/{name}/download/key/{accessKey}, regardless of other authorization settings. This enables:

  • Public avatar URLs in <img> tags (no auth headers needed)

  • Shareable file links

  • Email-embedded image URLs

Owner Data Object

Pair a bucket with a data object to create a parent-child relationship:

{
  "ownerDataObject": {
    "hasOwnerDataObject": true,
    "configuration": {
      "dataObjectName": "product",
      "relationProperty": "productId"
    }
  }
}

This adds a productId property to the bucket's data object with a foreign key relation. Benefits:

  • Filter by owner: GET /v1/sys_productImagesFiles?productId={id} lists only that product's images

  • Cascading deletes: When the owner record is deleted, associated files are also removed

  • Upload with owner: Pass productId in the upload form data to link the file

Auth Service Auto-Generated Buckets

The authentication service automatically includes database buckets for avatars — you don't need to configure these manually:

  • userAvatars — Always present. Public read, authenticated write, images only (png/jpeg/webp/gif), 5 MB max. Paired with the user data object.

  • {tenantName}Avatars — Only in multi-tenant projects. Same config, paired with the tenant data object.

Avatar Upload Workflow

  1. User selects an image

  2. Crop with react-easy-crop (zoom, pan, crop)

  3. Upload cropped blob: POST {authBaseUrl}/bucket/userAvatars/upload

  4. Get back accessKey from the response

  5. Build public URL: {authBaseUrl}/bucket/userAvatars/download/key/{accessKey}

  6. Save URL to user profile: updateProfile({ avatar: downloadUrl })

Since readAccess is public, avatar URLs work directly in <img> tags without authentication.

Examples

Simple Icon Bucket (No Owner)

{
  "bucketBasics": {
    "name": "appIcons",
    "description": "Application icon storage",
    "maxFileSizeMb": 2,
    "allowedMimeTypes": "image/png,image/svg+xml"
  },
  "bucketAuthorization": {
    "readAccess": "public",
    "writeAccess": "adminOnly",
    "enableKeyAccess": true
  }
}

Private Document Bucket (With Owner)

{
  "bucketBasics": {
    "name": "contracts",
    "description": "Signed contract documents — private to owner",
    "maxFileSizeMb": 10,
    "allowedMimeTypes": "application/pdf"
  },
  "bucketAuthorization": {
    "readAccess": "private",
    "writeAccess": "authenticated",
    "enableKeyAccess": false
  },
  "ownerDataObject": {
    "hasOwnerDataObject": true,
    "configuration": {
      "dataObjectName": "employee",
      "relationProperty": "employeeId"
    }
  }
}

Frontend Upload Example

// Upload a file to a dbBucket
async function uploadToBucket(serviceBaseUrl, bucketName, file, accessToken, metadata = {}) {
  const formData = new FormData();
  formData.append('file', file);
  if (Object.keys(metadata).length > 0) {
    formData.append('metadata', JSON.stringify(metadata));
  }

  const response = await fetch(`${serviceBaseUrl}/bucket/${bucketName}/upload`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${accessToken}` },
    body: formData,
  });

  const result = await response.json();
  return result.file; // { id, fileName, mimeType, fileSize, accessKey, ... }
}

// Build a public download URL
function getPublicUrl(serviceBaseUrl, bucketName, accessKey) {
  return `${serviceBaseUrl}/bucket/${bucketName}/download/key/${accessKey}`;
}

// Usage
const file = await uploadToBucket(authBaseUrl, 'userAvatars', croppedBlob, token);
const avatarUrl = getPublicUrl(authBaseUrl, 'userAvatars', file.accessKey);
await updateProfile({ avatar: avatarUrl });