PutBucketEncryption
PutBucketEncryption sets a bucket's default server-side encryption: the encryption applied to new
objects uploaded without an encryption header of their own. On STRG that default is
server-side encryption with STRG-managed keys (AES256) - we look after the keys, so there is
nothing more to choose. GetBucketEncryption reads the setting back.
The default applies to objects uploaded from the moment it is set. Objects already in the bucket keep the encryption they were stored with, and an upload that brings its own key (SSE-C) is encrypted with that key instead.
AES256is the default there is, with the keys managed for you. SSE-KMS (aws:kms,aws:kms:dsse), a KMS key ID, bucket keys and blocked encryption types answer501 NotImplemented, so a client knows straight away.- The configuration holds exactly one
Rule. - Every request carries an integrity header -
Content-MD5or anx-amz-checksum-*header. The AWS SDKs and the AWS CLI send one on their own, so this is taken care of. - Once set, the default stays:
DeleteBucketEncryptionanswers501 NotImplemented. x-amz-expected-bucket-owneris welcome and has nothing to check: a key only ever reaches buckets of its own account.
When you'd use it
- A compliance baseline asks for default encryption on every bucket. The script that sets up a
new bucket calls PutBucketEncryption with
AES256, and later audits confirm it with GetBucketEncryption. - Infrastructure-as-code tools often declare a bucket's default encryption next to the bucket
itself. With
AES256in that declaration, they apply it here the same way they do on Amazon S3. - An agent setting up a bucket for a new project sets the default before it writes anything, so every object it stores afterwards is encrypted without each upload having to ask.
Request
PUT /?encryption HTTP/1.1
Host: my-bucket.s3.eu-central-1.strg.com
Authorization: AWS4-HMAC-SHA256 Credential=...
x-amz-date: 20260926T120000Z
x-amz-content-sha256: <SHA-256 of the body>
Content-MD5: <base64 MD5 of the body>
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Rule>
<ApplyServerSideEncryptionByDefault>
<SSEAlgorithm>AES256</SSEAlgorithm>
</ApplyServerSideEncryptionByDefault>
</Rule>
</ServerSideEncryptionConfiguration>
Path-style, the same request is PUT /my-bucket?encryption on s3.eu-central-1.strg.com.
Addressing describes both styles.
Permissions
The access key needs Manage encryption (bucket-encryption:write). A key limited to
certain buckets can hold it too, and then reaches only those buckets. A key without it is
answered 403 AccessDenied. Access keys has the details.
URI parameters
| Name | Type | Required | Description |
|---|---|---|---|
Bucket | String | Yes | The bucket whose default encryption is set. |
encryption | Flag | Yes | Selects the encryption subresource. Sent without a value. |
Any other query parameter is answered 501 NotImplemented, so a client knows straight away that
it has no effect here.
Request headers
| Name | Type | Required | Description |
|---|---|---|---|
Content-MD5 | String | Conditional | The base64 MD5 digest of the body. Either this or an x-amz-checksum-* header is required, and a request with neither is answered 400 InvalidRequest. A digest that does not match the body is 400 BadDigest. The AWS SDKs and the AWS CLI send an integrity header on their own. |
x-amz-sdk-checksum-algorithm | String | No | Accepted, with the x-amz-checksum-* header the SDK sends beside it. That checksum header satisfies the integrity requirement above. |
x-amz-expected-bucket-owner | String | No | Welcome, and has nothing to check: an access key only ever reaches its own account's buckets. |
Request body
A ServerSideEncryptionConfiguration document of at most 2 MiB. STRG reads it strictly, so
the configuration applied is exactly the one meant: XML comments, CDATA sections, processing
instructions, a DTD, namespace prefixes and any attribute other than xmlns answer
400 MalformedXML, as does any element not listed here or listed more than once. The documents
the AWS SDKs and the AWS CLI build all fit.
| Element | Type | Required | Description |
|---|---|---|---|
ServerSideEncryptionConfiguration | Container | Yes | The root element. |
Rule | Container | Yes | Exactly one. A second Rule is 400 MalformedXML. |
ApplyServerSideEncryptionByDefault | Container | Yes | The default applied to new objects. |
SSEAlgorithm | String | Yes | AES256: server-side encryption with STRG-managed keys. aws:kms and aws:kms:dsse answer 501 NotImplemented; any other value is 400 MalformedXML. |
KMSMasterKeyID | String | No | STRG answers 501 NotImplemented: STRG manages the keys, so there is no KMS key to name. |
BucketKeyEnabled | Boolean | No | false is welcome and changes nothing. true answers 501 NotImplemented: bucket keys belong to SSE-KMS. |
BlockedEncryptionTypes | Container | No | STRG answers 501 NotImplemented: there is no setting for blocking encryption types. |
Response
A successful request answers 200 OK with an empty body.
Response headers
| Name | Description |
|---|---|
x-amz-request-id | The request ID, for support requests. |
Response body
None.
Errors
These are the errors this operation can answer, and the situation behind each.
| Code | HTTP status | When |
|---|---|---|
MalformedXML | 400 | The body is not well-formed, is not UTF-8, uses an XML feature STRG reads strictly (above), or does not match the schema above. |
InvalidRequest | 400 | Neither Content-MD5 nor an x-amz-checksum-* header was sent. |
BadDigest | 400 | Content-MD5 does not match the body. |
XAmzContentSHA256Mismatch | 400 | x-amz-content-sha256 does not match the body. |
MaxMessageLengthExceeded | 400 | The body is larger than 2 MiB. |
NotImplemented | 501 | The configuration asks for SSE-KMS, a KMS key ID, a bucket key or blocked encryption types, or the request carries a query parameter this operation does not accept. |
NoSuchBucket | 404 | The bucket does not exist, it is in a region other than the endpoint's, or your account has no storage in this endpoint's region yet. |
AccessDenied | 403 | The access key lacks Manage encryption, or is limited to buckets that do not include this one. |
InvalidAccessKeyId | 403 | The access key does not exist, has expired or been revoked, or was created so recently that it is not yet usable in this endpoint's region - a moment later it is. |
SignatureDoesNotMatch | 403 | The request signature is wrong. |
RequestTimeTooSkewed | 403 | The request time is more than 15 minutes from the server's. |
AuthorizationHeaderMalformed | 400 | The signature's credential scope names a region other than the endpoint's. |
SlowDown | 503 | Too many requests at once; a retry after the Retry-After interval goes through. |
ServiceUnavailable | 503 | A temporary failure; a retry usually succeeds. |
Differences from Amazon S3
A few things work a little differently on STRG, each listed here with what it means for your requests.
| Aspect | Amazon S3 | STRG |
|---|---|---|
| Algorithms | AES256 (SSE-S3), aws:kms, aws:kms:dsse | AES256, server-side encryption with STRG-managed keys - one choice, with no keys for you to manage. SSE-KMS answers 501 NotImplemented |
BucketKeyEnabled, BlockedEncryptionTypes | Supported | Neither setting exists on STRG: BucketKeyEnabled false is welcome and changes nothing; true and BlockedEncryptionTypes answer 501 NotImplemented |
| Removing the default | DeleteBucketEncryption resets the bucket to SSE-S3 | The default stays once set; DeleteBucketEncryption answers 501 NotImplemented (Other S3 operations) |
| Integrity header | Content-MD5 or a checksum | The same, on every request - the SDKs send one by default |
| Request body | Any document valid against the schema | Read strictly, at most 2 MiB: comments, CDATA, a DTD and namespace prefixes answer 400 MalformedXML |
| Bucket in another region | 301 redirect with x-amz-bucket-region | 404 NoSuchBucket. Each bucket answers on its own regional endpoint. |
x-amz-expected-bucket-owner | Checked against the bucket owner | Welcome, with nothing to check: a key only ever reaches buckets of its own account |
An object uploaded before the default was set can be encrypted by copying it onto itself with
CopyObject, sending x-amz-server-side-encryption: AES256. Since every bucket
keeps every version, the copy becomes the current version and the earlier one stays, billed as
stored data, until it is deleted or a lifecycle policy removes it.
Examples
Each example sets AES256 as the default encryption of my-bucket.
- AWS CLI
- Python (boto3)
- JavaScript (AWS SDK v3)
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}' \
--endpoint-url https://s3.eu-central-1.strg.com \
--region eu-central-1
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://s3.eu-central-1.strg.com",
region_name="eu-central-1",
)
s3.put_bucket_encryption(
Bucket="my-bucket",
ServerSideEncryptionConfiguration={
"Rules": [
{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}},
],
},
)
import { PutBucketEncryptionCommand, S3Client } from "@aws-sdk/client-s3";
const client = new S3Client({
endpoint: "https://s3.eu-central-1.strg.com",
region: "eu-central-1",
});
await client.send(
new PutBucketEncryptionCommand({
Bucket: "my-bucket",
ServerSideEncryptionConfiguration: {
Rules: [{ ApplyServerSideEncryptionByDefault: { SSEAlgorithm: "AES256" } }],
},
}),
);
Related
- GetBucketEncryption - reading the default back
- PutObject - per-object encryption headers, including your own key (SSE-C)
- CopyObject - re-encrypting an existing object
- Access keys
- S3 API overview