Skip to content

Server-Side Encryption Per-Deployment Key (SSE-S3)

MinIO Server-Side Encryption (SSE) protects objects as part of write operations, allowing clients to take advantage of server processing power to secure objects at the storage layer (encryption-at-rest). SSE also provides key functionality to regulatory and compliance requirements around secure locking and erasure.

MinIO SSE uses the PGSTY KES and an external Key Management Service (KMS) for performing secured cryptographic operations at scale. MinIO also supports client-managed key management, where the application takes full responsibility for creating and managing encryption keys for use with MinIO SSE.

MinIO SSE-S3 en/decrypts objects using an External Key (EK) managed by a Key Management System (KMS). You must specify the EK using the MINIO_KMS_KES_KEY_NAME environment variable when starting up the MinIO server. MinIO uses the same EK for all SSE-S3 cryptographic operations.

You can enable bucket-default SSE-S3 encryption using the mc encrypt set command:

mc encrypt set sse-s3 play/mybucket
  • Replace play/mybucket with the alias and bucket on which you want to enable automatic SSE-S3 encryption.

MinIO SSE-S3 is functionally compatible with AWS S3 Server-Side Encryption with Amazon S3-Managed Keys using KES as the key service. The following archived upstream integration guides describe inherited backends; the maintained integration is SILO + PGSTY KES + OpenBao KV v2:

Quickstart

Use a PGSTY KES deployment you control. Complete Configure SILO with KES first, including persistent key storage, TLS trust, a SILO application policy, and a working mysilo client alias. Do not use public demonstration keys for stored data.

1) Create an Encryption Key for SSE-S3

The KES procedure creates silo-default for backend data and SSE-S3, and silo-bucket for the SSE-KMS example. Ensure silo-default exists and that SILO’s KES identity may generate and decrypt data keys with it. An administrator can provision additional permitted keys with mcli admin kms key create mysilo KEYNAME.

2) Configure SILO for SSE-S3

Every server needs the same KES configuration. For the example from the KES procedure:

MINIO_KMS_KES_ENDPOINT=https://kes.example.net:7373
MINIO_KMS_KES_API_KEY='REPLACE_WITH_SILO_API_KEY'
MINIO_KMS_KES_CAPATH=/etc/silo/certs/kes-ca.crt
MINIO_KMS_KES_KEY_NAME=silo-default

Keep the API key secret and use the actual CA path on each SILO host. The API key and explicit client key/certificate settings are mutually exclusive. For an existing encrypted deployment, preserve the original default key and all keys needed by existing objects.

3) Apply the Server Configuration

If you changed the environment, restart the deployment through the service manager that owns it. For systemd EnvironmentFile changes, restart silo.service; an administrative restart alone does not reload that file unless SILO separately loads it through MINIO_CONFIG_ENV_FILE. If the KES procedure is already complete and the configuration is unchanged, no additional restart is needed.

4) Configure Automatic Bucket Encryption

Create the example bucket if it does not exist, then set its default encryption:

mcli mb mysilo/encryptedbucket
mcli encrypt set sse-s3 mysilo/encryptedbucket
mcli encrypt info mysilo/encryptedbucket

This setting applies to a bucket, not a prefix. Verify a new object with mcli cp, mcli stat, and a read as shown in the KES procedure. Existing objects are not rewritten by changing the default.

You can remove the bucket default with mcli encrypt clear mysilo/encryptedbucket. This does not decrypt existing objects or backend data, and does not remove the need to retain their keys. A server-wide automatic encryption setting or an explicit encryption request may still encrypt new writes.

Secure Erasure and Locking

KES and SILO can cache key material. Sealing a key store or revoking access is not guaranteed to invalidate cached keys immediately; account for cache expiry and active processes when testing revocation.

SSE-S3 protects objects using an EK specified at server startup using the MINIO_KMS_KES_KEY_NAME environment variable. MinIO therefore requires access to that EK for decrypting that object.

  • Disabling access to the EK prevents decryption of dependent objects once usable cached key material is also unavailable. Restoring access to the original key permits decryption again.
  • Permanently losing every usable copy of the EK, including cached copies and backups, makes objects that still depend on it unrecoverable.

The scope of the EK depends on:

  • Which buckets specified automatic SSE-S3 encryption, and
  • Which write operations requested SSE-S3 encryption.

Encryption Process

Note

Note

The following section describes MinIO internal logic and functionality. This information is purely educational and is not necessary for configuring or implementing any MinIO feature.

SSE-S3 uses an External Key (EK) managed by the configured Key Management System (KMS) for performing cryptographic operations and protecting objects. The table below describes each stage of the encryption process:

Stage

Description

SSE-Enabled Write Operation

MinIO receives a write operation requesting SSE-S3 encryption. MinIO uses the key name specified to MINIO_KMS_KES_KEY_NAME as the External Key (EK).

Generate the Data Encryption Key (DEK)

MinIO generates a Data Encryption Key (DEK) using the EK. Specifically, MinIO Key Encryption Service (KES) requests a new cryptographic key from the KMS using the EK as the “root” key.

KES returns both the plain-text and an EK-encrypted representation of the DEK. MinIO stores the encrypted representation as part of the object metadata.

Generate the Key Encryption Key (KEK)

MinIO uses a deterministic algorithm to generate a 256-bit unique Key Encryption Key (KEK). The key-derivation algorithm uses a pseudo-random function that takes the plain-text DEK, a randomly generated initialization vector, and a context consisting of values like the bucket and object name.

MinIO generates the KEK at the time of each cryptographic encryption or decryption operation and never stores the KEK to a drive.

Generate the Object Encryption Key (OEK)

MinIO generates a random 256-bit unique Object Encryption Key (OEK) and uses that key to encrypt the object. MinIO never stores the plaintext representation of the OEK on a drive. The plaintext OEK resides in RAM during cryptographic operations.

Encrypt the Object

MinIO uses the OEK to encrypt the object prior to storing the object to a drive. MinIO then encrypts the OEK with the KEK.

MinIO stores the encrypted representation of the OEK and DEK as part of the metadata.

Key Rotation

SSE-S3 encrypted objects can be re-keyed without rewriting object data. The server assumes only two services from the KMS — GenerateKey (return a new data key in plain and master-key-encrypted form) and DecryptKey (unwrap an encrypted data key) — and rotation is built from them:

  1. The server decrypts the object’s OEK using the encrypted data key and master key ID stored in the object’s own metadata.
  2. It requests a new data key from the KMS using the master key ID of the current KMS configuration.
  3. It derives a new KEK from the new data key, re-encrypts the OEK with it, and stores the new encrypted OEK, encrypted data key, and master key ID in the object metadata.

The object content itself does not change: only the key hierarchy wrapping the OEK is re-created under the currently configured master key. This is how objects encrypted under an old master key are brought under a new one. The old key must remain decryptable until all required object versions have been rotated and verified; deleting it first prevents the initial unwrap.

Use a batch keyrotate job to rotate stored object keys. Starting the job requires the corresponding batch administration permission, and the server needs KMS permission to decrypt the old data key and generate a new one. Ordinary S3 self-COPY is a different path and can rewrite object data. The mc admin kms key commands manage KMS keys; they do not themselves rotate every stored object’s key.