Files
rustfs/docs/kms/sse-integration.md
guojidan 9ddf6a011d feature: support kms && encryt (#573)
* feat(kms): implement key management service with local and vault backends

Signed-off-by: junxiang Mu <1948535941@qq.com>

* feat(kms): enhance security with zeroize for sensitive data and improve key management

Signed-off-by: junxiang Mu <1948535941@qq.com>

* remove Hashi word

Signed-off-by: junxiang Mu <1948535941@qq.com>

* refactor: remove unused request structs from kms handlers

Signed-off-by: junxiang Mu <1948535941@qq.com>

---------

Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-09-22 17:53:05 +08:00

3.9 KiB

Server-Side Encryption Integration

RustFS implements Amazon S3-compatible server-side encryption semantics. This document outlines how each mode maps to KMS operations and how clients should format requests.

Supported Modes

Mode Request Headers Managed by Notes
SSE-S3 x-amz-server-side-encryption: AES256 RustFS KMS using the configured default key. Simplest option; clients do not manage keys.
SSE-KMS x-amz-server-side-encryption: aws:kms
x-amz-server-side-encryption-aws-kms-key-id: <key-id> (optional)
RustFS KMS + backend (Vault/Local). Specify a key-id to override the default.
SSE-C x-amz-server-side-encryption-customer-algorithm: AES256
x-amz-server-side-encryption-customer-key: <Base64 key>
x-amz-server-side-encryption-customer-key-MD5: <Base64 MD5>
Customer provided RustFS never stores the plaintext key; clients must supply it on every request.

Request Examples

SSE-S3 Upload & Download

# Upload
aws s3api put-object \
  --endpoint-url http://localhost:9000 \
  --bucket demo --key obj.txt --body file.txt \
  --server-side-encryption AES256

# Download
aws s3api get-object \
  --endpoint-url http://localhost:9000 \
  --bucket demo --key obj.txt out.txt

SSE-KMS with Explicit Key ID

aws s3api put-object \
  --endpoint-url http://localhost:9000 \
  --bucket demo --key report.csv --body report.csv \
  --server-side-encryption aws:kms \
  --ssekms-key-id rotation-2024-09

If --ssekms-key-id is omitted, RustFS uses the configured default_key_id.

SSE-C Multipart Upload

SSE-C requires additional care:

  1. Generate a 256-bit key and compute its MD5 digest.
  2. For multipart uploads, every request (initiate, upload-part, complete, GET) must include the SSE-C headers.
  3. Keep part sizes ≥ 5 MiB to avoid falling back to inline storage which complicates key handling.
KEY="01234567890123456789012345678901"
KEY_B64=$(echo -n "$KEY" | base64)
KEY_MD5=$(echo -n "$KEY" | md5 | awk '{print $1}')

aws s3api create-multipart-upload \
  --endpoint-url http://localhost:9000 \
  --bucket demo --key video.mp4 \
  --server-side-encryption-customer-algorithm AES256 \
  --server-side-encryption-customer-key "$KEY_B64" \
  --server-side-encryption-customer-key-MD5 "$KEY_MD5"
# Upload all parts with the same trio of headers

On download, supply the same headers; otherwise the request fails with AccessDenied.

Response Headers

Header SSE-S3 SSE-KMS SSE-C
x-amz-server-side-encryption AES256 aws:kms absent
x-amz-server-side-encryption-aws-kms-key-id default key id Provided key id absent
x-amz-server-side-encryption-customer-algorithm absent absent AES256
x-amz-server-side-encryption-customer-key-MD5 absent absent MD5 of supplied key

Error Scenarios

Scenario Error Resolution
SSE-C key/MD5 mismatch AccessDenied Regenerate the MD5 digest, ensure Base64 encoding is correct.
Missing SSE-C headers on GET InvalidRequest Provide the same sse-c headers used during upload.
Invalid key id for SSE-KMS NotFound Call GET /kms/keys to retrieve the valid IDs or create one via the admin API.
KMS backend offline InternalError Check /kms/status, restart or reconfigure the backend.

Best Practices

  • Always use HTTPS endpoints when supplying SSE-C headers.
  • Log the key-id used for SSE-KMS uploads to simplify forensic analysis.
  • For compliance workloads, disable cache or lower cache TTL via /kms/reconfigure so data keys are short-lived.
  • Test multipart SSE-C flows regularly; the e2e suite (test_comprehensive_kms_full_workflow) covers this scenario.

For the administrative API and configuration specifics, refer to http-api.md and configuration.md.