kumolo implements the S3 REST API. All operations accept standard AWS SDK v2 requests — point your client at http://localhost:5566 with UsePathStyle = true.
Symbol Meaning ✓ Fully implemented — the feature behaves like real AWS ◐ Partial support — the operation works but has known limitations; see the note for details — Not yet implemented
Operations sourced from internal/s3/router.go in the kumolo repository.
Operation Supported CreateBucket✓ DeleteBucket✓ HeadBucket✓ ListBuckets◐ ListDirectoryBuckets— CreateSession—
Operation Supported PutObject✓ GetObject✓ DeleteObject✓ DeleteObjects✓ HeadObject✓ CopyObject✓ GetObjectAttributes✓ RestoreObject◐ SelectObjectContent◐ GetObjectTorrent— WriteGetObjectResponse—
Operation Supported ListObjects✓ ListObjectsV2✓ ListObjectVersions◐
Operation Supported CreateMultipartUpload✓ UploadPart✓ UploadPartCopy✓ CompleteMultipartUpload✓ AbortMultipartUpload✓ ListMultipartUploads◐ ListParts✓
All object operations (GetObject, PutObject, DeleteObject, HeadObject, etc.) support standard SigV4 presigned URLs generated by the AWS SDK presign client. The X-Amz-Expires value is validated (1–604800 seconds); expired URLs return 403 AccessDenied. Signatures are not verified — see Known Limitations .
Operation Supported POST Object✓
Presigned POST enables browser-based direct-to-S3 uploads without routing the file through your server. Generate a presigned POST policy with @aws-sdk/s3-presigned-post (JS) or a compatible library, then submit via an HTML form with enctype="multipart/form-data".
Supported form fields: key (required; supports ${filename} substitution), Content-Type, acl, x-amz-meta-*, success_action_status (200, 201, 204), and success_action_redirect.
Policy conditions are not evaluated — see Known Limitations .
Operation Supported GetBucketVersioning✓ PutBucketVersioning◐
Operation Supported GetBucketCors✓ PutBucketCors✓ DeleteBucketCors✓
Operation Supported GetBucketTagging✓ PutBucketTagging✓ DeleteBucketTagging✓ GetObjectTagging✓ PutObjectTagging✓ DeleteObjectTagging✓
Operation Supported GetObjectRetention✓ PutObjectRetention✓ GetObjectLegalHold✓ PutObjectLegalHold✓ GetObjectLockConfiguration✓ PutObjectLockConfiguration✓
Note
PutObjectLockConfiguration with a DefaultRetention rule automatically applies the configured mode (GOVERNANCE or COMPLIANCE) and period (days or years) to every new object uploaded to that bucket via PutObject, CopyObject, and CompleteMultipartUpload.
Operation Supported GetBucketLocation✓
Operation Supported GetBucketPolicy◐ PutBucketPolicy◐ DeleteBucketPolicy◐ GetBucketPolicyStatus—
Operation Supported GetBucketAcl✓ PutBucketAcl◐ GetObjectAcl◐ PutObjectAcl◐
Note
ACL is stored and enforced on object reads. Individual grant headers (e.g. x-amz-grant-read, x-amz-grant-write) are not supported in PutBucketAcl and PutObjectAcl — use the canned ACL or XML body form. The versionId query parameter is not supported on GetObjectAcl and PutObjectAcl; ACL applies to the current version only.
Operation Supported GetBucketEncryption✓ PutBucketEncryption✓ DeleteBucketEncryption✓
Operation Supported GetPublicAccessBlock◐ PutPublicAccessBlock◐ DeletePublicAccessBlock◐
Operation Supported GetBucketOwnershipControls◐ PutBucketOwnershipControls◐ DeleteBucketOwnershipControls◐
Operation Supported GetBucketLifecycleConfiguration✓ PutBucketLifecycleConfiguration✓ DeleteBucketLifecycle✓
Note
Transition (for the current object version) is not supported. Expiration (by days and by date), ExpiredObjectDeleteMarker, NoncurrentVersionExpiration, NoncurrentVersionTransition, and AbortIncompleteMultipartUpload are enforced. The x-amz-transition-default-minimum-object-size request header is accepted and stored but does not affect lifecycle evaluation.
Operation Supported GetBucketWebsite◐ PutBucketWebsite◐ DeleteBucketWebsite◐
Operation Supported GetBucketReplication✓ PutBucketReplication✓ DeleteBucketReplication✓
Operation Supported GetBucketNotificationConfiguration◐ PutBucketNotificationConfiguration◐
Operation Supported GetBucketLogging✓ PutBucketLogging✓
Note
Access logs are written to the configured target bucket in S3 server access log format. Each request produces one log object (real AWS batches multiple records per file). Fields not tracked by kumolo (bucket-owner, request-id, object-size, etc.) are emitted as -.
Operation Supported GetBucketAccelerateConfiguration◐ PutBucketAccelerateConfiguration◐
Operation Supported GetBucketRequestPayment◐ PutBucketRequestPayment◐
Operation Supported GetBucketAnalyticsConfiguration— PutBucketAnalyticsConfiguration— DeleteBucketAnalyticsConfiguration— ListBucketAnalyticsConfigurations—
Operation Supported GetBucketIntelligentTieringConfiguration— PutBucketIntelligentTieringConfiguration— DeleteBucketIntelligentTieringConfiguration— ListBucketIntelligentTieringConfigurations—
Operation Supported GetBucketInventoryConfiguration— PutBucketInventoryConfiguration— DeleteBucketInventoryConfiguration— ListBucketInventoryConfigurations—
Operation Supported GetBucketMetricsConfiguration— PutBucketMetricsConfiguration— DeleteBucketMetricsConfiguration— ListBucketMetricsConfigurations—
" github.com/aws/aws-sdk-go-v2/aws "
" github.com/aws/aws-sdk-go-v2/config "
" github.com/aws/aws-sdk-go-v2/credentials "
" github.com/aws/aws-sdk-go-v2/service/s3 "
cfg , err := config . LoadDefaultConfig ( context . Background (),
config . WithRegion ( " us-east-1 " ),
config . WithCredentialsProvider (
credentials . NewStaticCredentialsProvider ( " test " , " test " , "" ),
client := s3 . NewFromConfig ( cfg , func ( o * s3.Options) {
o . BaseEndpoint = aws . String ( " http://localhost:5566 " )
o . UsePathStyle = true // required for local endpoint
if _ , err = client . CreateBucket ( context . Background (), & s3.CreateBucketInput{
Bucket : aws . String ( " my-bucket " ),
if _ , err = client . PutObject ( context . Background (), & s3.PutObjectInput{
Bucket : aws . String ( " my-bucket " ),
Key : aws . String ( " hello.txt " ),
Body : strings . NewReader ( " hello, kumolo " ),
endpoint_url = " http://localhost:5566 " ,
aws_access_key_id = " test " ,
aws_secret_access_key = " test " ,
s3. create_bucket ( Bucket = " my-bucket " )
s3. put_object ( Bucket = " my-bucket " , Key = " hello.txt " , Body = b " hello, kumolo " )
aws s3 mb s3://my-bucket \
--endpoint-url http://localhost:5566 \
aws s3 cp hello.txt s3://my-bucket/ \
--endpoint-url http://localhost:5566