minio/minio
KMS and encryption
Server-side encryption (SSE-S3, SSE-KMS, SSE-C) is implemented in two layers: a low-level crypto package (internal/crypto/) and a key-management abstraction (internal/kms/). The runtime exposes admin and key-rotation endpoints under /minio/kms/v1.
Purpose
- Encrypt object data at rest with per-object data keys (DEKs) wrapped by a key encryption key (KEK).
- Plug into an external KMS (KES, AWS KMS via KES) for KEK management.
- Fall back to a local secret-derived KEK for development.
Layout
cmd/
├── encryption-v1.go # SSE wiring: read/write paths
├── encryption-v1_test.go
├── kms-handlers.go # /minio/kms/v1/*
├── kms-router.go
internal/crypto/
├── crypto.go # Top-level encrypt/decrypt
├── auto-encryption.go # Server-default encryption
├── header.go # SSE headers
├── key.go # Object encryption keys
├── metadata.go # Per-object SSE metadata
├── sse.go, sse-s3.go, sse-kms.go, sse-c.go
internal/kms/
├── config.go, single-key.go # Local single-KEK fallback
├── kms.go # Public KMS interface
├── kes.go, kes-conn.go # KES client (mTLS)
├── builtin.go # Built-in cipher
├── policy.go # Encryption policy decisions
└── stub.go # No-op KMSKey abstractions
| Symbol | File | What it is |
|---|---|---|
kms.KMS |
internal/kms/kms.go |
The interface every KMS backend implements. |
singleKeyKMS |
internal/kms/single-key.go |
Local single-KEK; for dev/test. |
kesKMS |
internal/kms/kes.go |
Production KES client. |
crypto.SSE, SSEC, SSES3, SSEKMS |
internal/crypto/sse*.go |
Encrypt/decrypt wrappers per scheme. |
objectEncryptionKey |
internal/crypto/key.go |
The DEK derived for each object. |
EncryptedObject |
internal/crypto/crypto.go |
Helper used by the read/write paths. |
How it works
graph TD
PUT[PutObject] --> SEL{SSE header?}
SEL -- SSE-C --> SSEC[Use client-supplied KEK]
SEL -- SSE-KMS --> KMS[KMS.GenerateDEK]
SEL -- SSE-S3 --> KMS
KMS --> WRAP[Wrap DEK with KEK]
WRAP --> ENC[Encrypt parts with DEK using sio]
ENC --> META[Store encrypted DEK + metadata in xl.meta]SSE schemes
- SSE-S3. Server-managed encryption. The KMS issues a DEK; the wrapped DEK is stored alongside the object. Default-on if
MINIO_KMS_AUTO_ENCRYPTION=on(internal/crypto/auto-encryption.go). - SSE-KMS. Same mechanism, but the client picks the KEK by name and may pass an encryption context.
- SSE-C. The client provides the KEK with each request. MinIO never persists the KEK; only the DEK encrypted with the client KEK is stored.
The DEK encrypts payloads using github.com/minio/sio (constant-time AEAD over fixed-size segments). Per-part keys are derived in internal/crypto/key.go.
KES integration
internal/kms/kes.go opens an mTLS connection to a KES server and uses it for GenerateKey, DecryptKey, and Status calls. KES in turn can be backed by Vault, AWS KMS, GCP KMS, Azure Key Vault, or its own file-based store. The connection uses aead.dev/mtls for client-cert auth.
Local fallback
For development, singleKeyKMS derives a KEK from MINIO_KMS_SECRET_KEY (or MINIO_KMS_MASTER_KEY legacy) and provides the same interface. This is what the make test flow uses.
Auto-encryption
internal/crypto/auto-encryption.go lets an operator force every PUT through SSE-S3 even if the client didn't ask for it. The decision is made in cmd/encryption-v1.go before the data hits the erasure encoder.
Bucket encryption configuration
The S3 bucket-encryption API (cmd/bucket-encryption-handlers.go and internal/bucket/encryption/) lets each bucket pin a default encryption scheme. The header presence on a PUT overrides the bucket setting.
KMS admin endpoints
Routes in cmd/kms-router.go:
GET /minio/kms/v1/statusGET /minio/kms/v1/key/listPOST /minio/kms/v1/key/createPOST /minio/kms/v1/key/import(KES variants)
mc admin kms key is the user-facing CLI.
Key rotation
- Per-object batch rotation.
cmd/batch-rotate.godefines a batch job that re-wraps DEKs with a new KEK without re-uploading payload bytes. - Bucket key rotation. Triggered from
mc admin kms key rotate.
Integration points
cmd/object-handlers.go(PUT/GET path) pulls incrypto.EncryptedObjectand the KMS.cmd/object-multipart-handlers.goderives per-part keys.cmd/encryption-v1.gois the bridge between the handler layer andinternal/crypto/.internal/bucket/encryption/parses the S3 bucket-encryption XML.
Entry points for modification
- Add a KMS provider. Implement the
kms.KMSinterface in a new file underinternal/kms/, register it withinternal/config/, document the env vars. - Add an SSE variant. Place the wrapper in
internal/crypto/, updateinternal/crypto/header.go, and wire the headers throughcmd/encryption-v1.go. - Tune cipher chunk size. It comes from
github.com/minio/siodefaults; changing it requires backwards-compatibility planning because it changes on-disk layout.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.