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.
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.
Signing and addressing
Section titled Signing and addressing| 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. |
What each key can do
Section titled What each key can doA 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.
Bucket settings
Section titled Bucket settingsCreate 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:
- Versioning and Object Lock: Versioning and Object Lock.
- CORS: CORS rules.
- Lifecycle rules: Lifecycle rules.
- Encryption: Encrypt the objects in a bucket. No key can read the encryption setting either.
Reading a setting works with any key, as the table above shows. Object tags are yours to write with a read and write key.
Conditional requests
Section titled Conditional requests| 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. |
Checksums
Section titled Checksums| 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.
Multipart uploads
Section titled Multipart uploads| 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. |
Presigned URLs
Section titled Presigned URLs| 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 formAn 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. |
Objects and ACLs
Section titled Objects and ACLsACLs 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. |
In the dashboard
Section titled In the dashboardThe 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).