Access to CoreWeave AI Object Storage with appropriate permissions
An S3-compatible client or library that supports SSE-C
A method to generate and store encryption keys securely
Understanding of basic S3 operations (upload, download, copy)
If you lose your encryption key, you cannot recover your encrypted data. CoreWeave does not store your encryption keys, and cannot decrypt your data without them. See the Key management section for best practices on storing and managing your encryption keys securely.
CoreWeave AI Object Storage uses your provided key to encrypt or decrypt your data as required, but does not permanently store that key itself. Instead, CoreWeave stores only a base64-encoded MD5 digest of your encryption key.This hash is stored solely for verification, meaning, when you later access the object, you must supply the same key and hash you used originally. CoreWeave checks the hash of the supplied key against the stored hash to verify that the correct key is provided before attempting decryption.
Why only the hash?The hash of the key serves as a checksum: it can verify that the key is correct, but it cannot be used to reconstruct the actual key. By storing only the hash and not the key itself, CoreWeave ensures that only someone who possesses the original encryption key can access the corresponding encrypted data. If you lose your key, neither you nor CoreWeave can recover your data. The hash makes it computationally infeasible to recover the original key due to the one-way nature of cryptographic hashes.
SSE-C requires 256-bit (32-byte) encryption keys. Generate these keys using cryptographically secure methods and encode them in base64 format:
OpenSSL
Python
Shell
# Generate a random 256-bit key and encode in base64openssl rand -base64 32
import secretsimport base64# Generate a random 256-bit key and encode in base64key_bytes = secrets.token_bytes(32)key = base64.b64encode(key_bytes).decode('utf-8')print(key)
# Generate a random 256-bit key using /dev/urandom and encode in base64head -c 32 /dev/urandom | base64# Alternative: Generate key and save to variableBASE64_KEY=$(head -c 32 /dev/urandom | base64)echo $BASE64_KEY
Replace [BUCKET-NAME] with the name of the bucket. Replace [OBJECT-KEY] with the key of the object to download (for example, myfile.txt). Replace [LOCAL-FILE-PATH] with the local path to save the file to (for example, /tmp/downloaded-file.txt).
When copying objects that use SSE-C, specify the encryption parameters for both source and destination:
AWS CLI
Boto3
curl
Replace [SOURCE-BUCKET-NAME] and [SOURCE-OBJECT-KEY] with the source bucket name and object key. Replace [DEST-BUCKET-NAME] and [DEST-OBJECT-KEY] with the destination bucket name and object key.
Replace [SOURCE-BUCKET-NAME] and [SOURCE-OBJECT-KEY] with the source bucket name and object key. Replace [DEST-BUCKET-NAME] and [DEST-OBJECT-KEY] with the destination bucket name and object key.
def validate_encryption_key(key): """Validate that the encryption key meets requirements""" if not isinstance(key, str): raise ValueError("Encryption key must be a string") try: # Decode base64 to check if it's valid key_bytes = base64.b64decode(key) if len(key_bytes) != 32: # 32 bytes = 256 bits raise ValueError("Encryption key must be 32 bytes (256 bits)") except Exception: raise ValueError("Encryption key must be valid base64-encoded 32-byte key") return True
When using SSE-C with presigned URLs, you must include the encryption parameters when generating the URL and when accessing it. The encryption key is required both during URL generation and when the URL is used.
When accessing a presigned URL that was generated with SSE-C, you must include the same encryption headers in the request. Use the presigned URL generated by Boto3 or the AWS CLI, then pass it to curl with the SSE-C headers:
Bucket policies can be configured to enforce SSE-C usage for specific operations. This ensures that objects are always encrypted with customer-provided keys.
To have environment variables like $BUCKET_NAME evaluated within a heredoc, use << EOF (unquoted) instead of << 'EOF' (single-quoted). Single quotes prevent variable expansion.
Apply the policy:
# Apply the policyaws s3api put-bucket-policy --bucket $BUCKET_NAME --policy file://ssec-policy.json
Set environment variables for your CoreWeave credentials:
Alternatively, configure your CoreWeave credentials to work with the AWS CLI.Using a separate profile for CoreWeave AI Object Storage is recommended to avoid conflicts with your other AWS profiles and S3-compatible services; if you do not set up this configuration, you may encounter errors when using AI Object Storage.
Configure CoreWeave credentials
Create a new credentials file and profile in your CoreWeave configuration directory.
You can also enforce SSE-C only for specific object prefixes. For example, the following policy denies uploads to any object under the sensitive/ prefix unless the request uses SSE-C with the AES256 algorithm. This ensures that only objects stored under [BUCKET-NAME]/sensitive/ require customer-provided encryption keys, while other objects in the bucket are not affected by this policy.Replace [BUCKET-NAME] with the name of your bucket.
For enhanced security, you can restrict uploads to specific encryption keys by checking the key hash.Replace [BUCKET-NAME] with the name of your bucket and [KEY-MD5-HASH] with the base64-encoded MD5 hash of the allowed encryption key.
Regularly rotate your SSE-C encryption keys to reduce risk from key compromise. To rotate a key, download objects encrypted with the old key and re-upload them with a new key. Use a secret management system such as HashiCorp Vault, AWS Secrets Manager, or Kubernetes Secrets to track key versions and expiry dates. Establish a rotation schedule that aligns with your organization’s security policies.
Avoid recalculating the base64-encoded MD5 hash of your encryption key for every request. Compute the key hash once and store it in an environment variable or application configuration for reuse across operations. This reduces computational overhead, especially in high-throughput workloads.
Log all SSE-C upload, download, and copy operations to maintain an audit trail. Track which keys are used for which objects, and record key rotation events. Integrate with your existing logging and monitoring infrastructure to detect unauthorized access attempts or missing key errors.
Before using an encryption key in an SSE-C operation, verify that it is valid base64 and decodes to exactly 32 bytes (256 bits). Validating keys upfront prevents cryptic errors during upload or download operations.