Skip to content
Coritan Docs

S3 API compatibility

Which S3 operations work with a read only key, a read and write key or the dashboard, and how checksums, multipart and presigned uploads behave.

View as Markdown

Object Storage answers the Amazon S3 API at each region's endpoint. These tables list what an S3 client can do with each kind of access key, how the request features behave, and what the dashboard does without a key. An operation the page does not list may or may not work, so try it on a test bucket before you rely on it.

What Answer
Signature AWS Signature Version 4, in the Authorization header or in the query string of a presigned URL.
Region in the signature Any name, such as fra, us-east-1 or auto.
Host in the signature The address you connect to, exactly as the dashboard gives it, port included when it has one, such as s3.fra.coritan.com:7337. In virtual-hosted style, the bucket's own hostname. A request signed for another host or port answers 403 SignatureDoesNotMatch (Endpoints, ports and addressing styles).
Addressing Path style in every region, and virtual-hosted style where the dashboard offers it (Endpoints, ports and addressing styles). Connect an S3 client shows the setting for each tool.
GetBucketLocation Answers with no location. Clients read that as us-east-1, which signs as well as any other name.
Temporary credentials (AssumeRole) Not available at the endpoint: an access key that calls it gets 403 AccessDenied. Create temporary credentials in the dashboard or with the API (Create temporary credentials), and send the session token with them.

A key is Read only or Read and write, and works on one bucket or on all your buckets (What a key can do). A request outside its permissions or its scope answers 403 AccessDenied.

Temporary credentials do what a key of the same permissions does with objects, and nothing with a bucket's settings: they cannot read them either (Create temporary credentials).

Operation Read only Read and write
ListBuckets Yes Yes
HeadBucket, GetBucketLocation Yes Yes
ListObjects, ListObjectsV2, ListObjectVersions Yes Yes
GetObject, HeadObject, GetObjectAttributes Yes Yes
GetObjectTagging Yes Yes
ListMultipartUploads, ListParts Yes Yes
GetBucketVersioning, GetBucketCors, GetBucketLifecycleConfiguration Yes Yes
PutObject, CopyObject, DeleteObject, DeleteObjects No Yes
RenameObject No Yes
PutObjectTagging, DeleteObjectTagging No Yes
GetBucketTagging, PutBucketTagging No Yes
CreateMultipartUpload, UploadPart, UploadPartCopy, CompleteMultipartUpload, AbortMultipartUpload No Yes
PutBucketVersioning No No, read Bucket settings
PutBucketCors, DeleteBucketCors, PutBucketLifecycleConfiguration, DeleteBucketLifecycle No No, read Bucket settings
CreateBucket, DeleteBucket No No
GetObjectAcl, PutObjectAcl, GetBucketAcl, PutBucketAcl No No
PutBucketPolicy No No
GetBucketEncryption, PutBucketEncryption, DeleteBucketEncryption No No, read Bucket settings
PutObjectLockConfiguration, PutObjectRetention, PutObjectLegalHold No No
PutBucketNotificationConfiguration, PutBucketReplication, PutBucketWebsite, PutBucketLogging No No
SelectObjectContent, RestoreObject No No

ListBuckets lists only the buckets in the key's scope, so a key limited to one bucket lists that bucket alone. Such a key gets 403 AccessDenied from every other bucket, also as the source of a CopyObject.

DeleteObjects with a read only key answers 200 and deletes nothing. Each key comes back under Errors with the code AccessDenied, so read Errors as well as the status.

SelectObjectContent and RestoreObject answer 405 MethodNotAllowed with any key.

Create and delete buckets, and change their settings, in the dashboard or through the Coritan API (Create and delete buckets). No key can.

A request signed with your key that changes a bucket or object setting answers 403 AccessDenied with the message Change this setting in the dashboard or the Object Storage API. The settings are versioning, CORS, lifecycle rules, Object Lock, retention, legal holds, policies, ACLs, encryption, website, notifications, replication and logging. Change them here instead:

Reading a setting works with any key, as the table above shows. Object tags are yours to write with a read and write key.

Header Request Answer
If-None-Match: * PutObject Writes only when no object has the key. Otherwise 412 PreconditionFailed.
If-Match: <ETag> PutObject Writes only over the object with that ETag. Another ETag, or no object, answers 412.
If-None-Match: <ETag> GetObject The current ETag answers 304 Not Modified.
If-Match: <ETag> GetObject An ETag that is no longer current answers 412.
x-amz-copy-source-if-match CopyObject An ETag that is no longer current answers 412.
If-Match: <ETag> DeleteObject An ETag that is no longer current answers 412.
Range: bytes=0-1023 GetObject Returns those bytes, with Content-Range.
What Answer
Algorithms CRC32, CRC32C, CRC64NVME, SHA-1 and SHA-256 in the x-amz-checksum-* headers, and Content-MD5.
A value that does not match the body 400 BadDigest.
Reading it back HeadObject with x-amz-checksum-mode: ENABLED (ChecksumMode="ENABLED" in boto3) returns the checksum stored with the object.
Multipart uploads Send a checksum with each part. CompleteMultipartUpload answers a checksum of the part checksums that ends in -<number of parts>, with ChecksumType set to COMPOSITE.

Encryption with your own key (SSE-C)

Section titled Encryption with your own key (SSE-C)

Upload with your own 256-bit key in the x-amz-server-side-encryption-customer-* headers, and every read of the object needs the same key. In boto3, pass SSECustomerAlgorithm="AES256" and SSECustomerKey to put_object, get_object and head_object.

Request Answer
PutObject with the key 200, with SSECustomerAlgorithm AES256 in the answer. Needs a read and write key.
GetObject or HeadObject with the same key 200. A read only key works too.
GetObject without the key 400 InvalidArgument.
GetObject with another key 403 AccessDenied.

Warning

Keep the key. Without it, the object cannot be read back.

Default encryption for a whole bucket is separate: Encrypt the objects in a bucket. A PutObject that asks for x-amz-server-side-encryption: AES256 works once default encryption is available, and can answer 500 InternalError until then.

What Answer
Part numbers 1–10,000. 10001 answers 400 InvalidPart.
Part size At least 5 MiB for every part except the last. A smaller one answers 400 EntityTooSmall when you complete the upload.
UploadPartCopy Copies a part from an object in a bucket the key can read.
Unfinished uploads ListMultipartUploads lists them. AbortMultipartUpload removes one with its parts, and ListParts then answers 404 NoSuchUpload.
What Answer
Lifetime of a URL signed with your key Up to 7 days (X-Amz-Expires=604800). Longer answers 400 AuthorizationQueryParametersError.
After it expires 403 AccessDenied.
What it allows What the key allows. A read only key signs GET URLs that work, and its PUT URLs answer 403 AccessDenied.
Content type A PUT URL signed with a Content-Type takes only an upload with that type. Another type answers 403 SignatureDoesNotMatch.
response-content-disposition Sets the Content-Disposition header on the answer.
URLs from the dashboard and the Coritan API 60–3600 seconds (Presigned URLs).

Browser uploads with a POST form

Section titled Browser uploads with a POST form

An HTML form can upload a file straight to a bucket with a POST policy that you sign with a read and write key, such as one from boto3's generate_presigned_post. The form posts to the bucket's URL, such as https://s3.fra.coritan.com:7337/u7-assets.

The form Answer
Meets every condition in the policy 204 No Content, and the object is stored.
Sends a file larger than content-length-range allows 400 EntityTooLarge.
Names a key the policy does not allow 403 AccessDenied.
Carries a policy signed with a read only key 403 AccessDenied.
Has no signature fields 400 AuthorizationQueryParametersError.

ACLs are off on every bucket. An upload with x-amz-acl: public-read or an x-amz-grant-* header succeeds, and the object stays private: a request without a signature still answers 403. To share one object, send a presigned URL.

What Answer
Metadata x-amz-meta-* headers, Cache-Control and Content-Disposition are stored with the object and returned when it is read.
Storage class One class. A StorageClass you send, such as STANDARD_IA, is kept as a label that HeadObject reports, and the object is billed like any other (How Object Storage is billed).
RenameObject Renames an object within its bucket: a PUT to the new key with ?renameObject and the old one in x-amz-rename-source, or rename_object in boto3. The old key then answers 404.

The object browser on a bucket's page uses none of your keys, because we sign each of its requests. It lists objects, uploads files with one request for each file, downloads them, creates folders, and deletes objects and folders (Upload, download and delete objects). Everything else on this page needs an S3 client and a key (Connect an S3 client).