Legacy encryption architectures encrypt at the volume or drive level—one compromised key exposes everything. Storage encryption that slows down workloads gets disabled, and teams find out at the audit. With data breaches averaging $4.44M globally and $10.22M in the US, organizations need encryption that scales without becoming a bottleneck and limits blast radius by design.
Answer
MinIO AIStor encrypts every object with its own unique key, limiting breach impact to a single object rather than an entire volume or dataset. Encryption happens inline with erasure coding in a single atomic operation[1]—no staging buffers where plaintext waits. Keys are wrapped and stored with object metadata[2], not in a central database. AES-256-GCM with SIMD hardware acceleration[3] keeps encryption at wire speed. The result is encryption that scales to exabytes without degradation.
The Problem: Encryption That Doesn’t Scale Gets Disabled
The Reality of Legacy Encryption
| Problem | Impact |
|---|---|
| Volume-level encryption | One compromised key exposes entire dataset |
| Performance degradation | Teams disable encryption to meet SLAs |
| Staging buffers | Plaintext sits in memory waiting for encryption |
| Central key database | Single point of failure, attack surface |
| RMA exposure | Drives returned with recoverable data |
| Key management bottleneck | Legacy KMS built for thousands, not billions of keys |
What Organizations Need
- Per-object encryption that isolates blast radius
- Inline encryption with no staging vulnerabilities
- Wire-speed performance that doesn’t impact workloads
- Key management that scales to billions of objects
- Audit evidence proving encryption for compliance
The AIStor Solution: Encryption Built Into the Data Path
Architectural Overview
┌─────────────────────────────────────────────────────────────────────┐│ AIStor Encryption Architecture │├─────────────────────────────────────────────────────────────────────┤│ ││ Client Write Request ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ TLS 1.3 Transport │ ││ │ (TLS_AES_256_GCM_SHA384, ECDHE cipher suites) [4] │ ││ └─────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ Generate Unique Object Key (DEK) │ ││ │ 32-byte key derived with HMAC-SHA256 [5] │ ││ └─────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ KMS Wraps DEK with Customer Master Key │ ││ │ CMK never leaves KMS/HSM boundary [6] │ ││ └─────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ Inline Encryption + Erasure Coding (Atomic) [1] │ ││ │ ┌───────────────┐ ┌───────────────┐ │ ││ │ │ AES-256-GCM │ → │ Reed-Solomon │ → Distributed Shards │ ││ │ │ (SIMD accel) │ │ Encoding │ │ ││ │ └───────────────┘ └───────────────┘ │ ││ └─────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ Wrapped Key Stored with Object Metadata [2] │ ││ │ No central key database │ Key travels with object │ ││ └─────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────┘Inline Encryption: No Staging, No Waiting
How It Works
When an object is written, AIStor encrypts it simultaneously with erasure coding[1]:
// cmd/encryption-v1.go:513-525func newEncryptReader(ctx context.Context, content io.Reader, ...) { // Wrap content reader with encryption BEFORE erasure coding encryptedReader := sio.EncryptReader(content, sio.Config{ Key: objectKey, CipherSuites: crypto.DARECiphers(), // AES-256-GCM }) // Data flows: plaintext → encryption → erasure coding → disk // No staging buffer, no intermediate state}By the time the write is acknowledged, data is already encrypted and distributed across the cluster.
Single Atomic Operation
| Step | Traditional | AIStor |
|---|---|---|
| 1 | Receive plaintext | Receive plaintext |
| 2 | Stage to buffer | Encrypt inline |
| 3 | Encrypt staged data | Erasure code |
| 4 | Write encrypted | Write to disk |
| 5 | Erasure code | Done |
| 6 | Write to disk | — |
Result: No plaintext buffer window. No staging vulnerability. One atomic operation.
Read Path
Read Request → Retrieve Encrypted Shards → KMS Unwraps DEK →Decrypt Inline → Stream to Client over TLSEncrypted objects are retrieved, the KMS unwraps the DEK using the CMK, and decryption streams directly to the client. Corrupted authentication tags fail fast with clear errors.
Per-Object Unique Keys: Blast Radius by Design
Key Generation
Each object receives a unique 256-bit Data Encryption Key (DEK)[5]:
// internal/crypto/key.go:34-55func GenerateKey(extKey []byte, random io.Reader) (key ObjectKey) { // Generate cryptographically unique nonce io.ReadFull(random, nonce[:]) // Derive 32-byte (256-bit) object key via HMAC-SHA256 mac := hmac.New(sha256.New, extKey) mac.Write(nonce[:]) mac.Sum(key[:0]) return key}Blast Radius Comparison
| Encryption Model | One Key Compromised = |
|---|---|
| Volume-level | Entire volume exposed |
| Drive-level | All data on drive exposed |
| Bucket-level | All objects in bucket exposed |
| AIStor per-object | Single object exposed |
Why This Matters
- Breach containment — Compromise limited to one object
- Compliance — Demonstrable isolation for regulators
- Risk reduction — No “master key” that unlocks everything
AES-256-GCM with Hardware Acceleration
Encryption Algorithm
AIStor uses AES-256-GCM with the DARE v2 protocol[3]:
// internal/crypto/fips.go:22-29func DARECiphers() []byte { if fips.Enabled { return []byte{sio.AES_256_GCM} // FIPS: AES-256-GCM only } return []byte{sio.AES_256_GCM, sio.CHACHA20_POLY1305}}Performance Characteristics
| Aspect | Implementation |
|---|---|
| Algorithm | AES-256-GCM (DARE v2) |
| Key size | 256-bit per object |
| Acceleration | SIMD hardware via sio package |
| Throughput | Wire speed (near-zero overhead) |
| FIPS mode | AES-256-GCM only |
SIMD acceleration uses processor vector instructions (AES-NI on Intel/AMD, AES on ARM) to encrypt at wire speed without CPU bottleneck.
TLS 1.3 Transport Security
Cipher Suites
All client-server and inter-node communication uses TLS 1.3 with TLS 1.2 fallback[4]:
// internal/crypto/fips.go:37-58func TLSCiphers() []uint16 { return []uint16{ // TLS 1.3 ciphers tls.TLS_CHACHA20_POLY1305_SHA256, tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384, // TLS 1.2 fallback (ECDHE-based) tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // ... }}Result: Data encrypted in transit (TLS) and at rest (SSE), with no plaintext exposure at any point.
Server-Side Encryption Modes
Three Modes for Different Trust Models
| Mode | Key Location | Use Case |
|---|---|---|
| SSE-KMS[7] | KMS manages keys | Regulated workloads, per-bucket/object key control |
| SSE-S3[8] | AIStor manages keys | Simplified management, single cluster key |
| SSE-C[9] | Client provides keys | Maximum control, application-managed keys |
SSE-KMS (Recommended for Enterprise)
┌─────────────────────────────────────────────────────────────────┐│ SSE-KMS Flow │├─────────────────────────────────────────────────────────────────┤│ ││ PUT Object with x-amz-server-side-encryption: aws:kms ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Generate unique DEK for object │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ KMS wraps DEK with Customer Master Key (CMK) │ ││ │ CMK never leaves KMS boundary │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Store with object metadata: │ ││ │ • x-amz-server-side-encryption-aws-kms-key-id │ ││ │ • Wrapped DEK (ciphertext) │ ││ │ • Key version │ ││ └─────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘SSE-C (Client-Provided Keys)
The application provides a 256-bit key per request[9]. AIStor uses the key for encryption/decryption but never stores it:
// internal/crypto/sse-c.go:90// Validates client-provided key is exactly 256 bits (32 bytes)if len(clientKey) != 32 { return ErrInvalidCustomerKey}Use case: Maximum security where the application controls all keys.
Key Management: KMS Integration
Supported KMS Providers
AIStor integrates with enterprise KMS infrastructure via KES (Key Encryption Service)[6]:
| Provider | Integration | HSM Support |
|---|---|---|
| AWS KMS | Native via KES | Yes (CloudHSM) |
| HashiCorp Vault | Native via KES | Yes (HSM backend) |
| Azure Key Vault | Native via KES | Yes (HSM-backed) |
| Google Cloud KMS | Native via KES | Yes |
| AIStor MinKMS | Direct integration | Optional HSM |
Key Hierarchy
┌─────────────────────────────────────────────────────────────────┐│ Key Hierarchy │├─────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Customer Master Key (CMK) │ ││ │ Lives in KMS/HSM │ Never leaves │ You control it │ ││ └──────────────────────────┬──────────────────────────────┘ ││ │ wraps ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Data Encryption Key (DEK) - One per object │ ││ │ Wrapped ciphertext stored with object metadata │ ││ │ Plaintext exists only during encrypt/decrypt operation │ ││ └─────────────────────────────────────────────────────────┘ ││ ││ Delete CMK = All related data permanently unreadable ││ │└─────────────────────────────────────────────────────────────────┘Wrapped Key Storage
Keys are stored with object metadata[2], not in a central database:
// internal/crypto/metadata.go:35-54const ( MetaSealedKeySSEC = "X-Minio-Internal-Server-Side-Encryption-Sealed-Key" MetaSealedKeyS3 = "X-Minio-Internal-Server-Side-Encryption-S3-Sealed-Key" MetaSealedKeyKMS = "X-Minio-Internal-Server-Side-Encryption-Kms-Sealed-Key" MetaKeyID = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Key-Id" MetaDataEncryptionKey = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Sealed-Key")Benefits:
- No central key database to attack
- Decryption requires only the object and KMS access
- No coordination overhead
- No single point of failure
AIStor MinKMS: Purpose-Built for Object Scale
The Problem with Traditional KMS
Traditional KMS and HSM products were built for thousands of keys—not billions. When every object has its own encryption key, legacy key management becomes the bottleneck.
MinKMS Architecture
| Capability | Implementation |
|---|---|
| Scale | Billions of keys without degradation |
| Deployment | Separate from object store |
| High availability | Synchronous replication across nodes |
| Read availability | Single node can serve decrypt operations |
| Admin operations | Require all nodes (key creation) |
| Failure tolerance | Cryptographic operations continue during partial failures |
Consensus Model
Read Operations (encrypt, decrypt, derive): → Require only ONE available node → Operations continue during partial cluster failure
Admin Operations (create key, delete key): → Require ALL nodes → Ensures consistency for key lifecycleLive Key Rotation
Zero-Downtime Rotation
Key rotation happens without maintenance windows[10]:
# Batch key rotation job configuration# cmd/batch-rotate.go:37-68keyrotate: flags: filter: newerThan: "7d" olderThan: "365d" tags: - key: "classification" value: "sensitive" metadata: - key: "x-amz-meta-project" value: "analytics" kmskey: "my-old-key-version"How It Works
- Define policy — Rotation by age, tags, metadata, or KMS key ID
- Background processing — AIStor processes matching objects
- Re-wrap DEK — Each object’s DEK wrapped with new CMK version
- Data untouched — Only key envelope changes, payload unchanged
- Backward compatible — Objects with old key versions remain readable
Key Version Tracking
// internal/crypto/metadata.go:46-50const MetaKeyVersion = "X-Minio-Internal-Server-Side-Encryption-Kms-Key-Version"Each object metadata stores which CMK version encrypted it, enabling:
- Audit of encryption key currency
- Policy-based rotation targeting
- Compliance reporting
Multipart Upload Encryption
Per-Part Encryption
Each part of a multipart upload receives its own derived encryption key[11]:
// cmd/object-multipart-handlers.go:540-557partEncryptionKey := objectEncryptionKey.DerivePartKey(uint32(partID))encryptedReader := sio.EncryptReader(partReader, sio.Config{ Key: partEncryptionKey, Nonce: nonce, // Unique per part})
// internal/crypto/key.go:134-143func (key ObjectKey) DerivePartKey(id uint32) (partKey [32]byte) { // HMAC-SHA256 derives unique key from object key + part ID mac := hmac.New(sha256.New, key[:]) binary.LittleEndian.PutUint32(tmp[:], id) mac.Write(tmp[:]) mac.Sum(partKey[:0]) return partKey}Benefits:
- Parallel part encryption
- Independent part validation
- Corrupted parts detected via authentication tags
- No need to re-encrypt entire object for part failure
HSM Integration
Root Key Protection
For organizations with strict compliance requirements, MinKMS integrates with Hardware Security Modules[6]:
Root Key → Sealed inside HSM boundary → Never in software │ └→ Supports FIPS 140-2 validation └→ NIST key management guidelinesSupported HSM paths:
- AWS CloudHSM (via AWS KMS)
- HashiCorp Vault HSM backend
- Azure Key Vault HSM tier
- PKCS#11-compatible HSMs
Comparison: Traditional vs. AIStor Encryption
| Aspect | Traditional Storage Encryption | MinIO AIStor |
|---|---|---|
| Encryption granularity | Whole-drive or volume | Per-object unique keys |
| Key management scale | Thousands of keys | Billions of keys |
| Encryption timing | Staged, post-write | Inline with erasure coding |
| Performance impact | Measurable degradation | Near-zero (SIMD accelerated) |
| Key rotation | Maintenance windows required | Live, zero downtime |
| Compromise blast radius | Entire volume or dataset | Single object |
| Key storage | Central database | With object metadata |
| Staging vulnerability | Plaintext in buffer | No staging buffers |
Audit and Compliance
What Gets Logged
Every KMS operation generates an audit entry:
| Event | Logged Data |
|---|---|
| Key generation | Identity, timestamp, key ID, outcome |
| Encryption | Object, key ID, identity |
| Decryption | Object, key ID, identity, success/failure |
| Key rotation | Objects processed, old/new key versions |
| Failed attempts | Identity, reason, resource |
Compliance Coverage
| Regulation | Requirement | AIStor Capability |
|---|---|---|
| FIPS 140-2 | Validated cryptography | FIPS mode with AES-256-GCM |
| PCI DSS | Encryption of cardholder data | Per-object encryption + audit |
| HIPAA | PHI protection | SSE-KMS + access logging |
| SOC 2 | Encryption controls | Demonstrable key management |
| GDPR | Data protection | Encryption + right to erasure (delete CMK) |
Summary
MinIO AIStor delivers encryption that scales to enterprise requirements:
- Per-object unique keys[5] — Blast radius limited to single object
- Inline encryption[1] — No staging buffers, single atomic operation
- AES-256-GCM with SIMD[3] — Wire-speed encryption without CPU bottleneck
- Multiple SSE modes[7][8][9] — SSE-KMS, SSE-S3, SSE-C for different trust models
- Enterprise KMS integration[6] — AWS, Vault, Azure, GCP, MinKMS
- Live key rotation[10] — No maintenance windows, background processing
- Metadata-based key storage[2] — No central key database vulnerability
- Multipart encryption[11] — Independent part keys for parallel processing
Security that scales is security that gets used. AIStor ensures encryption is built into the data path, not bolted on afterward.
Source Code References
cmd/encryption-v1.go:513-525-newEncryptReader()wraps content withsio.EncryptReaderbefore erasure coding, single atomic operationinternal/crypto/metadata.go:35-54- Metadata constants for storing wrapped keys with objects (MetaSealedKeyKMS,MetaDataEncryptionKey)internal/crypto/fips.go:22-29-DARECiphers()returns AES-256-GCM (DARE v2 protocol) with SIMD acceleration viasiopackageinternal/crypto/fips.go:37-58-TLSCiphers()defines TLS 1.3 ciphers with TLS 1.2 ECDHE fallbackinternal/crypto/key.go:34-55-GenerateKey()creates unique 256-bit DEK per object using HMAC-SHA256internal/kms/conn.go:80-102- KMS types (MinKMS, MinKES, Builtin) andinternal/kms/config.go:129-304for KMS/KES configurationinternal/crypto/sse-kms.go:29-241- SSE-KMS implementation with KMS key context and versioninginternal/crypto/sse-s3.go:28-209- SSE-S3 implementation with cluster-managed keysinternal/crypto/sse-c.go:27-182- SSE-C implementation requiring 256-bit client-provided keyscmd/batch-rotate.go:131-178-BatchJobKeyRotateV1for live key rotation via batch jobscmd/object-multipart-handlers.go:540-557andinternal/crypto/key.go:134-143-DerivePartKey()generates unique key per multipart part