A team wants to use SSE-C for an Amazon S3 bucket so that AWS never stores their key material. What does S3 keep on its side, what must every request carry, and what breaks operationally?
answer
- the key rides along, every time
- S3 keeps a proof, not the key
- the header forces the protocol
- no key, no object, no recourse
- rotation means rewriting everything
basics
~20 sWith SSE-C you send the key on every request; S3 uses it, discards it, and keeps only a randomly salted HMAC to validate later requests. HTTPS is mandatory, a lost key means a lost object, and clients that cannot send custom headers cannot read it.
solid answer
~50 sSSE-C means server-side encryption with a customer-provided key: the client sends the key in request headers, S3 encrypts or decrypts with it and then throws it away. What S3 persists alongside the object is a randomly salted HMAC of the key — enough to verify that a later request presented the *same* key, not enough to reconstruct it. Consequences follow directly. Every GET, HEAD and COPY must re-supply `x-amz-server-side-encryption-customer-algorithm`, `-customer-key` and `-customer-key-MD5`. S3 rejects SSE-C over plain HTTP, since the key would otherwise cross the wire in cleartext. Lose the key and the object is unrecoverable — AWS cannot help. And any consumer that cannot attach custom headers, such as a browser following a plain download link or a CDN fetching from the origin, simply cannot read the object. Choose it when a contract forbids AWS holding key material, not for convenience.
code
bash · 13 linesaws s3api put-object \
--bucket my-bucket \
--key report.csv \
--body ./report.csv \
--sse-customer-algorithm AES256 \
--sse-customer-key fileb://key.bin
aws s3api get-object \
--bucket my-bucket \
--key report.csv \
--sse-customer-algorithm AES256 \
--sse-customer-key fileb://key.bin \
./report.csvgo deeper
Know that SSE-C means the client supplies the encryption key on every S3 request and that AWS never stores it, so losing the key permanently loses the object.
Explain the mechanics: three customer-key headers on every operation, a randomly salted HMAC stored to validate later requests, and mandatory HTTPS because the key travels in a header.
Weigh it honestly against SSE-KMS — you inherit key distribution, rotation as a full object rewrite, no KMS audit trail, and lockout of any consumer that cannot set headers — and say plainly that it is justified only by an explicit no-AWS-key-custody requirement.
Own the decision of whether that custody requirement is real and what it costs the organisation: a key store that is now more critical than the data, an incompatible distribution path, and the question of whether client-side encryption is the more defensible commitment.
## What SSE-C is Server-side encryption with customer-provided keys. The encryption still happens inside S3 — S3 does the AES work on the way in and out — but the key comes from the caller on each request and is never persisted by AWS. It sits between SSE-KMS (AWS holds and controls the key) and client-side encryption (AWS never sees plaintext at all). ## The three headers, on every request A write and every subsequent read must carry: - `x-amz-server-side-encryption-customer-algorithm` — the algorithm, `AES256` - `x-amz-server-side-encryption-customer-key` — the key itself, base64-encoded - `x-amz-server-side-encryption-customer-key-MD5` — a checksum S3 uses to detect a mangled key in transit A copy is the awkward case, because it touches two objects: the source key is supplied with the parallel `x-amz-copy-source-server-side-encryption-customer-*` headers while the destination key uses the ordinary ones. This is how you rotate an SSE-C key — copy each object onto itself, presenting the old key as the source and the new key as the destination. There is no rotate operation. ## What S3 stores Not the key. S3 keeps a **randomly salted HMAC of the key** with the object, purely so a later request can be checked: present the same key and the HMAC matches and S3 proceeds; present a different key and the request is rejected rather than returning garbage. That stored value cannot be used to recover the key or to decrypt the object. This is the design's whole selling point and the honest answer to "does AWS have my key?" — no, and it kept just enough to tell you when you got it wrong. ## HTTPS is not optional Because the key travels in a request header, S3 **rejects SSE-C requests made over plain HTTP**. This is not a policy you configure; it is enforced by the service. It is also a useful thing to say in an interview, because it shows you have connected the mechanism (key in a header) to the constraint (the header must not be observable). ## What actually breaks 1. **Key distribution becomes your problem.** Every service, job and person that reads the object needs the key. You now run a key-distribution system — which usually means a secrets store, which usually means a KMS-backed one, at which point it is worth asking honestly what SSE-C bought over SSE-KMS. 2. **Key loss is data loss.** There is no recovery path, no support ticket, no AWS-side copy. Treat the key store as more critical than the bucket. 3. **Header-less consumers are locked out.** A plain browser download from a URL cannot attach the three headers, and a CDN fetching from the S3 origin cannot invent them either. Anything whose access path is "hand someone a link" is incompatible with SSE-C. 4. **Rotation is a full rewrite.** Rotating means copying every affected object with old and new key headers — an S3 Batch Operations job at scale, not a configuration change. 5. **You lose the KMS ecosystem.** No CloudTrail record of key use tied to an AWS-managed key, no key policy, no grants, no central rotation. Whatever governance you want around the key, you build. ## What it buys, stated fairly Exactly one thing: AWS holds no usable key material for those objects. If a contract, a regulator, or a customer-managed-key commitment says that in writing, SSE-C satisfies it while leaving the encryption work with S3. If nobody is asking for that, the same at-rest protection with far less operational risk comes from SSE-KMS with a customer-managed key. ## Where it sits against client-side encryption Both keep key material out of AWS's hands. SSE-C still transmits the key to S3 for the duration of the request, so S3 momentarily holds it in memory; client-side encryption never sends it at all, and AWS stores bytes it could not decrypt under any circumstances. If the requirement is genuinely "AWS must never be able to read this", client-side encryption is the stronger and more defensible answer, and the operational burden is roughly the same. SSE-C's niche is narrow: you want S3 to do the crypto, but you must be able to say AWS stores no key.
- How do you rotate an SSE-C key for a million existing objects?By copying every object onto itself, presenting the old key with the `x-amz-copy-source-server-side-encryption-customer-*` headers and the new key with the ordinary customer-key headers. There is no rotate operation and no server-side re-key. At scale that is an S3 Batch Operations copy job, and every object must be covered — a missed object is only discoverable when a read fails.
- Why can't a CDN or a plain browser download link serve an SSE-C object?Because reading the object requires three custom request headers carrying the key, and neither a browser following an ordinary link nor an origin fetch you do not control can attach them. Any distribution model built on handing someone a URL is incompatible with SSE-C; you need a client that constructs the request itself and already holds the key.
- If the requirement is that AWS must never be able to read the data, is SSE-C the right answer?Not quite. SSE-C still transmits the key to S3 for the duration of each request, so S3 holds it transiently and does the decryption. Client-side encryption is the stronger answer: the bytes arriving at S3 are already ciphertext under a key AWS never receives. The operational burden is comparable, so pick client-side when the requirement is stated that strictly.
saying these in an interview costs you the question
- Thinks S3 stores the customer key for later reads
- Believes a presigned link alone can fetch an SSE-C object
- Expects AWS Support to recover a lost SSE-C key
- Assumes there is a server-side key rotation operation
- Treats SSE-C as simply a stricter form of SSE-KMS