Table of Contents
- Server-Side Encryption (SSE)
- Overview
- Encryption Types
- SSE-KMS (Server-Side Encryption with Key Management Service)
- SSE-C (Server-Side Encryption with Customer-Provided Keys)
- SSE-S3 (Server-Managed Keys)
- Quick Start
- Configuration
- Features
- KEK Configuration
- Recommended: security.toml
- s3.sse.kek — hex-encoded, drop-in for existing filer KEK
- s3.sse.key — any secret string (HKDF-derived)
- Legacy: Filer-Stored KEK (backward compatibility only)
- Migration from Filer KEK to security.toml
- Replication and Backup with SSE
- Implementation Notes
Server-Side Encryption (SSE)
If you're using SeaweedFS with the S3 API, you can encrypt objects at rest without changing your apps. We support the same server-side encryption (SSE) options as Amazon S3, so you can pick the one that fits how you already manage keys.
Overview
Use this quick guide to choose the right option:
| Encryption Type | Key Management | Use Case |
|---|---|---|
| SSE-KMS | External KMS providers | Enterprise key management, audit trails |
| SSE-C | Customer-provided | Full customer control, regulatory compliance |
| SSE-S3 | SeaweedFS-managed | Simple server-managed encryption, bucket defaults |
Encryption Types
SSE-KMS (Server-Side Encryption with Key Management Service)
- Pick this if: You already use a KMS and want strong audit trails
- Keys live in: External providers (AWS KMS, Google Cloud KMS, OpenBao/Vault, Azure Key Vault [experimental])
- Why teams like it: Centralized key management, detailed audit logs, per-bucket key assignment, optional Bucket Key optimization
- Configuration: Requires KMS provider setup in the S3 config
- Documentation: SSE-KMS Guide
SSE-C (Server-Side Encryption with Customer-Provided Keys)
- Pick this if: You want to bring your own keys and keep full control
- Keys live in: Your application (sent per request)
- Why teams like it: No key storage on the server; maximum control for compliance-heavy environments
- Configuration: Keys provided via HTTP headers
- Documentation: SSE-C Guide
SSE-S3 (Server-Managed Keys)
- Pick this if: You want simple, fully managed encryption with minimal setup
- Keys live in: SeaweedFS (we handle the key management for you)
- Why teams like it: Works with explicit
x-amz-server-side-encryption: AES256and bucket default encryption; supports multipart uploads and range requests - Configuration: Optional bucket-level default encryption via the standard S3 bucket encryption API
- Key Encryption Key (KEK): The recommended way to provide the KEK is via the
WEED_S3_SSE_KEKorWEED_S3_SSE_KEYenvironment variable. This avoids storing the master key on the filer. See KEK Configuration below.
Quick Start
SSE-KMS (Enterprise)
# Ensure $S3_ENDPOINT is set
export S3_ENDPOINT=http://localhost:8333
# Configure KMS in s3 config file (see KMS Providers Integration guide)
# Then upload with KMS encryption
aws --endpoint-url $S3_ENDPOINT s3 cp file.txt s3://mybucket/file.txt \
--server-side-encryption aws:kms \
--ssekms-key-id test-key-123
SSE-C (Customer Keys)
# Generate customer key
openssl rand 32 > customer-key.bin
# Upload with customer-provided key
aws --endpoint-url $S3_ENDPOINT s3 cp file.txt s3://mybucket/file.txt \
--sse-c AES256 \
--sse-c-key fileb://customer-key.bin
SSE-S3 (Server-Managed)
# Explicit SSE-S3 on upload (or configure bucket default encryption)
aws --endpoint-url $S3_ENDPOINT s3 cp file.txt s3://mybucket/file.txt \
--server-side-encryption AES256
Configuration
Basic Setup
Configure KMS providers and IAM settings in your S3 config file:
{
"identities": [
{
"name": "admin",
"credentials": [{"accessKey": "admin", "secretKey": "password"}],
"actions": ["Admin", "Read", "Write"]
}
],
"kms": {
"default_provider": "openbao",
"providers": {
"openbao": {
"type": "openbao",
"address": "http://localhost:8200",
"token": "root-token",
"transit_path": "transit"
}
}
}
}
Note: The S3 config JSON file contains both KMS encryption settings AND IAM-style access control (user identities, credentials, permissions).
Start S3 API with Encryption Support
# Start with KMS config
weed s3 -config=s3_kms_config.json
Features
Supported Operations:
- All standard S3 operations (PUT, GET, HEAD, COPY, DELETE)
- Multipart uploads with consistent encryption
- Cross-encryption copy operations
- Object metadata preservation
- Range requests for SSE-C, SSE-KMS, and SSE-S3
AWS S3 Compatibility:
- Identical API behavior and headers
- Compatible with all S3 clients and SDKs
- Same error codes and responses
KEK Configuration
SSE-S3 uses envelope encryption: a Key Encryption Key (KEK) protects per-object Data Encryption Keys (DEKs). If no KEK is configured, SSE-S3 is disabled and requests with x-amz-server-side-encryption: AES256 will fail.
Recommended: security.toml
Add an [s3.sse] section to your security.toml. Set exactly one of kek or key:
[s3.sse]
# Option A: hex-encoded 256-bit key (same format as the legacy /etc/s3/sse_kek file).
# Generate with: openssl rand -hex 32
kek = ""
# Option B: any secret string. A 256-bit key is derived via HKDF-SHA256.
# Cannot be used while /etc/s3/sse_kek exists on the filer — delete it first.
key = ""
These can also be set via environment variables: WEED_S3_SSE_KEK and WEED_S3_SSE_KEY.
s3.sse.kek — hex-encoded, drop-in for existing filer KEK
Same format as the filer file /etc/s3/sse_kek. If the filer file also exists, the values must match or the server refuses to start. This is ideal for migrating an existing deployment.
[s3.sse]
kek = "a1b2c3d4..." # 64 hex characters
s3.sse.key — any secret string (HKDF-derived)
A 256-bit key is derived automatically via HKDF-SHA256, so any passphrase works. However, this cannot be used while /etc/s3/sse_kek exists on the filer — you must delete the filer file first to avoid silently orphaning data encrypted with the old KEK.
[s3.sse]
key = "my-secret-passphrase"
The same secret always produces the same derived key, so all S3 API servers in a cluster must use the same value.
Legacy: Filer-Stored KEK (backward compatibility only)
If neither config key is set, SeaweedFS falls back to loading the KEK from /etc/s3/sse_kek on the filer. This supports existing deployments that already have the file.
If the filer file does not exist either, SSE-S3 is disabled.
Migration from Filer KEK to security.toml
- Read the existing KEK:
weed shell→fs.cat /etc/s3/sse_kek - Add it to
security.toml:[s3.sse]→kek = "<value from step 1>" - Restart all S3 API servers — they will use the config and verify it matches the filer file
- Once all servers use the config, optionally delete
/etc/s3/sse_kekfrom the filer
Note: Use
s3.sse.kek(nots3.sse.key) for migration — it uses the same hex format as the filer file.s3.sse.keyderives a different key via HKDF and refuses to start while the filer file exists.
Replication and Backup with SSE
SSE-encrypted objects are handled transparently during replication and backup. The behavior depends on the replication command and destination type:
filer.sync (Filer-to-Filer)
weed filer.sync copies encrypted chunk data and SSE metadata as-is between SeaweedFS clusters. No decryption or re-encryption occurs — the destination filer stores the same ciphertext with the same encryption metadata.
Requirement: Both filers must share the same SSE key configuration:
- SSE-S3: Same KEK (via
WEED_S3_SSE_KEK/WEED_S3_SSE_KEYor the filer's/etc/s3/sse_kek) - SSE-KMS: Same KMS provider with access to the same keys
- SSE-C: Works automatically (encryption metadata is copied with the chunk)
If the destination filer uses different SSE keys, the replicated data will be stored but cannot be decrypted — reads will fail silently with corrupt data.
filer.backup / filer.replicate (To External Storage)
weed filer.backup and weed filer.replicate decrypt SSE-encrypted objects before uploading to external sinks (S3, GCS, Azure, B2, local disk). The destination receives plaintext — the destination storage system's own encryption (e.g., AWS S3 SSE, Azure Storage encryption) should be used if encryption at rest is required.
| SSE Type | Behavior |
|---|---|
| SSE-S3 | Decrypted automatically using the KEK from security.toml or the filer |
| SSE-KMS | Decrypted automatically if KMS is configured in security.toml [kms] section |
| SSE-C | Cannot be decrypted — the customer key is not available in the backup context. These objects are skipped with an error. |
SSE-KMS Configuration for Backup
The S3 API server loads KMS configuration from its config file, but filer.backup and filer.replicate do not load the S3 config. To enable SSE-KMS decryption during backup, add a [kms] section to security.toml or set the equivalent WEED_KMS_* environment variables:
[kms]
default_provider = "openbao"
[kms.providers.openbao]
type = "openbao"
address = "http://localhost:8200"
token = "root-token"
transit_path = "transit"
If no KMS configuration is provided, SSE-KMS encrypted objects will fail to replicate with a "KMS is not configured" error.
Implementation Notes
- SSE-KMS: Supports AWS KMS, Google Cloud KMS, OpenBao/Vault; Azure Key Vault is available behind the
azurekmsbuild tag (experimental) - SSE-C: Full support with security best practices
- SSE-S3: Supported with SeaweedFS-managed keys and bucket default encryption
For hands-on setup guides and examples, see the individual encryption method docs linked above.
Introduction
- Quick Start with weed mini
- Simplest S3 Bucket and User Setup
- Components
- Getting Started
- Production Setup
- A typical step‐by‐step example
- Benchmarks
- FAQ
- Applications
API
Configuration
- Replication
- Store file with a Time To Live
- Failover Master Server
- Erasure coding for warm storage
- EC Bitrot Detection
- Server Startup via Systemd
- Environment Variables
Filer
- Filer Setup
- Directories and Files
- File Operations Quick Reference
- Data Structure for Large Files
- Filer Data Encryption
- Filer Commands and Operations
- Filer JWT Use
- TUS Resumable Uploads
Filer Stores
- Filer Cassandra Setup
- Filer Redis Setup
- Super Large Directories
- Path-Specific Filer Store
- Choosing a Filer Store
- Customize Filer Store
Management
Advanced Filer Configurations
- Migrate to Filer Store
- Add New Filer Store
- Filer Store Replication
- Filer Active Active cross cluster continuous synchronization
- Filer as a Key-Large-Value Store
- Path Specific Configuration
- Filer Change Data Capture
- Filer Operation Serialization
FUSE Mount
- FIO benchmark
- fstab and systemd mount
- POSIX Compliance
- Distributed POSIX Locks
- P2P reading in weed mount
WebDAV
SFTP Server
Cloud Drive
- Cloud Drive Benefits
- Cloud Drive Architecture
- Configure Remote Storage
- Mount Remote Storage
- Cache Remote Storage
- Cloud Drive Quick Setup
- Gateway to Remote Object Storage
AWS S3 API
- Amazon S3 API
- Supported APIs vs Minio
- S3 Lifecycle
- S3 Lifecycle vs Volume TTL
- S3 Conditional Operations
- S3 CORS
- S3 Object Lock and Retention
- S3 Object Versioning
- S3 API Benchmark
- S3 API FAQ
- S3 Bucket Quota
- S3 Rate Limiting
- S3 API Audit log
- S3 Nginx Proxy
- Docker Compose for S3
S3 Table Bucket
- S3 Table Bucket
- S3 Table Bucket Commands
- S3 Tables Security
- SeaweedFS Iceberg Catalog
- Iceberg Table Maintenance
Iceberg Integrations
- Spark Iceberg Integration
- Trino Iceberg Integration
- Dremio Iceberg Integration
- DuckDB Iceberg Integration
- Doris Iceberg Integration
- RisingWave Iceberg Integration
- Lakekeeper Iceberg Integration
S3 Authentication & IAM
- S3 Configuration - Start Here
- S3 Credentials (
-s3.config) - OIDC Integration (
-s3.iam.config) - Kubernetes ServiceAccount Authentication (IRSA-style)
- S3 Policy Variables
- S3 Policy Conditions
- S3 Bucket Policies
- Amazon IAM API
- AWS IAM CLI
- weed shell - Shell IAM Commands
Server-Side Encryption
S3 Client Tools
- AWS CLI with SeaweedFS
- s3cmd with SeaweedFS
- rclone with SeaweedFS
- restic with SeaweedFS
- nodejs with Seaweed S3
Machine Learning
HDFS
- Hadoop Compatible File System
- run Spark on SeaweedFS
- run HBase on SeaweedFS
- run Presto on SeaweedFS
- Hadoop Benchmark
- HDFS via S3 connector
Replication and Backup
- Async Replication to another Filer [Deprecated]
- Async Backup
- Async Filer Metadata Backup
- Async Replication to Cloud [Deprecated]
- Kubernetes Backups and Recovery with K8up
Metadata Change Events
Messaging
- Structured Data Lake with SMQ and SQL
- Seaweed Message Queue
- SQL Queries on Message Queue
- SQL Quick Reference
- PostgreSQL-compatible Server weed db
- Pub-Sub to SMQ to SQL
- Kafka to Kafka Gateway to SMQ to SQL
Use Cases
Operations
- System Metrics
- weed shell
- Data Backup
- Deployment to Kubernetes and Minikube
- Deployment with seaweed-up
Rust Volume Server
Advanced
- Large File Handling
- Optimization
- Optimization for Many Small Buckets
- Volume Management
- Tiered Storage
- Cloud Tier
- Cloud Monitoring
- Load Command Line Options from a file
- SRV Service Discovery
- Volume Files Structure
Security
- Security Overview
- Security Configuration
- Cryptography and FIPS Compliance
- Run Blob Storage on Public Internet