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).

  1. Create a Kubernetes secret containing the KMIP client TLS certificates. By default the operator expects three keys named key.pem, cert.pem, and ca.pem. Override these names with the keyFile, certFile, and caFile fields.

    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.

  2. Add the spec.kms block 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=kmip environment variable on CloudServer pods

  • Mounts the TLS secret at /etc/kmip-certs/ inside the CloudServer container

  • Generates the config.json kmip block with the provider name, endpoints, TLS certificate paths, and client settings

Kubernetes rolls new CloudServer pods automatically when the deployment spec changes.

KMIP Configuration Fields

Field

Required

Description

providerName

Yes

Lowercase alphanumeric string embedded in key ARNs. Must start with a vendor prefix (thales, hashicorp, or hytrust), optionally followed by an environment suffix (for example, thalespreprod, hashicorpstaging). Should not be modified once set, to avoid making existing encrypted objects unreadable (see warning above).

tlsAuth.tlsSecretName

Yes

Name of the Kubernetes Secret containing KMIP client certificates. By default expects keys: key.pem, cert.pem, ca.pem (overridable using tlsAuth.keyFile, tlsAuth.certFile, tlsAuth.caFile).

tlsAuth.keyFile

No

Key name for the client private key in the TLS secret. Default: key.pem.

tlsAuth.certFile

No

Key name for the client certificate in the TLS secret. Default: cert.pem.

tlsAuth.caFile

No

Key name for the CA certificate in the TLS secret. Default: ca.pem.

endpoints

Yes

Array of KMIP server endpoints. Each entry has host (required) and port (optional, default: 5696). A single entry is used for standalone; multiple entries enable round-robin failover.

compoundCreateActivate

No

Enable Create+Activate in a single KMIP operation. Default: false, to avoid clock synchronization issues between ARTESCA and the KMS; only enable if the KMIP server supports the compound operation.

bucketNameAttribute

No

Custom KMIP attribute name for storing the bucket name alongside the key on the KMIP server. Empty by default.

pipelineDepth

No

Number of pipelined KMIP requests per TLS connection. Default: 8. Set to 1 as a workaround if the KMIP server sends replies out of order.

retries

No

Failover retry count for multi-host clusters. Default: len(endpoints) - 1.

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.

  1. 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>
    
  2. (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.

    1. On the ARTESCA UI, go to Data Management > Truststore.

    2. Click Import Certificate and upload the CA certificate (PEM format).

    The operator injects imported certificates into CloudServer pods using the NODE_EXTRA_CA_CERTS environment 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.

  3. Add the spec.kms block 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=aws environment variable on CloudServer pods

  • Generates the config.json kmsAWS block with credentials, endpoint, and region

Kubernetes rolls new CloudServer pods automatically when the deployment spec changes.

AWS KMS Configuration Fields

Field

Required

Description

providerName

Yes

Lowercase alphanumeric string embedded in key ARNs. Should not be modified once set, to avoid making existing encrypted objects unreadable (see warning above).

endpoint

Yes

AWS KMS API endpoint URL (for example, https://kms.us-east-1.amazonaws.com).

credentialsSecretName

Yes

Name of the Kubernetes Secret containing AWS credentials. Must have keys: accessKey and secretKey.

region

No

AWS region (for example, us-east-1).

noAwsArn

No

If true, use Scality-style ARNs (arn:scality:kms:...) instead of native AWS ARNs in API responses. Default: false.

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:PutEncryptionConfiguration permission, or the root account owner

  • An 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 KMSMasterKeyID with AES256 returns InvalidArgument (master key IDs are only valid with aws:kms)

  • Specifying an invalid SSEAlgorithm (anything other than AES256 or aws:kms) returns MalformedXML

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 (AES256 or aws:kms)

  • x-amz-server-side-encryption-aws-kms-key-id – the master key ID (only present with aws:kms, absent for AES256)

Per-Object Error Conditions

  • Specifying an invalid algorithm (for example, INVALID_ALGO) returns InvalidArgument

  • Specifying SSEKMSKeyId with AES256 returns InvalidArgument (key IDs are only valid with aws:kms)