AWS KMS: AWS Managed Key vs Customer Managed Key untuk Enkripsi S3

Saat pertama kali mengaktifkan enkripsi di S3 bucket produksi, pilihan antara AWS Managed Key dan Customer Managed Key (CMK) sering terasa seperti keputusan kecil — sampai tim security audit menanyakan siapa yang mengontrol rotasi kunci, atau sampai tagihan KMS tiba-tiba muncul di billing report. Memahami AWS KMS secara mendalam adalah fondasi untuk membuat keputusan enkripsi yang tepat dan menghindari kejutan operasional.

TL;DR: AWS Managed Key vs Customer Managed Key

Aspek AWS Managed Key Customer Managed Key (CMK)
Kontrol kebijakan kunci Tidak bisa dimodifikasi Penuh — key policy, grants, kondisi IAM
Rotasi kunci Otomatis oleh AWS (setiap 1 tahun) Opsional, bisa diaktifkan manual (setiap 1 tahun)
Cross-account access Tidak didukung Didukung via key policy
Audit granular per kunci Terbatas Penuh via CloudTrail
Biaya per kunci/bulan Gratis $1/bulan per kunci (cek AWS pricing)
Biaya per API call Dikenakan (cek AWS pricing) Dikenakan (cek AWS pricing)
Cocok untuk Workload internal sederhana, compliance dasar Multi-tenant, cross-account, audit ketat

Bagaimana AWS KMS Bekerja dengan S3

AWS KMS tidak menyimpan data terenkripsi. KMS hanya menyimpan dan melindungi kunci enkripsi. S3 menggunakan envelope encryption: setiap objek dienkripsi dengan data key unik, dan data key tersebut dienkripsi oleh KMS key. Ini berarti setiap operasi PUT dan GET pada objek terenkripsi menghasilkan API call ke KMS.

sequenceDiagram participant App as Aplikasi participant S3 as Amazon S3 participant KMS as AWS KMS Note over App,KMS: Operasi PUT (Upload) App->>S3: PutObject (data plaintext) S3->>KMS: GenerateDataKey (key-id) KMS-->>S3: Plaintext data key + Encrypted data key S3->>S3: Enkripsi objek dengan plaintext data key S3->>S3: Simpan objek terenkripsi + encrypted data key S3->>S3: Hapus plaintext data key dari memori S3-->>App: Upload berhasil Note over App,KMS: Operasi GET (Download) App->>S3: GetObject S3->>KMS: Decrypt (encrypted data key) KMS-->>S3: Plaintext data key S3->>S3: Dekripsi objek S3-->>App: Data terdekripsi dikembalikan
  1. PUT Object: Aplikasi mengirim data ke S3. S3 meminta data key baru dari KMS via GenerateDataKey. KMS mengembalikan plaintext data key dan versi terenkripsinya. S3 mengenkripsi objek dengan plaintext data key, menyimpan objek terenkripsi beserta encrypted data key, lalu menghapus plaintext data key dari memori.
  2. GET Object: S3 mengambil encrypted data key yang tersimpan bersama objek, mengirimkannya ke KMS via Decrypt. KMS mengembalikan plaintext data key. S3 mendekripsi objek dan mengembalikan data plaintext ke aplikasi.
  3. Setiap operasi ini tercatat di CloudTrail — inilah sumber audit trail yang paling berharga untuk enkripsi berbasis KMS.

Anatomi AWS KMS Key: Apa yang Sebenarnya Dikontrol

Sebelum memilih tipe kunci, penting memahami layer kontrol yang ada. KMS key memiliki tiga mekanisme otorisasi yang bekerja bersama: key policy, IAM policy, dan grants. Ketiganya bukan alternatif — mereka berlapis.

graph TD A["Permintaan Akses KMS Key"] --> B{"Izin di Key Policy?" } B -- Tidak --> C["DITOLAK"] B -- Ya --> D{"Izin di IAM Policy?"} D -- Tidak --> E["DITOLAK"] D -- Ya --> F{"Ada Grant yang relevan?"} F -- Tidak diperlukan --> G["DIIZINKAN"] F -- Diperlukan & Ada --> G F -- Diperlukan & Tidak Ada --> E
  1. Key Policy adalah dokumen resource-based policy yang melekat langsung pada KMS key. Tidak seperti IAM policy biasa, key policy adalah syarat wajib — tanpa izin eksplisit di key policy, bahkan IAM policy yang mengizinkan pun tidak cukup untuk menggunakan kunci tersebut.
  2. IAM Policy bekerja sebagai lapisan kedua. Principal harus diizinkan di key policy terlebih dahulu, baru IAM policy berlaku.
  3. Grants memungkinkan delegasi akses sementara ke principal lain tanpa mengubah key policy. Berguna untuk workload seperti AWS services yang membutuhkan akses atas nama pengguna.
Analoginya seperti kunci brankas di bank: key policy adalah siapa yang boleh masuk ke ruang brankas, IAM policy adalah siapa yang boleh membuka brankas tertentu di dalam ruangan itu. Keduanya harus mengizinkan sebelum akses diberikan.

AWS Managed Key: Kapan Cukup, Kapan Tidak

AWS Managed Key dibuat otomatis saat kamu mengaktifkan enkripsi di layanan AWS seperti S3 dengan opsi SSE-KMS tanpa menentukan kunci sendiri. Format alias-nya adalah aws/s3 untuk S3, aws/ebs untuk EBS, dan seterusnya.

Yang sering tidak disadari: kamu tidak bisa melihat atau memodifikasi key policy dari AWS Managed Key. AWS mengontrol sepenuhnya siapa yang bisa menggunakan kunci ini — dan jawabannya adalah: principal mana pun di account yang sama yang memiliki izin IAM yang sesuai. Ini berarti tidak ada mekanisme untuk membatasi akses ke kunci ini per-tim atau per-aplikasi menggunakan key policy.

AWS Managed Key cocok jika:

  • Enkripsi at-rest adalah kebutuhan compliance dasar dan tidak ada persyaratan kontrol granular.
  • Semua akses terjadi dalam satu AWS account.
  • Tidak ada kebutuhan audit trail per-kunci yang terpisah dari audit S3.

AWS Managed Key tidak cukup jika kamu perlu membatasi akses ke data terenkripsi berdasarkan identitas spesifik, berbagi data terenkripsi lintas account, atau memenuhi persyaratan compliance yang mengharuskan kontrol rotasi kunci yang dapat dibuktikan.

Customer Managed Key: Kontrol Penuh, Tanggung Jawab Penuh

CMK memberikan kontrol penuh atas key policy, rotasi, dan siapa yang bisa menggunakan atau mengelola kunci. Ini juga berarti kamu yang bertanggung jawab memastikan kunci tidak terkunci dari semua principal — kondisi yang bisa membuat data tidak dapat diakses secara permanen.

Membuat CMK untuk S3

# Buat symmetric CMK untuk enkripsi S3
aws kms create-key \
  --description "CMK untuk enkripsi S3 bucket produksi" \
  --key-usage ENCRYPT_DECRYPT \
  --origin AWS_KMS \
  --region us-east-1

# Buat alias yang mudah diidentifikasi
aws kms create-alias \
  --alias-name alias/s3-produksi-cmk \
  --target-key-id <key-id-dari-output-sebelumnya> \
  --region us-east-1

Mengaktifkan Rotasi Otomatis pada CMK

# Aktifkan rotasi otomatis tahunan
aws kms enable-key-rotation \
  --key-id alias/s3-produksi-cmk \
  --region us-east-1

# Verifikasi status rotasi
aws kms get-key-rotation-status \
  --key-id alias/s3-produksi-cmk \
  --region us-east-1

Mengonfigurasi S3 Bucket dengan CMK

# Aktifkan default enkripsi pada bucket menggunakan CMK
aws s3api put-bucket-encryption \
  --bucket nama-bucket-produksi \
  --server-side-encryption-configuration '{
    "Rules": [
      {
        "ApplyServerSideEncryptionByDefault": {
          "SSEAlgorithm": "aws:kms",
          "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd"
        },
        "BucketKeyEnabled": true
      }
    ]
  }'

Perhatikan BucketKeyEnabled: true di atas — ini penting dan akan dibahas di bagian biaya.

Key Policy Minimal yang Aman

🔽 Klik untuk melihat contoh key policy CMK
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow S3 Service to use this key",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow application role to use key",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AppRole"
      },
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    }
  ]
}

Statement pertama dengan principal root adalah wajib — ini memastikan IAM policy di level account masih bisa mengontrol kunci. Menghapus statement ini bisa mengakibatkan kunci terkunci permanen.

Memahami Biaya KMS: Di Mana Kejutan Biasanya Terjadi

Biaya KMS terdiri dari dua komponen: biaya per kunci per bulan dan biaya per API request. Harga aktual berubah — selalu verifikasi di halaman resmi AWS KMS Pricing.

Yang sering mengejutkan tim engineering: setiap GET request ke S3 objek yang dienkripsi dengan KMS menghasilkan satu Decrypt API call ke KMS. Untuk bucket dengan jutaan objek yang sering diakses, ini bisa menjadi biaya signifikan.

S3 Bucket Key: Solusi untuk Mengurangi API Call KMS

S3 Bucket Key adalah fitur yang mengurangi jumlah API call ke KMS secara drastis. Ketika diaktifkan, S3 membuat data key sementara di level bucket yang digunakan untuk mengenkripsi objek-objek dalam batch, bukan memanggil KMS untuk setiap objek individual.

graph LR subgraph TanpaBucketKey["Tanpa S3 Bucket Key"] O1["Objek 1"] --> K1["KMS: GenerateDataKey"] O2["Objek 2"] --> K2["KMS: GenerateDataKey"] O3["Objek 3"] --> K3["KMS: GenerateDataKey"] end subgraph DenganBucketKey["Dengan S3 Bucket Key"] BK["Bucket-level
Data Key"] --> O4["Objek 1"] BK --> O5["Objek 2"] BK --> O6["Objek 3"] KMS2["KMS: 1x GenerateDataKey"] --> BK end
  1. Tanpa Bucket Key: Setiap PUT objek = 1 GenerateDataKey call ke KMS. Untuk 1 juta upload, ada 1 juta API call KMS.
  2. Dengan Bucket Key: S3 menggunakan bucket-level data key untuk periode tertentu. Jumlah API call ke KMS berkurang secara signifikan — AWS mengklaim pengurangan hingga 99% dalam beberapa skenario.
  3. Bucket Key kompatibel dengan CMK maupun AWS Managed Key, dan bisa diaktifkan per-bucket atau per-objek.

Aktifkan Bucket Key adalah langkah pertama yang harus dilakukan sebelum menganalisis biaya KMS lebih lanjut.

Memverifikasi Status Bucket Key

# Cek konfigurasi enkripsi bucket termasuk status Bucket Key
aws s3api get-bucket-encryption \
  --bucket nama-bucket-produksi \
  --region us-east-1

Memantau Penggunaan KMS via CloudTrail

Tidak ada metrik CloudWatch bawaan yang menampilkan total jumlah request per KMS key secara langsung. Untuk menganalisis volume API call per kunci, kamu perlu menganalisis log CloudTrail menggunakan Amazon Athena atau CloudWatch Logs Insights.

Berikut contoh query CloudWatch Logs Insights untuk menganalisis KMS API call dari CloudTrail log group:

# Query CloudWatch Logs Insights untuk menganalisis KMS API calls
# Jalankan di CloudWatch Logs Insights console, arahkan ke log group CloudTrail
filter eventSource = 'kms.amazonaws.com'
| filter eventName in ['GenerateDataKey', 'Decrypt']
| stats count(*) as total_calls by eventName, requestParameters.keyId
| sort total_calls desc
| limit 20

Untuk analisis historis yang lebih dalam atau query ad-hoc terhadap data CloudTrail di S3, gunakan Amazon Athena dengan tabel yang dikonfigurasi di atas bucket CloudTrail. Pendekatan ini memberikan visibilitas penuh terhadap pola penggunaan per kunci tanpa bergantung pada metrik agregat.

Pengalaman Nyata: Salah Diagnosis Biaya KMS yang Melonjak

Situasi ini cukup umum: biaya KMS tiba-tiba naik 10x dalam satu bulan. Asumsi pertama biasanya adalah ada kunci baru yang dibuat tanpa sepengetahuan tim, atau ada serangan brute force yang memicu banyak API call gagal.

Setelah menganalisis CloudTrail, ternyata penyebabnya berbeda: sebuah Lambda function yang baru di-deploy melakukan GetObject pada ribuan objek S3 kecil dalam loop — setiap objek menghasilkan satu Decrypt call KMS. Fungsi ini berjalan setiap menit via EventBridge. Tidak ada yang salah secara teknis, tapi pola akses ini tidak diantisipasi saat merancang arsitektur.

Perbaikannya dua langkah: pertama, aktifkan S3 Bucket Key yang belum diaktifkan di bucket tersebut. Kedua, refactor Lambda untuk menggunakan S3 Select atau batch processing daripada mengambil objek satu per satu. Biaya KMS turun ke level normal dalam 24 jam.

Insight penting: lonjakan biaya KMS hampir selalu merupakan sinyal pola akses yang tidak efisien, bukan masalah konfigurasi kunci itu sendiri.

Memilih Tipe Kunci: Decision Guide

graph TD Start(["Perlu enkripsi S3?"]) --> Q1{"Akses lintas
AWS account?"} Q1 -- Ya --> CMK["Gunakan CMK"] Q1 -- Tidak --> Q2{"Perlu kontrol
key policy granular?"} Q2 -- Ya --> CMK Q2 -- Tidak --> Q3{"Audit trail
per kunci wajib?"} Q3 -- Ya --> CMK Q3 -- Tidak --> Q4{"Compliance mensyaratkan
kontrol rotasi kunci?"} Q4 -- Ya --> CMK Q4 -- Tidak --> AMK["AWS Managed Key
sudah cukup"] CMK --> BK["Aktifkan S3 Bucket Key"] AMK --> BK

Verifikasi dan Audit CMK

Melihat Detail Kunci dan Status

# Lihat metadata lengkap CMK
aws kms describe-key \
  --key-id alias/s3-produksi-cmk \
  --region us-east-1

# List semua CMK di region
aws kms list-keys \
  --region us-east-1

# Lihat key policy yang aktif
aws kms get-key-policy \
  --key-id alias/s3-produksi-cmk \
  --policy-name default \
  --region us-east-1

IAM Policy untuk Aplikasi yang Mengakses S3 dengan CMK

🔽 Klik untuk melihat contoh IAM policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3Operations",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::nama-bucket-produksi/*"
    },
    {
      "Sid": "AllowKMSForS3",
      "Effect": "Allow",
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt",
        "kms:DescribeKey"
      ],
      "Resource": "arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd"
    }
  ]
}

Perhatikan bahwa izin KMS di IAM policy harus dikombinasikan dengan izin yang sesuai di key policy CMK. Salah satu saja tidak cukup.

Wrap-Up: Memahami AWS KMS untuk Keputusan Enkripsi yang Tepat

Untuk sebagian besar workload internal dengan satu AWS account, AWS Managed Key sudah memadai dan tidak memerlukan biaya tambahan per kunci. Pilih Customer Managed Key ketika kamu membutuhkan kontrol granular atas key policy, akses lintas account, atau audit trail yang dapat dibuktikan per kunci.

Apapun pilihan kuncinya, aktifkan S3 Bucket Key untuk mengurangi biaya API call KMS secara signifikan. Pantau pola penggunaan KMS melalui CloudTrail menggunakan Athena atau CloudWatch Logs Insights — bukan untuk mendeteksi ancaman, tapi untuk memahami pola akses yang menghasilkan biaya.

Langkah selanjutnya:

Glosarium

Istilah Penjelasan
Envelope Encryption Teknik enkripsi di mana data key yang mengenkripsi data juga dienkripsi oleh master key. Memungkinkan enkripsi data besar tanpa mengirim data ke KMS.
CMK (Customer Managed Key) KMS key yang dibuat, dimiliki, dan dikelola oleh pengguna AWS. Memberikan kontrol penuh atas key policy dan rotasi.
Key Policy Resource-based policy yang melekat pada KMS key. Merupakan syarat wajib untuk mengotorisasi penggunaan kunci — IAM policy saja tidak cukup.
S3 Bucket Key Fitur S3 yang mengurangi jumlah API call ke KMS dengan menggunakan data key sementara di level bucket, bukan memanggil KMS per objek.
Data Key Kunci simetris yang digunakan langsung untuk mengenkripsi data. Dibuat oleh KMS via GenerateDataKey, dienkripsi oleh KMS key, dan disimpan bersama data terenkripsi.

Related Posts

Komentar

Postingan populer dari blog ini

EC2 Tidak Bisa Akses Internet di Custom VPC: Cara Pasang Internet Gateway dan Update Route Table