Object Storage — System Protocol reference Object Storage Protocol. Reference for AccessControlConfig, BucketConfig, FileMetadata, LifecycleAction and 11 more: every property with its type and default.
Object Storage Protocol
Unified storage protocol that combines:
Object storage systems (S3, Azure Blob, GCS, MinIO)
Scoped storage configuration (temp, cache, data, logs, config)
Multi-cloud storage providers
Bucket/container configuration
Access control and permissions
Lifecycle policies for data retention
Presigned URLs for secure direct access
Multipart uploads for large files
Source: packages/spec/src/system/object-storage.zod.ts
import { AccessControlConfigSchema, BucketConfigSchema, FileMetadataSchema, LifecycleActionSchema, LifecyclePolicyConfigSchema, LifecyclePolicyRuleSchema, MultipartUploadConfigSchema, ObjectMetadataSchema, ObjectStorageConfigSchema, PresignedUrlConfigSchema, StorageAclSchema, StorageClassSchema, StorageConnectionSchema, StorageProviderSchema, StorageScopeSchema } from '@objectstack/spec/system' ;
import type { AccessControlConfig, BucketConfig, FileMetadata, LifecycleAction, LifecyclePolicyConfig, LifecyclePolicyRule, MultipartUploadConfig, ObjectMetadata, ObjectStorageConfig, PresignedUrlConfig, StorageAcl, StorageClass, StorageConnection, StorageProvider, StorageScope } from '@objectstack/spec/system' ;
// Validate data
const result = AccessControlConfigSchema. parse (data);
Property Type Required Description acl Enum<'private' | 'public_read' | 'public_read_write' | 'authenticated_read' | 'bucket_owner_read' | 'bucket_owner_full_control'>optional (default: "private") Default access control level allowedOrigins string[]optional CORS allowed origins allowedMethods Enum<'GET' | 'PUT' | 'POST' | 'DELETE' | 'HEAD'>[]optional CORS allowed HTTP methods allowedHeaders string[]optional CORS allowed headers exposeHeaders string[]optional CORS exposed headers maxAgeSeconds numberoptional CORS preflight cache duration in seconds maxAge neveroptional [REMOVED] AccessControlConfig.maxAge was renamed to maxAgeSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Every bucket-CORS standard this value is forwarded to already spells the unit (S3 MaxAgeSeconds, GCS maxAgeSeconds, Azure MaxAgeInSeconds), so the bare name was a deviation from them rather than a mirror of them. Rename the key to maxAgeSeconds; the value (seconds) is unchanged. The unrelated CorsConfig.maxAge on the shared HTTP surface keeps its name — that one mirrors the Access-Control-Max-Age response header, which carries no unit token. corsEnabled booleanoptional (default: false) Enable CORS configuration publicAccess { allowPublicRead?: boolean; allowPublicWrite?: boolean; allowPublicList?: boolean }optional Public access control allowedIps string[]optional Allowed IP addresses/CIDR blocks blockedIps string[]optional Blocked IP addresses/CIDR blocks
Property Type Required Description allowPublicRead booleanoptional (default: false) Allow public read access allowPublicWrite booleanoptional (default: false) Allow public write access allowPublicList booleanoptional (default: false) Allow public bucket listing
Property Type Required Description name string✅ Bucket identifier in ObjectStack (snake_case) label string✅ Display label bucketName string✅ Actual bucket/container name in storage provider region stringoptional Storage region (e.g., us-east-1, westus) provider Enum<'s3' | 'azure_blob' | 'gcs' | 'minio' | 'r2' | 'spaces' | 'wasabi' | 'backblaze' | 'local'>✅ Storage provider endpoint stringoptional Custom endpoint URL (for S3-compatible providers) pathStyle booleanoptional (default: false) Use path-style URLs (for S3-compatible providers) versioning booleanoptional (default: false) Enable object versioning encryption { enabled?: boolean; algorithm?: Enum<'AES256' | 'aws:kms' | 'azure:kms' | 'gcp:kms'>; kmsKeyId?: string }optional Server-side encryption configuration accessControl { acl?: Enum<'private' | 'public_read' | 'public_read_write' | 'authenticated_read' | …>; allowedOrigins?: string[]; allowedMethods?: Enum<'GET' | 'PUT' | 'POST' | 'DELETE' | 'HEAD'>[]; allowedHeaders?: string[]; … }optional Access control configuration lifecyclePolicy { enabled?: boolean; rules?: object[] }optional Lifecycle policy configuration multipartConfig { enabled?: boolean; partSize?: number; maxParts?: number; threshold?: number; … }optional Multipart upload configuration tags Record<string, string>optional Bucket tags for organization description stringoptional Bucket description enabled booleanoptional (default: true) Enable this bucket
Property Type Required Description enabled booleanoptional (default: false) Enable server-side encryption algorithm Enum<'AES256' | 'aws:kms' | 'azure:kms' | 'gcp:kms'>optional (default: "AES256") Encryption algorithm kmsKeyId stringoptional KMS key ID for managed encryption
Property Type Required Description acl Enum<'private' | 'public_read' | 'public_read_write' | 'authenticated_read' | …>optional (default: "private") Default access control level allowedOrigins string[]optional CORS allowed origins allowedMethods Enum<'GET' | 'PUT' | 'POST' | 'DELETE' | 'HEAD'>[]optional CORS allowed HTTP methods allowedHeaders string[]optional CORS allowed headers exposeHeaders string[]optional CORS exposed headers maxAgeSeconds numberoptional CORS preflight cache duration in seconds maxAge neveroptional [REMOVED] AccessControlConfig.maxAge was renamed to maxAgeSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Every bucket-CORS standard this value is forwarded to already spells the unit (S3 MaxAgeSeconds, GCS maxAgeSeconds, Azure MaxAgeInSeconds), so the bare name was a deviation from them rather than a mirror of them. Rename the key to maxAgeSeconds; the value (seconds) is unchanged. The unrelated CorsConfig.maxAge on the shared HTTP surface keeps its name — that one mirrors the Access-Control-Max-Age response header, which carries no unit token. corsEnabled booleanoptional (default: false) Enable CORS configuration publicAccess { allowPublicRead?: boolean; allowPublicWrite?: boolean; allowPublicList?: boolean }optional Public access control allowedIps string[]optional Allowed IP addresses/CIDR blocks blockedIps string[]optional Blocked IP addresses/CIDR blocks
Property Type Required Description enabled booleanoptional (default: false) Enable lifecycle policies rules { id: string; enabled?: boolean; action: Enum<'transition' | 'delete' | 'abort'>; prefix?: string; … }[]optional (default: []) Lifecycle rules
Property Type Required Description enabled booleanoptional (default: true) Enable multipart uploads partSize numberoptional (default: 10485760) Part size in bytes (min 5MB, max 5GB) maxParts numberoptional (default: 10000) Maximum number of parts (max 10,000) threshold numberoptional (default: 104857600) File size threshold to trigger multipart upload (bytes) maxConcurrent numberoptional (default: 4) Maximum concurrent part uploads abortIncompleteAfterDays numberoptional Auto-abort incomplete uploads after N days
Property Type Required Description path string✅ File path name string✅ File name size integer✅ File size in bytes mimeType string✅ MIME type lastModified string✅ Last modified timestamp created string✅ Creation timestamp etag stringoptional Entity tag fileId stringoptional Opaque sys_file id (ADR-0104 D3 file-as-reference)
Lifecycle policy action type
Property Type Required Description enabled booleanoptional (default: false) Enable lifecycle policies rules { id: string; enabled?: boolean; action: Enum<'transition' | 'delete' | 'abort'>; prefix?: string; … }[]optional (default: []) Lifecycle rules
Property Type Required Description id string✅ Rule identifier enabled booleanoptional (default: true) Enable this rule action Enum<'transition' | 'delete' | 'abort'>✅ Action to perform prefix stringoptional Object key prefix filter (e.g., "uploads/") tags Record<string, string>optional Object tag filters daysAfterCreation numberoptional Days after object creation daysAfterModification numberoptional Days after last modification targetStorageClass Enum<'standard' | 'intelligent' | 'infrequent_access' | 'glacier' | 'deep_archive'>optional Target storage class for transition action
Property Type Required Description id string✅ Rule identifier enabled booleanoptional (default: true) Enable this rule action Enum<'transition' | 'delete' | 'abort'>✅ Action to perform prefix stringoptional Object key prefix filter (e.g., "uploads/") tags Record<string, string>optional Object tag filters daysAfterCreation numberoptional Days after object creation daysAfterModification numberoptional Days after last modification targetStorageClass Enum<'standard' | 'intelligent' | 'infrequent_access' | 'glacier' | 'deep_archive'>optional Target storage class for transition action
Property Type Required Description enabled booleanoptional (default: true) Enable multipart uploads partSize numberoptional (default: 10485760) Part size in bytes (min 5MB, max 5GB) maxParts numberoptional (default: 10000) Maximum number of parts (max 10,000) threshold numberoptional (default: 104857600) File size threshold to trigger multipart upload (bytes) maxConcurrent numberoptional (default: 4) Maximum concurrent part uploads abortIncompleteAfterDays numberoptional Auto-abort incomplete uploads after N days
Property Type Required Description contentType string✅ MIME type (e.g., image/jpeg, application/pdf) contentLength number✅ File size in bytes contentEncoding stringoptional Content encoding (e.g., gzip) contentDisposition stringoptional Content disposition header contentLanguage stringoptional Content language cacheControl stringoptional Cache control directives etag stringoptional Entity tag for versioning/caching lastModified stringoptional Last modification timestamp versionId stringoptional Object version identifier storageClass Enum<'standard' | 'intelligent' | 'infrequent_access' | 'glacier' | 'deep_archive'>optional Storage class/tier encryption { algorithm: string; keyId?: string }optional Server-side encryption configuration custom Record<string, string>optional Custom user-defined metadata
Property Type Required Description algorithm string✅ Encryption algorithm (e.g., AES256, aws:kms) keyId stringoptional KMS key ID if using managed encryption
Property Type Required Description name string✅ Storage configuration identifier label string✅ Display label provider Enum<'s3' | 'azure_blob' | 'gcs' | 'minio' | 'r2' | 'spaces' | 'wasabi' | 'backblaze' | 'local'>✅ Primary storage provider scope Enum<'global' | 'tenant' | 'user' | 'session' | 'temp' | 'cache' | 'data' | 'logs' | 'config'>optional (default: "global") Storage scope connection { accessKeyId?: string; secretAccessKey?: string; sessionToken?: string; accountName?: string; … }✅ Connection credentials buckets { name: string; label: string; bucketName: string; region?: string; … }[]optional (default: []) Configured buckets defaultBucket stringoptional Default bucket name for operations location stringoptional Root path (local) or base location quota integeroptional Max size in bytes options Record<string, any>optional Provider-specific configuration options enabled booleanoptional (default: true) Enable this storage configuration description stringoptional Configuration description
Property Type Required Description accessKeyId stringoptional AWS access key ID or MinIO access key secretAccessKey stringoptional AWS secret access key or MinIO secret key sessionToken stringoptional AWS session token for temporary credentials accountName stringoptional Azure storage account name accountKey stringoptional Azure storage account key sasToken stringoptional Azure SAS token environmentId stringoptional GCP project ID credentials stringoptional GCP service account credentials JSON endpoint stringoptional Custom endpoint URL region stringoptional Default region useSSL booleanoptional (default: true) Use SSL/TLS for connections timeoutMs numberoptional Connection timeout in milliseconds timeout neveroptional [REMOVED] StorageConnection.timeout was renamed to timeoutMs in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Rename the key to timeoutMs; the value (milliseconds) is unchanged.
Property Type Required Description name string✅ Bucket identifier in ObjectStack (snake_case) label string✅ Display label bucketName string✅ Actual bucket/container name in storage provider region stringoptional Storage region (e.g., us-east-1, westus) provider Enum<'s3' | 'azure_blob' | 'gcs' | 'minio' | 'r2' | 'spaces' | 'wasabi' | 'backblaze' | 'local'>✅ Storage provider endpoint stringoptional Custom endpoint URL (for S3-compatible providers) pathStyle booleanoptional (default: false) Use path-style URLs (for S3-compatible providers) versioning booleanoptional (default: false) Enable object versioning encryption { enabled?: boolean; algorithm?: Enum<'AES256' | 'aws:kms' | 'azure:kms' | 'gcp:kms'>; kmsKeyId?: string }optional Server-side encryption configuration accessControl { acl?: Enum<'private' | 'public_read' | 'public_read_write' | 'authenticated_read' | …>; allowedOrigins?: string[]; allowedMethods?: Enum<'GET' | 'PUT' | 'POST' | 'DELETE' | 'HEAD'>[]; allowedHeaders?: string[]; … }optional Access control configuration lifecyclePolicy { enabled?: boolean; rules?: object[] }optional Lifecycle policy configuration multipartConfig { enabled?: boolean; partSize?: number; maxParts?: number; threshold?: number; … }optional Multipart upload configuration tags Record<string, string>optional Bucket tags for organization description stringoptional Bucket description enabled booleanoptional (default: true) Enable this bucket
Property Type Required Description operation Enum<'get' | 'put' | 'delete' | 'head'>✅ Allowed operation expiresIn number✅ Expiration time in seconds (max 7 days) (unit per AWS S3 presigned URL expiresIn (@aws-sdk/s3-request-presigner)) contentType stringoptional Required content type for PUT operations maxSize numberoptional Maximum file size in bytes for PUT operations responseContentType stringoptional Override content-type for GET operations responseContentDisposition stringoptional Override content-disposition for GET operations
Storage access control level
private
public_read
public_read_write
authenticated_read
bucket_owner_read
bucket_owner_full_control
Storage class/tier for cost optimization
standard
intelligent
infrequent_access
glacier
deep_archive
Property Type Required Description accessKeyId stringoptional AWS access key ID or MinIO access key secretAccessKey stringoptional AWS secret access key or MinIO secret key sessionToken stringoptional AWS session token for temporary credentials accountName stringoptional Azure storage account name accountKey stringoptional Azure storage account key sasToken stringoptional Azure SAS token environmentId stringoptional GCP project ID credentials stringoptional GCP service account credentials JSON endpoint stringoptional Custom endpoint URL region stringoptional Default region useSSL booleanoptional (default: true) Use SSL/TLS for connections timeoutMs numberoptional Connection timeout in milliseconds timeout neveroptional [REMOVED] StorageConnection.timeout was renamed to timeoutMs in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Rename the key to timeoutMs; the value (milliseconds) is unchanged.
Storage provider type
s3
azure_blob
gcs
minio
r2
spaces
wasabi
backblaze
local
Storage scope classification
global
tenant
user
session
temp
cache
data
logs
config