Skip to main content

S3 compatibility

OpenBucket speaks the Amazon S3 wire protocol: AWS Signature V4 (header and presigned query), path-style addressing, XML error envelopes, streaming PUT/GET, multipart uploads, versioning, object lock, tagging, ACL/policy, CORS, and lifecycle. Point any S3 SDK at it — no special client.

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({
endpoint: 'http://localhost:9000', // standalone; add `/storage` when embedded
region: 'us-east-1', // must match OpenBucket's region option
forcePathStyle: true, // REQUIRED — see limitations
credentials: { accessKeyId, secretAccessKey },
});
await s3.send(new PutObjectCommand({ Bucket: 'my-bucket', Key: 'a.jpg', Body: buf }));

The wire surface is exercised by the conformance suite against the real aws CLI, MinIO's mc, and s3cmd. See how OpenBucket compares to MinIO if you're choosing between them.

Proven, not just claimed

The matrix below is hand-maintained today, but backed by a machine-generated conformance report. On every pull request to main (and every release tag), the conformance suite boots the built image under test with testcontainers and round-trips objects through each real client. As it runs, it records every (client × operation) outcome and emits a dated report — both conformance-report.json and a rendered conformance-report.md matrix — stamped with the image sha under test, the run timestamp, and each client version. The report is published as the conformance-report workflow artifact on the s3 conformance suite CI job; download it from the run's summary to see the exact operations that passed against a specific image. The hand-written tables here are kept in sync with that generated report.

Supported operations

Service & buckets

OperationSupportedNotes
ListBucketsService-scope GET.
CreateBucketPUT /:bucket.
DeleteBucketMust be empty (409 BucketNotEmpty otherwise).
HeadBucketExistence + region probe.
GetBucketLocationReturns the configured region.

Objects

OperationSupportedNotes
PutObjectStreaming PUT, chunked SigV4, checksums.
GetObjectRange reads, conditional headers.
HeadObjectMetadata only.
DeleteObjectIdempotent.
DeleteObjectsBulk delete (POST ?delete).
CopyObjectVia x-amz-copy-source.
ListObjectsV1 listing.
ListObjectsV2list-type=2, continuation tokens, delimiter roll-up.
GetObjectAttributesGET ?attributes.
PostObjectBrowser-form direct upload (presigned POST).
RestoreObjectPOST ?restore — rehydrate a tiered object.

Multipart uploads

OperationSupportedNotes
CreateMultipartUploadPOST ?uploads.
UploadPartPUT ?uploadId=&partNumber=.
UploadPartCopyPart sourced from another object.
CompleteMultipartUpload
AbortMultipartUpload
ListPartsGET ?uploadId=.
ListMultipartUploadsGET ?uploads at bucket scope.

Versioning

OperationSupportedNotes
GetBucketVersioning
PutBucketVersioningEnable / suspend.
ListObjectVersionsGET ?versions.

Tagging

OperationSupportedNotes
GetBucketTagging / PutBucketTagging / DeleteBucketTaggingBucket-level tags.
GetObjectTagging / PutObjectTagging / DeleteObjectTaggingObject-level tags.

ACL, policy & encryption

OperationSupportedNotes
GetBucketAcl / PutBucketAclCanned ACLs.
GetObjectAcl / PutObjectAcl
GetBucketPolicy / PutBucketPolicy / DeleteBucketPolicyEvaluated by the same policy engine that enforces scoped keys.
GetBucketEncryption / PutBucketEncryption / DeleteBucketEncryptionSSE-S3 (AES-256) at rest.

CORS & lifecycle

OperationSupportedNotes
GetBucketCors / PutBucketCors / DeleteBucketCorsPreflight honoured on the S3 routes.
GetBucketLifecycleConfiguration / PutBucketLifecycleConfiguration / DeleteBucketLifecycleExpiration + <Transition> (cold-object tiering).

Object lock

OperationSupportedNotes
GetObjectLockConfiguration / PutObjectLockConfigurationGovernance / compliance mode.
GetObjectRetention / PutObjectRetentionPer-object retain-until.
GetObjectLegalHold / PutObjectLegalHoldIndependent hold.

Presign

CapabilitySupportedNotes
Presigned GET / PUT (query auth)Standard X-Amz-* query signing, up to 7-day expiry.
Presigned POST (browser form)Policy document with content-type + length-range conditions.

Known limitations

Path-style addressing only

Virtual-host-style addressing (bucket.host/key) is not supported. Always set forcePathStyle: true in your SDK — requests go to host/bucket/key.

  • Single-node. One Node process over SQLite + the local filesystem. There is no built-in multi-node clustering or sharding. Durability beyond the single node comes from async replication to an external S3 target, not from a distributed data plane.
  • SelectObjectContent (POST ?select) — not implemented (returns NotImplemented).
  • GetObjectTorrent (GET ?torrent) — not implemented.
  • Read-only bucket subresources such as accelerate, logging, request-payment, and website configuration are recognised but not full features — treat them as stubs, not production surfaces.
  • Region. OpenBucket reports a single configured region (default us-east-1); it does not emulate cross-region behaviour or redirects.
Compatibility beyond the AWS SDK

The conformance suite runs the same object round-trips through the aws CLI, MinIO's mc, and s3cmd, so those tools work against OpenBucket out of the box — point them at the endpoint with path-style addressing and the root credentials.

Next steps