API Coverage

Mini S3 uses path-style addressing only: https://host/{bucket}/{key}. There is no virtual-hosted-style addressing (bucket.host/key).

Implemented

These behave according to the S3 API, with the simplifications noted below:

Operation Notes
ListBuckets Returns only the buckets the caller's access key can read or write.
HeadBucket
GetBucketLocation Mini S3 has no regions: reports the region the request was signed for (empty for us-east-1, as S3 does), so clients that switch to the bucket's region keep working.
GetBucketVersioning Always reports versioning as never enabled.
ListObjects / ListObjectsV2
ListObjectVersions Every current object is reported as a single version with VersionId=null, IsLatest=true — Mini S3 does not implement real versioning.
GetObject Supports single-range Range requests.
HeadObject
PutObject Supports standard, aws-chunked unsigned-trailer, and aws-chunked signed-chunk request bodies.
DeleteObject
DeleteObjects
CopyObject Same-bucket copies only.
RenameObject PUT /{bucket}/{key}?renameObject= with the source key in the x-amz-rename-source header (this is the actual wire format real S3 clients use, not a documentation artifact). Supports x-amz-if-none-match: * to fail if the destination already exists.
CreateMultipartUpload
UploadPart
CompleteMultipartUpload ETag is the standard <md5-of-part-md5s>-<part-count> form.
AbortMultipartUpload
ListParts
CreateSession See below — Mini S3 has no real STS.

CreateSession

Mini S3 has no AWS STS equivalent. CreateSession verifies the caller's normal SigV4 credentials for the bucket, then returns those same long-term access_key_id/secret_access_key back to the caller as the "session credentials," paired with a randomly generated, opaque session token valid for 5 minutes. Subsequent requests must present that token via the x-amz-s3session-token header (as real S3 Express clients do) and must still be SigV4-signed with the same key/secret; Mini S3 checks the token is unexpired and scoped to the same bucket and access key before honoring it. This satisfies the request shape SDKs expect without Mini S3 having to implement a real token-issuing service.

Not implemented

These return AccessDenied (HTTP 403), per the original design goals — Mini S3 has no bucket lifecycle, ACL, tagging, or object-lock model. Each denial is logged at info level ("denied unsupported operation", with the method, path, and query), so a client failing on one of these is visible in the log:

  • CreateBucket, DeleteBucket*
  • DeletePublicAccessBlock
  • GetBucket* other than GetBucketLocation/GetBucketVersioning (any other GET /{bucket}?<sub-resource>, e.g. ?acl, ?policy, ?cors, ...)
  • GetObject* variants other than plain GetObject (e.g. ?acl, ?tagging, ?legal-hold, ?retention)
  • ListBucket* variants other than ListObjects/ListObjectsV2/ListObjectVersions
  • PutBucket*, PutObject* variants other than plain PutObject
  • RestoreObject
  • UpdateBucket*, UpdateObjectEncryption
  • WriteGetObjectResponse
  • UploadPartCopy and any other S3 operation not listed above

Known fidelity gaps

  • X-Amz-Content-Sha256 is verified as part of the SigV4 signature, but the declared hash is not cross-checked against the actual bytes received for non-chunked request bodies (chunked/streaming bodies are cryptographically verified per-chunk when signed, see internal/auth/chunked.go). Since a valid signature is still required, this only matters for a caller who already holds valid credentials.
  • Multi-range GetObject requests (Range: bytes=0-1,5-6) are not supported; the whole object is returned instead.
  • ListObjectsV2's common-prefix / key interleaving does not exactly match S3's pagination semantics when both objects and common prefixes are present in the same page (max-keys is applied to objects only).