feat(kms+ecr): real AES-256-GCM layer encryption on KMS repos#732
Merged
vieiralucas merged 1 commit intomainfrom Apr 24, 2026
Merged
feat(kms+ecr): real AES-256-GCM layer encryption on KMS repos#732vieiralucas merged 1 commit intomainfrom
vieiralucas merged 1 commit intomainfrom
Conversation
Previously `EncryptionConfiguration.encryption_type=KMS` with a kms_key ARN was stored but never consulted. Layer blobs sat plaintext on the fakecloud disk regardless. Now they're actually encrypted under AES-256-GCM via a new fakecloud-kms crate-level API, with a fresh 12-byte IV per call and an authenticated tag bound to the key ARN. - New `fakecloud_kms::api` module exposes `encrypt_blob` / `decrypt_blob`. Self-describing envelope format (`|arn_len:u16|arn|iv:12|ct+tag|`) so decrypters don't need the key ARN passed separately. - The AES-256 key is derived via SHA-256 over the KMS key's `private_key_seed` (or `imported_material_bytes` when set via `ImportKeyMaterial`). Each CreateKey populates its own seed, so keys produce distinct ciphertext. - aes-gcm 0.10 added as a fakecloud-kms dep (not workspace-level — it's the only crate that needs the crypto primitives). - fakecloud-ecr gets a new optional `with_kms` builder. When wired, blob uploads (both the OCI v2 single-POST and two-phase paths, plus the AWS SDK `CompleteLayerUpload`) encrypt before storage; blob GETs decrypt on the way out. Pull-through-cached blobs stay plaintext (their repo is auto-created without KMS config). - `Layer` gains `encrypted_with_kms_key: Option<String>` so the decrypt path knows whether to skip. Existing snapshots deserialize with it defaulted to None — pre-encryption layers stay readable. - Server wires `kms_state` into the ECR service at startup so the integration is live by default. - 4 new KMS unit tests (roundtrip, distinct IVs, tamper detection, disabled-key rejection). 2 new ECR E2E tests: KMS repo round-trips the plaintext via blob GET; the default AES256 path keeps storing plaintext as a regression guard.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch 3. Real encryption on KMS-configured ECR repos.
fakecloud_kms::api::encrypt_blob/decrypt_blob— AES-256-GCM, per-call 12-byte IV, authenticated tag bound to key ARN. Self-describing envelope so decrypt doesn't need the key passed back.with_kmsbuilder; wired in server. Both OCI v2 upload paths (single-POST + two-phase) and the SDKCompleteLayerUploadbranch onencryption_type=KMS. Blob GET decrypts.Layergetsencrypted_with_kms_keyso old snapshots stay readable.Test plan
cargo test -p fakecloud-e2e --test ecr --test ecr_oci --test ecr_lifecycle --test ecr_pull_through— no regressionsSummary by cubic
Adds real AES‑256‑GCM encryption for ECR layer blobs when repositories are configured with KMS, and decrypts on blob GET. Existing repositories and snapshots remain readable; non‑KMS repos still store plaintext.
New Features
fakecloud_kms::api::{encrypt_blob, decrypt_blob}using AES‑256‑GCM with per‑call 12‑byte IV and a self‑describing envelope (|arn_len:u16|arn|iv:12|ct+tag|).EcrService::with_kms; encrypts on upload (single‑POST, two‑phase, and SDKCompleteLayerUpload) and decrypts on GET; pull‑through cache stays plaintext.Layer.encrypted_with_kms_keyto track encrypted blobs; defaults toNonefor backward compatibility.Dependencies
aes-gcm@0.10tofakecloud-kms.Written for commit d67c40c. Summary will update on new commits.