# KMS + secrets: use a key you can audit, never user-data

Source: https://ai.techclick.in/blog_aws_kms_secrets
Markdown: https://ai.techclick.in/blog_aws_kms_secrets.md
Publisher: Techclick Infosec Pvt Ltd

KMS CMK vs AWS-owned. Secrets Manager / SSM. Encrypt S3/EBS with a key you can audit. Never put secrets in user-data.

## The ticket

 Contractor with  ec2:DescribeInstanceAttribute  dumped user-data and got the DB password. The S3 bucket is “encrypted” but the key is AWS-owned — you cannot read a useful key policy or restrict who decrypts.

  Quick interview answer

  AWS owned keys : AWS owns them, used on your behalf, you do not manage or deeply audit them.  AWS managed keys  (e.g.  aws/s3 ,  aws/ebs ): live in your account, AWS sets the key policy, you can see use in CloudTrail.  Customer managed keys  (CMK): you create, you write the key policy, you control rotation/aliases, you can grant  AppEC2Role   kms:Decrypt . Encrypt S3/EBS with a key you can audit.  Secrets Manager  is the rotation-first secret store.  SSM Parameter Store SecureString  is fine for parameters/secrets wrapped with KMS. Never put secrets in EC2 user-data — it is an instance attribute, not a vault.

  Hero · envelope, not notepad

 If describe-instance-attribute can print it, it is not a secret store.
  Lab data · dummy only
 Account  111122223333  · OUs Security / Workloads · hub VPC  10.50.0.0/16  · app VPC  10.51.0.0/16  · SG  sg-web  · NACL  acl-app  · bucket  tc-lab-app-logs  · role  AppEC2Role  · TGW  tgw-lab  · VGW public  203.0.113.60  · on-prem FortiGate WAN  203.0.113.10 . Dummy account ID. Not yours.

## Mental model

   Thing  Who controls the key policy  Use here

  AWS owned  AWS — you do not manage it  Default-ish encryption with no audit story
  AWS managed ( aws/s3 )  AWS in your account  Better than nothing; limited policy control
  Customer managed (CMK)  You  S3  tc-lab-app-logs , EBS, Secrets/SSM
  Secrets Manager / SSM SecureString  Wrapped by KMS + resource policy / IAM  DB password for the app role

  Who can decrypt

- CMK key policy AppEC2Role Secret / EBS / S3 user-data ✕ KMS key policy and IAM must both allow. User-data bypasses neither — it just leaks. https://111122223333.signin.aws.amazon.com/console Training mock · not live AWS console VPC IAM S3 CloudTrail KMS → Customer managed keys ### alias/tc-lab-app Key type Customer managed (not AWS owned) Key policy Allow AppEC2Role kms:Decrypt / GenerateDataKey S3 default encryption SSE-KMS · alias/tc-lab-app · tc-lab-app-logs Secret Secrets Manager / SSM SecureString — not user-data Rotation Enable where the engine supports it (Secrets Manager) Cancel Save Encrypt with a key you can audit. Training mock. ## How to choose Need Store / key Trap Audit who decrypted app data CMK + CloudTrail AWS-owned key with no policy story DB password with rotation Secrets Manager User-data, AMI, or a ticket wiki App config + a few secrets SSM SecureString + CMK Plain SSM String for a password S3 / EBS at rest SSE-KMS with the CMK “Encrypted” checkbox with a key you cannot name ## Runbook #### Side A — key Create alias/tc-lab-app . Key policy: admin + AppEC2Role decrypt/generate. Default-encrypt tc-lab-app-logs and the app EBS volume with that key.

- #### Side B — secret Put the DB password in Secrets Manager (or SSM SecureString). Grant the role secretsmanager:GetSecretValue / ssm:GetParameter plus kms:Decrypt .

- #### Side C — prove Instance retrieves the secret. describe-instance-attribute --attribute userData has no password. CloudTrail shows Decrypt from AppEC2Role , not from a random IAM user.

  aws cli · KMS + secret  aws kms list-aliases --query "Aliases[?AliasName=='alias/tc-lab-app']"

aws s3api get-bucket-encryption --bucket tc-lab-app-logs
# SSEAlgorithm: aws:kms   KMSMasterKeyID: alias/tc-lab-app

aws secretsmanager get-secret-value --secret-id tc-lab/app/db --query Name
# (from AppEC2Role — not from your laptop as root)

aws ec2 describe-instance-attribute --instance-id i-labapp01 --attribute userData
# UserData empty of secrets — that is the proof

## Four failures

### 1 · Secret in user-data

 Readable as an instance attribute. Rotate the secret, then delete it from user-data.

### 2 · CMK without a grant to the role

 S3/EBS/Secrets say AccessDenied on decrypt. Fix the key policy + IAM, do not switch back to plaintext.

### 3 · AWS-owned key called “we encrypt”

 You cannot put a least-privilege key policy on it. Use a CMK when you must audit and restrict.

### 4 · Key in account A, role in account B, no grant

 Cross-account KMS needs key policy for the other account. Silent AccessDenied is usually this.

## How to prove it

  Close only when

 1) Bucket and volume name a CMK. 2) The role can decrypt; random users cannot. 3) User-data has no secret. 4) You can show a CloudTrail Decrypt event for the role.

## Traps

   Symptom  First check

  AccessDenied on GetObject of encrypted object  IAM + key policy, not the bucket ACL
  “Encryption is on” but no alias  AWS owned / managed — say so honestly
  Password in launch template  Same leak as user-data

## Knowledge check

   Judgment items. One best answer. Reasons send you back to the matching section.

       Q1
       Which key type lets you write the key policy and audit use in this account?

           AWS owned
           Customer managed (CMK)
           The NACL
           A public S3 ACL

       Correct:  b . CMK.

       Q2
       Where must the DB password not live?

           Secrets Manager
           SSM SecureString
           EC2 user-data
           A CMK-encrypted parameter

       Correct:  c . User-data is not a vault.

       Q3
       AppEC2Role gets AccessDenied on an SSE-KMS object. Often missing…

           kms:Decrypt on the CMK (key policy + IAM)
           A second IGW
           Root MFA only
           A TGW ASN

       Correct:  a . KMS + IAM both.

       Q4
       AWS-owned key is a weak interview answer for “can you audit decrypt?” because…

           You do not manage that key or its policy
           It always public-reads the bucket
           It disables CloudTrail
           It is a NACL

       Correct:  a . AWS owned.

       Q5
       Secrets Manager vs putting a password in the AMI?

           AMI is fine if the SG is private
           Use Secrets Manager / SSM; AMI snapshots leak forever
           AMI encrypts user-data from IAM
           KMS deletes AMIs

       Correct:  b . Snapshots persist.

       Q6
       Default-encrypt tc-lab-app-logs with…

           SSE-KMS and alias/tc-lab-app
           A public-read ACL
           User-data base64
           Disable BPA

       Correct:  a . CMK on the bucket.

       Check answers
       Reset

  AWS security class series:   Shared + IAM  ·  Org / OU  ·  SG vs NACL  ·  Role not key  ·  KMS + Secrets  ·  VPC endpoint  ·  Trail + GuardDuty  ·  TGW hub  ·  S3 public  ·  Interview

## Sources

- AWS KMS Developer Guide — Overview (AWS owned, AWS managed, customer managed) .

 Related:  AWS session factory  ·  Migration series .

---
Cite this Techclick lesson with the source URL. Do not invent fees, batch dates, or job guarantees.
Browse all lessons: https://ai.techclick.in/blogs
AI index: https://ai.techclick.in/llms.txt
