docs: move SSE-S3 KEK config to security.toml, update all references

Chris Lu committed 2026-04-03 12:04:48 -07:00
1 parent cea0117bbd
commit f38832808f
3 files changed
+49 -37

No files matched your search

+8 -6
@@ -80,18 +80,20 @@ WEED_HTTPS_CLIENT_CA=/path/to/ca.crt
```
### SSE-S3 Encryption Key (KEK)
These map to the `[sse_s3]` section of `security.toml`:
```shell
# Option A: hex-encoded 256-bit key (same format as /etc/s3/sse_kek).
# Drop-in replacement for the filer-stored KEK. If /etc/s3/sse_kek also
# exists, the values must match.
WEED_S3_SSE_KEK=$(openssl rand -hex 32)
# Maps to: sse_s3.kek in security.toml
WEED_SSE_S3_KEK=$(openssl rand -hex 32)
# Option B: any secret string. A 256-bit key is derived via HKDF-SHA256.
# Cannot be used while /etc/s3/sse_kek exists — delete the filer file first.
WEED_S3_SSE_KEY=my-secret-passphrase
# Maps to: sse_s3.key in security.toml
WEED_SSE_S3_KEY=my-secret-passphrase
```
Only one of `WEED_S3_SSE_KEK` and `WEED_S3_SSE_KEY` may be set. See [[Server-Side-Encryption]] for details.
Only one may be set. See [[Server-Side-Encryption]] for details.
For full details, see [[Security Configuration]].
+9 -6
@@ -166,17 +166,20 @@ The endpoint is `http://<s3_server_host>:8333`.
If your S3 clients use server-side encryption (`x-amz-server-side-encryption: AES256`), you **must** configure the Key Encryption Key (KEK) before starting the S3 API server. Without it, SSE-S3 requests will fail.
Set one of these environment variables on every S3 API server (all servers in the cluster must use the same value):
Add to `security.toml` (all S3 API servers in the cluster must use the same value):
```bash
# Option A: hex-encoded 256-bit key (use this to migrate from an existing /etc/s3/sse_kek)
export WEED_S3_SSE_KEK=$(openssl rand -hex 32)
```toml
[sse_s3]
# Option A: hex-encoded 256-bit key (generate with: openssl rand -hex 32)
kek = "a1b2c3d4..."
# Option B: any secret string (simpler, key is derived via HKDF)
export WEED_S3_SSE_KEY=my-secret-passphrase
key = "my-secret-passphrase"
```
Store the value in your secrets manager and inject it at startup. See [[Server-Side-Encryption]] for details and migration instructions.
Or via environment variables: `WEED_SSE_S3_KEK` / `WEED_SSE_S3_KEY`.
Store the value in your secrets manager. See [[Server-Side-Encryption]] for details and migration instructions.
## Set up FUSE mount
+32 -25
@@ -119,52 +119,59 @@ weed s3 -config=s3_kms_config.json
## KEK Configuration
SSE-S3 uses envelope encryption: a Key Encryption Key (KEK) protects per-object Data Encryption Keys (DEKs). You can provide the KEK in two ways:
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: Environment Variable
### Recommended: `security.toml`
Two options — pick one (they cannot both be set):
Add an `[sse_s3]` section to your `security.toml`. Set exactly one of `kek` or `key`:
#### `WEED_S3_SSE_KEK` — hex-encoded, drop-in for existing filer KEK
```toml
[sse_s3]
# 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_SSE_S3_KEK` and `WEED_SSE_S3_KEY`.
#### `sse_s3.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.
```bash
# For new deployments, generate a fresh key:
export WEED_S3_SSE_KEK=$(openssl rand -hex 32)
# For existing deployments, copy the value from the filer:
# weed shell → fs.cat /etc/s3/sse_kek
export WEED_S3_SSE_KEK=<value from filer>
weed s3 -filer=localhost:8888
```toml
[sse_s3]
kek = "a1b2c3d4..." # 64 hex characters
```
#### `WEED_S3_SSE_KEY` — any secret string (HKDF-derived)
#### `sse_s3.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.
```bash
export WEED_S3_SSE_KEY=my-secret-passphrase
weed s3 -filer=localhost:8888
```toml
[sse_s3]
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. Store it in your secrets manager (Vault, AWS Secrets Manager, Kubernetes Secrets, etc.) and inject it at startup.
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 environment variable 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 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**. Any S3 request with `x-amz-server-side-encryption: AES256` will return an error. To enable SSE-S3, set one of the environment variables above.
If the filer file does not exist either, **SSE-S3 is disabled**.
### Migration from Filer KEK to Environment Variable
### Migration from Filer KEK to `security.toml`
1. Read the existing KEK: `weed shell` → `fs.cat /etc/s3/sse_kek`
2. Set the env var with the **exact same value**: `export WEED_S3_SSE_KEK=<value>`
3. Restart all S3 API servers — they will use the env var and verify it matches the filer file
4. Once all servers use the env var, optionally delete `/etc/s3/sse_kek` from the filer
2. Add it to `security.toml`: `[sse_s3]` → `kek = "<value from step 1>"`
3. Restart all S3 API servers — they will use the config and verify it matches the filer file
4. Once all servers use the config, optionally delete `/etc/s3/sse_kek` from the filer
> **Note:** Use `WEED_S3_SSE_KEK` (not `WEED_S3_SSE_KEY`) for migration — it uses the same hex format as the filer file. `WEED_S3_SSE_KEY` derives a different key via HKDF and refuses to start while the filer file exists.
> **Note:** Use `sse_s3.kek` (not `sse_s3.key`) for migration — it uses the same hex format as the filer file. `sse_s3.key` derives a different key via HKDF and refuses to start while the filer file exists.
## Implementation Notes