SSE Configuration¶
Configure SSE Using the Zenko CR¶
SSE configuration is managed through the spec.kms block of the Zenko
Custom Resource (CR). The operator translates this into the appropriate
CloudServer config.json block and sets the S3KMS environment variable
on CloudServer pods.
Warning
Changing the KMS backend type or providerName after objects have been
encrypted makes those existing encrypted objects unreadable until the
original configuration is restored. The providerName is embedded in
every encrypted object’s metadata ARN, and ARTESCA rejects decryption if
the stored provider does not match the current configuration.
Restoring the original providerName and KMS backend (with the same keys
still present in the KMS) makes objects readable again.
To permanently switch to a different SSE configuration, first copy all encrypted objects to an unencrypted bucket, apply the new configuration, then re-upload the objects.
No KMS (Internal / File Backend)¶
When spec.kms is omitted from the Zenko CR, ARTESCA uses the internal
KMS by default. No KMS-level configuration is needed in the CR.
The internal KMS only determines where keys are stored. Objects are not
encrypted automatically. Enable encryption at bucket level (using
PutBucketEncryption) or at object level (using
x-amz-server-side-encryption headers on PutObject). This applies
regardless of which KMS backend is configured.
KMIP Backend¶
KMIP (Key Management Interoperability Protocol) is the recommended external KMS for most deployments. ARTESCA communicates with the KMIP server over mutual TLS (mTLS).
Create a Kubernetes secret containing the KMIP client TLS certificates. By default the operator expects three keys named
key.pem,cert.pem, andca.pem. Override these names with thekeyFile,certFile, andcaFilefields.kubectl -n zenko create secret generic kmip-tls-certs \ --from-file=key.pem=<path-to-client-key.pem> \ --from-file=cert.pem=<path-to-client-cert.pem> \ --from-file=ca.pem=<path-to-ca.pem>
The client certificate’s CN/SAN does not need to match a hostname, it is used for client authentication only. The CA certificate must be the CA that signed the KMIP server’s certificate.
Add the
spec.kmsblock to the Zenko CR.spec: kms: kmip: providerName: thales tlsAuth: tlsSecretName: kmip-tls-certs endpoints: - host: kmip-server.example.com port: 5696
The operator then:
Sets the
S3KMS=kmipenvironment variable on CloudServer podsMounts the TLS secret at
/etc/kmip-certs/inside the CloudServer containerGenerates the
config.jsonkmipblock with the provider name, endpoints, TLS certificate paths, and client settings
Kubernetes rolls new CloudServer pods automatically when the deployment spec changes.
Field |
Required |
Description |
|---|---|---|
|
Yes |
Lowercase alphanumeric string embedded in key ARNs. Must
start with a vendor prefix ( |
|
Yes |
Name of the Kubernetes Secret containing KMIP client
certificates. By default expects keys: |
|
No |
Key name for the client private key in the TLS secret.
Default: |
|
No |
Key name for the client certificate in the TLS secret.
Default: |
|
No |
Key name for the CA certificate in the TLS secret.
Default: |
|
Yes |
Array of KMIP server endpoints. Each entry has |
|
No |
Enable Create+Activate in a single KMIP operation.
Default: |
|
No |
Custom KMIP attribute name for storing the bucket name alongside the key on the KMIP server. Empty by default. |
|
No |
Number of pipelined KMIP requests per TLS connection.
Default: |
|
No |
Failover retry count for multi-host clusters.
Default: |
KMIP High Availability¶
When multiple KMIP endpoints are configured, ARTESCA distributes requests using round-robin across all nodes.
If a request fails due to a retryable error (such as a network issue), ARTESCA retries the request on the next node. The failing node is marked as unhealthy for 30 seconds to prevent other requests from being dispatched to it. After this cooldown period, the node is considered healthy again and receives requests normally.
The number of failover retries defaults to len(endpoints) - 1 (that is,
every node is tried once) and can be overridden with the retries field.
Example with a 3-node KMIP cluster:
spec:
kms:
kmip:
providerName: thales
tlsAuth:
tlsSecretName: kmip-tls-certs
endpoints:
- host: kmip-node-1.example.com
port: 5696
- host: kmip-node-2.example.com
port: 5696
- host: kmip-node-3.example.com
port: 5696
retries: 2
Note
KMIP high availability and clustering are only supported with the KMIP backend. The AWS KMS backend expects the KMS provider to handle its own high availability behind a single endpoint.
AWS KMS Backend¶
ARTESCA can use any KMS exposing an AWS KMS-compatible API. This includes AWS KMS itself and third-party KMS products that implement the same API.
Unlike KMIP (which uses mutual TLS for authentication), AWS KMS uses standard HTTPS with SigV4 request signing. ARTESCA authenticates to the KMS endpoint using the configured access key and secret key – no client certificates are needed.
Create a Kubernetes secret containing the AWS credentials.
kubectl -n zenko create secret generic aws-kms-creds \ --from-literal=accessKey=<AWS_ACCESS_KEY> \ --from-literal=secretKey=<AWS_SECRET_KEY>
(Optional – custom CA certificate) If your KMS endpoint uses a certificate signed by a private or corporate CA (that is, not a publicly trusted CA), import the CA certificate into the ARTESCA truststore.
On the ARTESCA UI, go to Data Management > Truststore.
Click Import Certificate and upload the CA certificate (PEM format).
The operator injects imported certificates into CloudServer pods using the
NODE_EXTRA_CA_CERTSenvironment variable, which makes the Node.js TLS stack trust the custom CA for all outgoing HTTPS connections, including calls to the AWS KMS endpoint.Note
If your KMS endpoint uses a certificate from a well-known public CA (for example, AWS KMS itself at
kms.<region>.amazonaws.com), you do not need to import any certificate – the default system trust store already includes it.Add the
spec.kmsblock to the Zenko CR.spec: kms: aws: providerName: awsprod endpoint: https://kms.us-east-1.amazonaws.com credentialsSecretName: aws-kms-creds region: us-east-1
The operator then:
Sets the
S3KMS=awsenvironment variable on CloudServer podsGenerates the
config.jsonkmsAWSblock with credentials, endpoint, and region
Kubernetes rolls new CloudServer pods automatically when the deployment spec changes.
Field |
Required |
Description |
|---|---|---|
|
Yes |
Lowercase alphanumeric string embedded in key ARNs. Should not be modified once set, to avoid making existing encrypted objects unreadable (see warning above). |
|
Yes |
AWS KMS API endpoint URL (for example,
|
|
Yes |
Name of the Kubernetes Secret containing AWS credentials.
Must have keys: |
|
No |
AWS region (for example, |
|
No |
If |
Note
AWS KMS does not require TLS certificate configuration in the CR. Authentication is handled using SigV4 request signing with the credentials secret. If the KMS endpoint uses a private CA, import the CA certificate using the ARTESCA UI truststore (see the optional step above).
Configure Bucket Encryption¶
Bucket-level encryption acts as a default applied to all objects uploaded to the bucket without explicit SSE headers. Individual objects can still override the bucket default by providing per-request SSE headers.
Prerequisites¶
An IAM user with the
s3:PutEncryptionConfigurationpermission, or the root account ownerAn existing bucket
Set Bucket Encryption¶
# AES256 -- platform-managed keys (no user-supplied key ID)
aws s3api put-bucket-encryption --bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}]
}' --endpoint-url http://<s3-endpoint>
# aws:kms -- keys owned by the account (auto-generated key)
aws s3api put-bucket-encryption --bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms"
}
}]
}' --endpoint-url http://<s3-endpoint>
# aws:kms with a specific master key
aws s3api put-bucket-encryption --bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "<key-id>"
}
}]
}' --endpoint-url http://<s3-endpoint>
Query and Remove Bucket Encryption¶
# Get current bucket encryption configuration
aws s3api get-bucket-encryption --bucket my-bucket \
--endpoint-url http://<s3-endpoint>
# Remove bucket encryption default
aws s3api delete-bucket-encryption --bucket my-bucket \
--endpoint-url http://<s3-endpoint>
Removing bucket encryption only affects future uploads – it does not decrypt or modify previously encrypted objects. Those objects remain encrypted and fully readable.
Note
Calling GetBucketEncryption on a bucket that has never had encryption
configured returns a ServerSideEncryptionConfigurationNotFoundError.
Bucket Encryption Error Conditions¶
Specifying
KMSMasterKeyIDwithAES256returnsInvalidArgument(master key IDs are only valid withaws:kms)Specifying an invalid
SSEAlgorithm(anything other thanAES256oraws:kms) returnsMalformedXML
Encrypt Individual Objects¶
Use the --server-side-encryption header when uploading an object:
# AES256
aws s3api put-object --bucket my-bucket --key my-object --body file.txt \
--server-side-encryption AES256 \
--endpoint-url http://<s3-endpoint>
# aws:kms with auto-generated key
aws s3api put-object --bucket my-bucket --key my-object --body file.txt \
--server-side-encryption aws:kms \
--endpoint-url http://<s3-endpoint>
# aws:kms with a specific key ID
aws s3api put-object --bucket my-bucket --key my-object --body file.txt \
--server-side-encryption aws:kms --ssekms-key-id <key-id> \
--endpoint-url http://<s3-endpoint>
Per-request headers always override bucket defaults. Refer to SSE Reference Documentation for the complete interaction rules.
SSE Response Headers¶
When encryption is applied, the following headers are returned in
PutObject, HeadObject, GetObject, and CopyObject responses:
x-amz-server-side-encryption– the algorithm used (AES256oraws:kms)x-amz-server-side-encryption-aws-kms-key-id– the master key ID (only present withaws:kms, absent forAES256)
Per-Object Error Conditions¶
Specifying an invalid algorithm (for example,
INVALID_ALGO) returnsInvalidArgumentSpecifying
SSEKMSKeyIdwithAES256returnsInvalidArgument(key IDs are only valid withaws:kms)

