Encryption
Encryption with SOS is realized at various levels:
- Data in transit
- Data at rest
Encryption in transit
By default all data and metadata sent to or retrieved from buckets using SOS endpoints over HTTPs is encrypted in transit using TLS.
Encryption at rest
To protect data at rest, multiple options are available when using SOS:
- Client side encryption: data is encrypted before being sent to SOS by the client library, tool or code. With this mode, the encryption process, encryption key and libraries are fully managed by you.
- Server side encryption: data is transparently encrypted by SOS upon reception and transparently deciphered at egress, without any extra costs.
Exoscale supports two types of server-side encryption at rest:
- Server-side encryption with Exoscale-managed keys (
SSE-SOS) (recommended) - Server-side encryption with customer-provided keys (
SSE-C)
SSE-SOS
All new buckets are created with SSE-SOS encryption enabled by default. Your data is automatically encrypted at rest without any additional configuration required.
Enabling SSE-SOS on existing buckets
For buckets created before this feature was enabled by default, you can manually enable SSE-SOS:
aws --endpoint https://sos-ch-gva-2.exo.io/ s3api put-bucket-encryption --bucket my-bucket --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'This can also be configured using Terraform:
resource "aws_s3_bucket_server_side_encryption_configuration" "my-bucket" {
bucket = aws_s3_bucket.my-bucket.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}Transferring objects with SSE-SOS
Uploading and downloading encrypted objects works seamlessly, nothing has to be changed within your application or tools. The only visible difference being an extra header informing you about the encryption status of an object.
You can confirm that encryption at rest is enabled by writing an object to a
bucket, and observing the "ServerSideEncryption" header in the response:
$ aws --endpoint https://sos-ch-gva-2.exo.io/ s3api put-object --bucket my-bucket --key sse-sos-object.txt --body plain-text-file.txt
{
"ETag": "\"da17b5a1c4cd2a8b55f98628e1f1089f\"",
"ServerSideEncryption": "AES256"
}The same header is visible when retrieving object metadata using the GetObject and HeadObject operations:
> aws --endpoint https://sos-ch-gva-2.exo.io/ s3api head-object --bucket my-bucket --key sse-sos-object.txt
{
"AcceptRanges": "bytes",
"LastModified": "2025-09-12T14:38:01+00:00",
"ContentLength": 1050,
"ETag": "\"da17b5a1c4cd2a8b55f98628e1f1089f\"",
"VersionId": "null",
"ContentType": "application/binary",
"ServerSideEncryption": "AES256",
"Metadata": {}
}
> aws --endpoint https://sos-ch-gva-2.exo.io/ s3api get-object --bucket my-bucket --key sse-sos-object.txt /dev/null
{
"AcceptRanges": "bytes",
"LastModified": "2025-09-12T14:38:01+00:00",
"ContentLength": 1050,
"ETag": "\"da17b5a1c4cd2a8b55f98628e1f1089f\"",
"VersionId": "null",
"ContentType": "application/binary",
"ServerSideEncryption": "AES256",
"Metadata": {}
}Note that objects uploaded before enabling SSE-SOS will not be automatically
encrypted and will not have the "ServerSideEncryption" header returned when
you try to access them.
SSE-C
To use SSE-C (Server-Side Encryption with Customer-Provided Keys), you must manage your own encryption keys. Data can only be retrieved by providing the original key used during upload. Therefore, you must store your keys in a durable and highly available manner, as Exoscale does not store or recover your keys.
The keys must be 256-bit AES keys and provided to the SOS API in base64-encoded format. An example command to generate such a key is:
openssl rand -out my_personal_sse-c.key 32Transferring objects with SSE-C
Uploading and downloading encrypted objects works similarly to standard operations. You use the cp operation, passing the encryption key as a command-line parameter.
It is your responsibility to track which key is used for each object.
The following command generates the 256-bit base64-encoded string for use as the encryption key:
cat /dev/urandom | head -c 32 | base64 -Object upload:
mc cp encrypted_file_to_upload.txt myminio/mylockedbucket/encrypted_file_uploaded.txt --encrypt-key "myminio/mylockedbucket/=wMEoiDXcIAh/uxEQ4vAKaoNwrOQmK5yrseIKieUO494="If you attempt to display the content of the encrypted object without supplying the encryption key, you should receive the following error to confirm that it has been server-side encrypted correctly.
mc cat myminio/mylockedbucket/encrypted_file_uploaded.txtOutput:
mc: Unable to read from myminio/mylockedbucket/encrypted_file_uploaded.txt. 400 Bad Request.Limitations
- No CLI or Portal support: SSE-C is not currently supported through the Exoscale Portal or standard CLI interfaces. Use tools that natively support SSE-C.
- No key rotation via copy: SOS does not support copying objects using different keys. To change keys, you must download the object locally and re-upload it with the new key.
- No replication: Objects encrypted with SSE-C cannot be replicated using SOS Bucket Replication.
Note
All new buckets are created with SSE-SOS enabled by default.
Once enabled, SSE-SOS cannot be disabled. It acts as a default for new uploads, while still allowing SSE-C to be used on specific objects if needed.
Note
SSE-KMS, while similar to SSE-SOS, is currently not supported on Exoscale. A KMS implementation is planned for future release and this page will be updated accordingly when available.