Hands-on Lab · 8 of 9

Lab 8: Security, Identity & Governance

Is lab mein tum production security ke saare building blocks khud chala ke dekhoge. Tum KMS se data encrypt karoge (envelope encryption tak), permission boundaries aur IAM Access Analyzer use karoge, IAM Identity Center (SSO) se logon ko login karwaoge, Cognito se app ke users banake ek JWT-protected API chalaoge, WAF se attacks block karoge, AWS Config se compliance check aur remediation karoge, GuardDuty se threats pakdoge, aur Security Hub mein account ka security score dekhoge. Aakhir mein ek optional hissa hai jisme tum Control Tower se landing zone banaoge.

⏱ 5–6 hours
📶 Intermediate
✅ Prereq: Labs 1, 3 complete
💰 Cost: ~$0.20–1 (KMS key, WAF hourly, Config items; GuardDuty/Security Hub free trials). Control Tower part costs extra — read its warning
🏢 Account: Personal for Identity Center + Control Tower · rest either
0 / 0 checks done

0 Setup

Terminal

Terminal mein region aur account ID set karo, lab ka folder banao, aur ek Python virtual environment banake usme boto3 aur cryptography install karo:

export AWS_DEFAULT_REGION=us-east-1
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
mkdir -p ~/deepdive/lab8 && cd ~/deepdive/lab8
python3 -m venv .venv && source .venv/bin/activate && pip install boto3 cryptography

Part C (Identity Center) aur Part H (Control Tower) ke liye AWS Organizations chahiye, isliye yeh dono sirf personal account mein ho sakte hain. Baaki saare parts personal account mein toh chalenge hi; agar Lab 1 ki check script ne sandbox mein ✅ diya ho toh wahan bhi chal sakte hain.

A KMS: keys, encrypt/decrypt, envelope encryption, SSE-KMS, key policy

KMS kya hai

AWS KMS encryption keys ko hardware security modules (HSMs) mein rakhta hai, aur key kabhi bhi KMS se bahar nahi aati. Tum KMS ko data (zyada se zyada 4 KB) ya data keys bhejte ho aur use encrypt ya decrypt karne ko kehte ho, aur har aisa istemaal CloudTrail mein log hota hai. AWS managed keys (jaise aws/s3 aur aws/ssm) muft hoti hain, lekin unki policy tum control nahi kar sakte. Customer managed key ka lagbhag $1 per month lagta hai (din ke hisaab se), aur isme tum apni key policy, rotation, aur key ko disable ya delete karna khud control karte ho. Kisi key ko use karne ke liye dono permissions chahiye: key policy allow kare, aur agar key policy ne account ko adhikaar de rakha hai, toh IAM policy bhi allow kare.

A1
Customer managed key banao aur direct encrypt/decrypt karo

Neeche ki commands ek nayi key aur uska alias alias/deepdive banati hain, ek chhoti text file ko KMS se encrypt karke secret.bin mein likhti hain, use wapas decrypt karti hain, key ki default policy dikhati hain, aur saalana key rotation chalu karti hain:

KEY_ID=$(aws kms create-key --description "DEEPDIVE lab key" \
  --tags TagKey=Project,TagValue=deepdive --query KeyMetadata.KeyId --output text)
aws kms create-alias --alias-name alias/deepdive --target-key-id $KEY_ID

echo "CEO salary: bahut zyada" > plain.txt
aws kms encrypt --key-id alias/deepdive --plaintext fileb://plain.txt \
  --query CiphertextBlob --output text | base64 --decode > secret.bin
xxd secret.bin | head -3            # binary ciphertext — ismein key ID bhi embedded hota hai

aws kms decrypt --ciphertext-blob fileb://secret.bin --query Plaintext --output text | base64 --decode
aws kms get-key-policy --key-id $KEY_ID --policy-name default --output text | python3 -m json.tool
aws kms enable-key-rotation --key-id $KEY_ID
aws kms get-key-rotation-status --key-id $KEY_ID
🖱 Console se bhi ho sakta hai
  1. KMS → Customer managed keys → Create key — type Symmetric, usage Encrypt/decrypt, alias deepdive, key administrators/usage defaults rehne do, Create karo.
  2. Key kholo, Key rotation tab se automatic rotation ON kar sakte ho. Encrypt/decrypt ke liye console mein direct UI nahi hai (CLI/SDK se hi hota hai) — key sirf yahin banti hai.

Default key policy dhyan se padho. Usme "Principal": {"AWS": "arn:aws:iam::<account>:root"} ko kms:* diya gaya hai, jiska matlab hai ki "is account ki IAM policies tay karengi ki key kaun use kar sakta hai". Tumne dekha hoga ki decrypt karte waqt key ID nahi deni padi; iski wajah yeh hai ki symmetric ciphertext ke andar hi key ka reference hota hai. Rotation chalu hone pe har saal naya key material banta hai, lekin purana ciphertext phir bhi decrypt ho jaata hai, kyunki KMS purana material bhi sambhal ke rakhta hai.

Acceptance criteria (verify)
  • Decrypt ne original text wapas de diya.
  • Tumne key policy ka "Enable IAM User Permissions" statement padha aur samjha.
  • Rotation status true dikha raha hai.
A2
Envelope encryption: 5 MB file encrypt karo (KMS 4 KB limit se bada)
Why

KMS seedha sirf 4 KB tak ka data encrypt karta hai, aur har call network pe jaata hai. Isliye S3, EBS aur RDS jaisi services envelope encryption use karti hain. Isme KMS se ek data key li jaati hai, jo do roop mein aati hai: ek plaintext copy aur ek encrypted copy. Plaintext key se data ko apne computer pe hi encrypt kiya jaata hai, phir plaintext key ko memory se hata diya jaata hai, aur encrypted key ko data ke saath hi store kar diya jaata hai. Decrypt karte waqt KMS se sirf data key decrypt karwayi jaati hai, aur baaki kaam locally hota hai.

Neeche ka Python script (jaise envelope.py naam se save karke chalao) 5 MB random data ko isi tareeke se encrypt karke big.enc mein likhta hai, aur phir use padh ke decrypt karta hai aur check karta hai ki data wahi hai:

import os

import boto3
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

kms = boto3.client("kms", region_name="us-east-1")

# --- encrypt ---
data = os.urandom(5 * 1024 * 1024)                              # 5 MB "file"
dk = kms.generate_data_key(KeyId="alias/deepdive", KeySpec="AES_256")
nonce = os.urandom(12)
ciphertext = AESGCM(dk["Plaintext"]).encrypt(nonce, data, None)
encrypted_key = dk["CiphertextBlob"]
del dk                                                          # plaintext key memory se hatao
with open("big.enc", "wb") as f:
    f.write(len(encrypted_key).to_bytes(2, "big") + encrypted_key + nonce + ciphertext)
print("encrypted file:", os.path.getsize("big.enc"), "bytes; KMS calls: 1")

# --- decrypt ---
raw = open("big.enc", "rb").read()
klen = int.from_bytes(raw[:2], "big")
enc_key, nonce, ct = raw[2:2 + klen], raw[2 + klen:14 + klen], raw[14 + klen:]
key = kms.decrypt(CiphertextBlob=enc_key)["Plaintext"]
assert AESGCM(key).decrypt(nonce, ct, None) == data
print("decrypted OK — data matches")
Acceptance criteria (verify)
  • 5 MB ka encrypt aur decrypt sirf 2 KMS calls mein ho gaya (ek generate ke liye aur ek decrypt ke liye).
  • Tum samjha sakte ho ki encrypted data key ko file ke andar hi store karna safe kyun hai (kyunki use kholne ke liye KMS ki permission chahiye).
A3
SSE-KMS bucket: S3 permission hai, KMS permission nahi → AccessDenied
Why

Real incidents mein sabse zyada uljhan paida karne wala error yeh hota hai: "S3 GetObject allowed hai, phir bhi AccessDenied aa raha hai". Iski wajah aksar yeh hoti hai ki object KMS key se encrypted hai aur request karne wale ke paas kms:Decrypt ki permission nahi hai. Is step mein tum yahi problem jaan-boojh ke paida karoge aur theek karoge.

Neeche ki commands pehle ek bucket banati hain jiska default encryption tumhari KMS key hai, usme file upload karti hain aur check karti hain ki woh KMS se encrypt hui. Phir ek test role deepdive-kms-test banaya jaata hai jise sirf S3 read ki permission hai, aur uske liye ek CLI profile kmstest joda jaata hai. Us profile se file padhne pe KMS wala AccessDenied aata hai. Aakhir mein role ko kms:Decrypt dene ke baad wahi command chal jaati hai:

export KMS_BUCKET=deepdive-kms-$ACCOUNT_ID
aws s3 mb s3://$KMS_BUCKET
KEY_ARN=$(aws kms describe-key --key-id alias/deepdive --query KeyMetadata.Arn --output text)
aws s3api put-bucket-encryption --bucket $KMS_BUCKET --server-side-encryption-configuration \
  "{\"Rules\":[{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"aws:kms\",\"KMSMasterKeyID\":\"$KEY_ARN\"},\"BucketKeyEnabled\":true}]}"
aws s3 cp plain.txt s3://$KMS_BUCKET/plain.txt
aws s3api head-object --bucket $KMS_BUCKET --key plain.txt --query '[ServerSideEncryption,SSEKMSKeyId,BucketKeyEnabled]'

# Test role: S3 read haan, KMS nahi
cat > kms-test-trust.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::$ACCOUNT_ID:root"},"Action":"sts:AssumeRole"}]}
EOF
cat > kms-test-s3.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::$KMS_BUCKET/*"}]}
EOF
aws iam create-role --role-name deepdive-kms-test --assume-role-policy-document file://kms-test-trust.json
aws iam put-role-policy --role-name deepdive-kms-test --policy-name s3read --policy-document file://kms-test-s3.json
cat >> ~/.aws/config <<EOF

[profile kmstest]
role_arn = arn:aws:iam::$ACCOUNT_ID:role/deepdive-kms-test
source_profile = default
region = us-east-1
EOF
sleep 10
aws s3 cp s3://$KMS_BUCKET/plain.txt - --profile kmstest
# → AccessDenied ... not authorized to perform: kms:Decrypt  (error mein key ARN bhi hoga)

cat > kms-test-decrypt.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"kms:Decrypt","Resource":"$KEY_ARN"}]}
EOF
aws iam put-role-policy --role-name deepdive-kms-test --policy-name kmsdecrypt --policy-document file://kms-test-decrypt.json
sleep 10
aws s3 cp s3://$KMS_BUCKET/plain.txt - --profile kmstest        # ab chalega

Ab CloudTrail mein Event history kholo, Event source mein kms.amazonaws.com chuno aur Decrypt events dekho; har event batata hai ki kisne, kab aur kaunsi key use ki. Bucket pe Bucket Key chalu hone ki wajah se S3 har object ke liye alag KMS call nahi karta, jisse KMS ka kharcha 99% tak kam ho sakta hai.

Acceptance criteria (verify)
  • head-object ke output mein aws:kms aur tumhari key ka ARN dikha.
  • Bina kms:Decrypt ke AccessDenied aaya, aur policy jodne ke baad file padh li gayi.
  • Tumne CloudTrail mein KMS ka Decrypt event dekha.

B IAM advanced: permission boundaries + Access Analyzer

B1
Permission boundary: AdministratorAccess ke bawajood limited
Why

Company sandboxes aksar yahi tareeka apnaate hain: tumhe roles banane dete hain, lekin sirf ek permission boundary ke saath. Boundary kisi identity ki permissions ki chhat (ceiling) hoti hai. Asli (effective) permission woh hoti hai jo identity policy aur boundary, dono mein allowed ho (aur agar SCP ya session policy hai, toh unme bhi). Isse developers roles bana sakte hain, lekin khud ko admin nahi bana sakte, yaani privilege escalation ruk jaata hai.

Neeche ki commands ek boundary policy banati hain jo sirf S3, CloudWatch aur Logs allow karti hai. Phir deepdive-bounded-admin naam ka role is boundary ke saath banaya jaata hai aur use poora AdministratorAccess diya jaata hai. Uske baad us role ke profile se teen commands chala ke dekho ki kya chalta hai aur kya nahi:

cat > boundary.json <<'EOF'
{"Version":"2012-10-17","Statement":[
  {"Effect":"Allow","Action":["s3:*","cloudwatch:*","logs:*"],"Resource":"*"}
]}
EOF
BOUNDARY=$(aws iam create-policy --policy-name DeepdiveDevBoundary --policy-document file://boundary.json \
  --query Policy.Arn --output text)
aws iam create-role --role-name deepdive-bounded-admin \
  --assume-role-policy-document file://kms-test-trust.json --permissions-boundary $BOUNDARY
aws iam attach-role-policy --role-name deepdive-bounded-admin --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
🖱 Console se bhi ho sakta hai
  1. IAM → Roles → Create role → Custom trust policy — kms-test-trust.json paste karo, permissions mein AdministratorAccess attach karo. Naam se pehle Set permissions boundary (Advanced settings ke neeche) kholo, "Use a permissions boundary" chuno aur DeepdiveDevBoundary select karo, phir Create role.
cat >> ~/.aws/config <<EOF

[profile bounded]
role_arn = arn:aws:iam::$ACCOUNT_ID:role/deepdive-bounded-admin
source_profile = default
region = us-east-1
EOF
sleep 10
aws s3 ls --profile bounded | head -3                      # ✅ boundary mein hai
aws ec2 describe-instances --profile bounded --max-items 1  # ❌ Admin hai phir bhi deny
aws iam list-users --profile bounded                        # ❌

Error message dhyan se padho; usme likha hoga "no permissions boundary allows the ec2:DescribeInstances action". Ab agar sandbox mein aisa error dikhe, toh tum samajh jaaoge ki tumhari permission boundary tumhe rok rahi hai.

Acceptance criteria (verify)
  • S3 wali command chal gayi, jabki EC2 aur IAM wali commands "permissions boundary" wale error ke saath deny hui.
B2
IAM Access Analyzer: bahar ke account ko access kisne diya?
Why

Jab account mein hazaaron buckets, keys aur roles hon, toh yeh pata lagana mushkil hota hai ki kaunsa resource account ke bahar (kisi doosre account ya public ke saath) share ho raha hai. Access Analyzer resource policies ka mathematical analysis karke yahi batata hai. External-access analyzer muft hai.

Neeche ki commands ek analyzer banati hain, ek naya bucket banake uski policy mein ek AWS-owned account ko read access deti hain, ek minute ruk ke phir analyzer ki findings dikhati hain:

aws accessanalyzer create-analyzer --analyzer-name deepdive-analyzer --type ACCOUNT
export SHARE_BUCKET=deepdive-share-$ACCOUNT_ID
aws s3 mb s3://$SHARE_BUCKET
# Ek AWS-owned account (us-east-1 Elastic Load Balancing, ALB logs ke liye use hota hai) ko read dete hain
cat > share-policy.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow",
 "Principal":{"AWS":"arn:aws:iam::127311923021:root"},
 "Action":"s3:GetObject","Resource":"arn:aws:s3:::$SHARE_BUCKET/*"}]}
EOF
aws s3api put-bucket-policy --bucket $SHARE_BUCKET --policy file://share-policy.json
sleep 60
ANALYZER=$(aws accessanalyzer list-analyzers --query "analyzers[?name=='deepdive-analyzer'].arn" --output text)
aws accessanalyzer list-findings --analyzer-arn $ANALYZER \
  --query 'findings[].[resourceType,resource,status,principal]' --output json

Finding mein dikhega ki tumhara bucket account 127311923021 ke saath share ho raha hai. Ab aws s3api delete-bucket-policy --bucket $SHARE_BUCKET chala ke bucket policy hata do; kuch minute mein finding ka status RESOLVED ho jaayega.

Access Analyzer ka ek aur feature hai policy validation, jo policy likhte waqt hi galtiyan pakad leta hai. Neeche wali policy mein jaan-boojh ke ek typo aur ek khatarnak permission rakhi gayi hai:

cat > sloppy.json <<'EOF'
{"Version":"2012-10-17","Statement":[
 {"Effect":"Allow","Action":["s3:GetObjekt","iam:PassRole"],"Resource":"*"}]}
EOF
aws accessanalyzer validate-policy --policy-type IDENTITY_POLICY --policy-document file://sloppy.json \
  --query 'findings[].[findingType,issueCode]' --output table
Acceptance criteria (verify)
  • Access Analyzer ne external access ki finding di, aur policy hatane pe woh resolved ho gayi.
  • validate-policy ne galat spelling wale action ko ERROR ke roop mein, aur * pe iam:PassRole ko SECURITY_WARNING ke roop mein pakda.

C IAM Identity Center (SSO) — human access ka sahi tareeka

Kyun IAM users nahi

Socho 50 engineers hain aur 10 accounts. Kya 500 IAM users aur 500 access keys banaoge? Bilkul nahi. IAM Identity Center mein users aur groups ek hi jagah rehte hain (ya tum company ka Okta, Entra ID ya Google Workspace jod sakte ho). Wahan permission sets (policies ke templates) bante hain, aur assignments kuch is tarah ke hote hain: "group X ko account Y mein permission set Z do". Log ek portal se login karte hain aur har baar unhe temporary credentials milte hain; koi long-term key nahi hoti. Kisi ke naukri chhodne pe sirf ek user disable karna padta hai. Tumhare company sandbox ka login bhi isi tareeke se hota hai.

C1
Enable karo, user + group banao
  1. Yeh step personal account mein karo, jahan Lab 1 ke G1 mein Organization bana tha. IAM Identity Center kholo, Enable dabao, "Enable with AWS Organizations" chuno aur region us-east-1 rakho.
  2. Users → Add user mein username deepdive-dev rakho, email daalo (Gmail ka alias bhi chalega), Generate a one-time password chuno, Add dabao aur one-time password (OTP) copy kar lo.
  3. Groups → Create group mein Developers naam ka group banao aur usme deepdive-dev ko jodo.
  4. Settings → Authentication → MFA mein "Every time they sign in" chuno; agar yeh pehle se default hai toh waise hi rehne do.
Acceptance criteria (verify)
  • User aur group ban gaye, aur tumne AWS access portal ka URL (https://d-xxxx.awsapps.com/start) note kar liya.
C2
Permission set + assignment + portal login
  1. Permission sets → Create mein Predefined chuno, ViewOnlyAccess select karo, session duration 1 hour rakho aur Create karo.
  2. AWS accounts mein apna account select karo, Assign users or groups dabao, Groups mein Developers chuno, permission set ViewOnlyAccess chuno aur Submit karo. Parde ke peeche Identity Center tumhare account mein ek AWSReservedSSO_ViewOnlyAccess_... role bana deta hai, jise tum IAM → Roles mein dekh sakte ho.
  3. Ek private ya incognito window kholo, portal URL pe jao, deepdive-dev aur OTP se login karo, naya password set karo, MFA register karo, phir account aur ViewOnlyAccess chun ke console mein jao.
  4. Console mein ek S3 bucket banane ki koshish karo; yeh deny ho jaayega. Lekin EC2 ki list tum dekh sakte ho.

CLI se bhi SSO login ho sakta hai. Pehli command ek SSO profile set up karti hai (woh portal URL, region us-east-1, account aur ViewOnlyAccess poochhegi). Baaki commands dikhati hain ki tum kaun ho, read kaam chalta hai, aur bucket banana deny hota hai:

aws configure sso --profile idc-dev        # portal URL, region us-east-1, account, ViewOnlyAccess
aws sts get-caller-identity --profile idc-dev   # assumed-role/AWSReservedSSO_ViewOnlyAccess_...
aws s3 ls --profile idc-dev
aws s3 mb s3://deepdive-idc-test-$ACCOUNT_ID --profile idc-dev    # AccessDenied
Acceptance criteria (verify)
  • Tumne portal se MFA ke saath login kiya aur ViewOnly console khula.
  • CLI ke SSO profile se read commands chali, lekin write deny hua.
  • Tumne IAM roles mein AWSReservedSSO_... role dekha.

D Cognito: app users, JWT, protected API

Identity Center vs Cognito

Identity Center tumhare employees ko AWS accounts ka access dene ke liye hai. Cognito user pools tumhari app ke customers ke sign-up aur sign-in ke liye hain (password, MFA, ya Google aur Apple jaise social login). Login hone pe Cognito JWT tokens deta hai (ID token, access token aur refresh token). API Gateway us JWT ko verify karta hai, aur sahi hone pe hi request ko aage jaane deta hai.

D1
User pool, app client, user banao aur token lo

Neeche ki commands ek user pool banati hain jisme email hi username hai, ek app client banati hain jo username-password se login allow karta hai, ek test user asha@example.com banake uska pakka password set karti hain, us user se login karke ID token leti hain, aur aakhir mein token ke beech wale hisse (payload) ko decode karke dikhati hain:

POOL=$(aws cognito-idp create-user-pool --pool-name deepdive-users \
  --policies 'PasswordPolicy={MinimumLength=8,RequireUppercase=true,RequireLowercase=true,RequireNumbers=true,RequireSymbols=false}' \
  --auto-verified-attributes email --username-attributes email \
  --query UserPool.Id --output text); echo $POOL
CLIENT=$(aws cognito-idp create-user-pool-client --user-pool-id $POOL --client-name deepdive-cli \
  --explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_REFRESH_TOKEN_AUTH --no-generate-secret \
  --query UserPoolClient.ClientId --output text); echo $CLIENT
🖱 Console se bhi ho sakta hai
  1. Cognito → User pools → Create user pool — sign-in option Email, password policy customize karo, MFA optional/off (lab ke liye), naam deepdive-users rakho.
  2. Pool ke App integration tab → Create app client — naam deepdive-cli, "Don't generate a client secret" tick karo, auth flows mein ALLOW_USER_PASSWORD_AUTH aur ALLOW_REFRESH_TOKEN_AUTH tick karo.
  3. Pool ke Users tab → Create user se test user bhi console se ban sakta hai (email verified tick karke, permanent password set karke).
aws cognito-idp admin-create-user --user-pool-id $POOL --username asha@example.com \
  --user-attributes Name=email,Value=asha@example.com Name=email_verified,Value=true --message-action SUPPRESS
aws cognito-idp admin-set-user-password --user-pool-id $POOL --username asha@example.com \
  --password 'Deepdive2026x' --permanent

TOKEN=$(aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id $CLIENT \
  --auth-parameters USERNAME=asha@example.com,PASSWORD=Deepdive2026x \
  --query AuthenticationResult.IdToken --output text)

# JWT = header.payload.signature — payload decode karo
echo $TOKEN | cut -d. -f2 | python3 -c "import sys,base64,json; s=sys.stdin.read().strip(); s+='='*(-len(s)%4); print(json.dumps(json.loads(base64.urlsafe_b64decode(s)), indent=1))"

Payload mein iss (issuer, yaani user pool ka URL), aud (app client ka ID), email aur exp (expiry, jo 1 ghante baad ki hoti hai) dikhenge. Token ka teesra hissa, yaani signature, Cognito ki private key se banta hai, isliye agar koi payload mein kuch bhi badlega toh signature ki jaanch fail ho jaayegi.

Acceptance criteria (verify)
  • Tumhe IdToken mila, aur decoded payload mein iss, aud, email aur exp dikhe.
D2
JWT authorizer se API protect karo

Neeche ki commands pehle ek chhota Lambda deepdive-whoami banati hain jo token ke claims mein se email aur sub wapas bhejta hai (isme Lab 5 wala deepdive-lambda-basic role use hota hai). Phir ek HTTP API banaya jaata hai jo seedha is Lambda se juda hai, aur API Gateway ko Lambda chalane ki permission di jaati hai. Uske baad Cognito wala JWT authorizer banake API ke route pe lagaya jaata hai. Aakhir mein teen curl requests se test hota hai: bina token, sahi token, aur chhede gaye token ke saath:

cat > whoami.py <<'EOF'
import json


def lambda_handler(event, context):
    claims = event["requestContext"]["authorizer"]["jwt"]["claims"]
    return {"statusCode": 200, "headers": {"Content-Type": "application/json"},
            "body": json.dumps({"hello": claims.get("email"), "sub": claims.get("sub")})}
EOF
zip -q whoami.zip whoami.py
LAMBDA_ROLE=$(aws iam get-role --role-name deepdive-lambda-basic --query Role.Arn --output text 2>/dev/null)
# Lab 5 E1 wala role nahi hai? Wahan ke pehle 4 commands chala ke bana lo.
aws lambda create-function --function-name deepdive-whoami --runtime python3.13 \
  --handler whoami.lambda_handler --role $LAMBDA_ROLE --zip-file fileb://whoami.zip
aws lambda wait function-active --function-name deepdive-whoami
FN_ARN=$(aws lambda get-function --function-name deepdive-whoami --query Configuration.FunctionArn --output text)

API_ID=$(aws apigatewayv2 create-api --name deepdive-secure-api --protocol-type HTTP \
  --target $FN_ARN --query ApiId --output text)                     # quick create: $default route + stage
aws lambda add-permission --function-name deepdive-whoami --statement-id apigw \
  --action lambda:InvokeFunction --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/*"

AUTH_ID=$(aws apigatewayv2 create-authorizer --api-id $API_ID --name cognito --authorizer-type JWT \
  --identity-source '$request.header.Authorization' \
  --jwt-configuration Audience=$CLIENT,Issuer=https://cognito-idp.us-east-1.amazonaws.com/$POOL \
  --query AuthorizerId --output text)
ROUTE_ID=$(aws apigatewayv2 get-routes --api-id $API_ID --query 'Items[0].RouteId' --output text)
aws apigatewayv2 update-route --api-id $API_ID --route-id $ROUTE_ID \
  --authorization-type JWT --authorizer-id $AUTH_ID

URL=https://$API_ID.execute-api.us-east-1.amazonaws.com
sleep 5
curl -s -w "  [%{http_code}]\n" $URL/                                   # 401 Unauthorized
curl -s -w "  [%{http_code}]\n" -H "Authorization: $TOKEN" $URL/          # 200 + email
curl -s -w "  [%{http_code}]\n" -H "Authorization: ${TOKEN}x" $URL/       # 401 (signature tooti)

Dhyan do ki Lambda ko token khud verify nahi karna pada. API Gateway ne signature, issuer, audience aur expiry check kiye, aur sab sahi hone pe hi Lambda ko claims bheje. Web aur mobile apps ke liye Cognito ka managed login (bana-banaya sign-in page) aur social login bhi yahin se configure kiye jaate hain.

Acceptance criteria (verify)
  • Bina token ke 401 aaya, sahi token ke saath 200 aaya (email ke saath), aur chhede gaye token pe 401 aaya.

E WAF: SQL/XSS, rate limiting, IP blocking

E1
Protect karne ke liye ek REST API (mock) banao
  1. API Gateway mein Create API dabao, REST API ke neeche Build chuno, New API chuno, naam deepdive-rest rakho, endpoint type Regional rakho aur Create karo.
  2. /hello naam ka resource banao, usme GET method banao, integration type Mock chuno aur Create karo.
  3. GET method mein Integration response kholo, default response ko Edit karo, Mapping templates mein application/json jodo, body mein {"message": "hello from mock"} likho aur Save karo.
  4. Deploy API dabao, naya stage prod banao aur Invoke URL copy kar lo.

Ab URL ko variable mein rakho (xxxx ki jagah apna API ID) aur API ko test karo:

REST=https://xxxx.execute-api.us-east-1.amazonaws.com/prod
curl -s $REST/hello

WAF ko ALB, CloudFront, REST API Gateway, AppSync aur Cognito pe lagaya ja sakta hai, lekin HTTP API pe nahi. Isiliye yahan REST API banaya gaya hai.

Acceptance criteria (verify)
  • Jawab mein {"message": "hello from mock"} aaya.
E2
Web ACL: managed rules + rate-based rule
Cost

Web ACL ka lagbhag $5 per month, har rule ka $1 per month (ghante ke hisaab se), aur har 10 lakh requests ka $0.60 lagta hai. 2–3 ghante chalane ka kharcha lagbhag $0.05 hoga. Yeh part khatam hote hi ise delete kar dena.

  1. WAF & Shield mein Web ACLs kholo (naye console mein inhe "protection packs" bhi kaha ja sakta hai) aur Create dabao. Regional resources aur us-east-1 chuno, naam deepdive-waf rakho, aur Add AWS resources mein API Gateway ka deepdive-rest - prod chuno.
  2. Rules mein Add managed rule groups → AWS managed kholo aur Core rule set, Known bad inputs aur SQL database jodo.
  3. Add my own rules mein ek Rate-based rule banao jiska naam deepdive-rate ho, limit 10 aur evaluation window 1 minute ho, jo source IP ke hisaab se gine aur action Block ho.
  4. Default action Allow rakho, CloudWatch metrics aur sampled requests chalu rakho, aur Create karo.

Ab ek normal request, ek XSS attack wali request aur ek SQL injection wali request bhejo. Phir ek minute ruk ke 40 requests jaldi-jaldi bhejo aur dekho ki kitne 200 aur kitne 403 aaye:

curl -s -o /dev/null -w "%{http_code}  normal\n" "$REST/hello"
curl -s -o /dev/null -w "%{http_code}  XSS\n"    "$REST/hello?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E"
curl -s -o /dev/null -w "%{http_code}  SQLi\n"   "$REST/hello?id=1%27%20OR%20%271%27%3D%271"
sleep 60
for i in $(seq 1 40); do curl -s -o /dev/null -w "%{http_code}\n" "$REST/hello"; sleep 0.5; done | sort | uniq -c

Normal request pe 200 aayega, jabki XSS aur SQLi wali requests turant 403 se block hongi. Rate wale loop mein lagbhag 30–60 second baad 403 aane lagenge. Web ACL ke Sampled requests ya Overview mein dekho ki kaunse rule ne kya block kiya.

Acceptance criteria (verify)
  • XSS aur SQLi wali requests 403 se block hui.
  • Rate limit paar hone ke baad 403 aane lage.
  • Tumne sampled requests mein match hone wale rule ka naam dekha.
E3
IP set se apna IP block karo (incident response)
  1. WAF mein IP sets → Create kholo, naam deepdive-blocklist rakho, region us-east-1 chuno aur apna IP <TUMHARA_IP>/32 ke roop mein daalo.
  2. deepdive-waf ke Rules mein Add my own rules → IP set rule chuno, blocklist select karo, action Block rakho aur is rule ko priority mein sabse upar rakho.
  3. curl $REST/hello chalao; ab 403 aayega. Phir rule hata do aur dobara chalao; ab 200 aayega.
Acceptance criteria (verify)
  • IP block rule ne tumhe block kiya, aur rule hatane pe tum unblock ho gaye.

F AWS Config: compliance rules + remediation

F1
Config recorder (sirf 2 resource types — cost control)
  1. AWS Config mein Get started / Set up kholo. Recording strategy mein Specific resource types chuno aur sirf AWS::EC2::SecurityGroup aur AWS::S3::Bucket jodo; recording frequency Continuous rakho.
  2. Data governance mein naya service-linked role banne do, Delivery mein Create a bucket chuno aur Next dabao.
  3. Rules mein restricted-ssh aur s3-bucket-versioning-enabled search karke jodo aur Confirm karo.

Config ka kharcha har configuration item ka lagbhag $0.003 aur har rule evaluation ka lagbhag $0.001 hota hai, isliye is lab mein sirf kuch cents lagenge.

Acceptance criteria (verify)
  • Recorder "Recording" status mein hai, dono rules Active hain, aur kuch minute baad compliance ke results aa gaye.
F2
Galat SG banao → NON_COMPLIANT → remediate

Neeche ki commands default VPC mein deepdive-bad-sg naam ka security group banati hain aur usme poori duniya ke liye SSH (port 22) khol deti hain. 2–5 minute baad aakhri command restricted-ssh rule ke NON_COMPLIANT resources dikhati hai:

VPC_ID=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
BAD_SG=$(aws ec2 create-security-group --group-name deepdive-bad-sg --description "open ssh" \
  --vpc-id $VPC_ID --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id $BAD_SG --protocol tcp --port 22 --cidr 0.0.0.0/0
# 2-5 min:
aws configservice get-compliance-details-by-config-rule --config-rule-name restricted-ssh \
  --compliance-types NON_COMPLIANT --query 'EvaluationResults[].EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId'

Ise theek karne (remediation) ke liye AWS ka bana-banaya SSM Automation runbook chalao. Yeh SG se port 22 wala rule hata deta hai. Phir SG ke rules dekho aur rule ka evaluation dobara chalao:

aws ssm start-automation-execution --document-name AWS-DisableIncomingSSHOnPort22 \
  --parameters SecurityGroupIds=$BAD_SG
aws ec2 describe-security-groups --group-ids $BAD_SG --query 'SecurityGroups[0].IpPermissions'   # []
aws configservice start-config-rules-evaluation --config-rule-names restricted-ssh

Ab Config mein Resources kholo, deepdive-bad-sg chuno aur uski Resource timeline dekho. Usme har configuration change dikhta hai, aur saath mein us change ka CloudTrail event bhi, jisse pata chalta hai ki change kisne kiya. Production mein rule pe automatic remediation lagaya jaata hai (Manage remediation mein yahi runbook aur ek automation role chun ke), taaki agar koi SSH khole, toh woh kuch hi minute mein apne aap band ho jaaye.

Acceptance criteria (verify)
  • Bad SG NON_COMPLIANT dikha, aur runbook ke baad uske rules khaali ho gaye aur woh COMPLIANT ho gaya.
  • Tumne resource timeline mein changes ki history dekhi.
  • Tumne note kiya ki versioning wale rule ne kaunse buckets ko NON_COMPLIANT bataya.

G GuardDuty + Security Hub

G1
GuardDuty: threat detection on karo, findings samjho
Why

GuardDuty CloudTrail, VPC Flow Logs aur DNS logs ko machine learning aur threat intelligence ki madad se lagataar analyse karta hai. Woh aisi baatein pakadta hai jaise "tumhara EC2 kisi crypto-mining pool se baat kar raha hai", "root credentials kisi ajeeb IP se use hue", ya "instance ke credentials AWS ke bahar se use ho rahe hain". Iske liye kuch install nahi karna padta, aur pehle 30 din muft trial hota hai.

Neeche ki commands GuardDuty chalu karti hain, kuch sample (nakli) findings banati hain, unki ginti batati hain, aur pehli paanch findings ki severity, type aur title ki table dikhati hain:

DET=$(aws guardduty create-detector --enable --query DetectorId --output text); echo $DET
aws guardduty create-sample-findings --detector-id $DET
🖱 Console se bhi ho sakta hai
  1. GuardDuty console pehli baar kholne pe seedha Enable GuardDuty button dikhata hai — ek click mein chalu ho jaata hai.
  2. Settings tab mein Sample findings → Generate sample findings se sample findings bhi console se ban jaati hain.
sleep 30
aws guardduty list-findings --detector-id $DET --query 'length(FindingIds)'
IDS=$(aws guardduty list-findings --detector-id $DET --max-results 5 --query FindingIds --output text)
aws guardduty get-findings --detector-id $DET --finding-ids $IDS \
  --query 'Findings[].[Severity,Type,Title]' --output table

Console mein GuardDuty → Findings kholo. Har finding ki severity (Low, Medium, High ya Critical), uske type ka naam (jo ThreatPurpose:ResourceType/ThreatFamily.Variant format mein hota hai), prabhavit resource aur sujhaaya gaya remediation dekho. Jin findings ke aage [SAMPLE] likha hai, woh nakli hain.

Optional real finding: kisi bhi chalte EC2 instance pe Session Manager se dig guarddutyc2activityb.com chalao. Yeh AWS ka documented test domain hai. 15–30 minute mein tumhare instance ID ke saath ek asli Backdoor:EC2/C&CActivity.B!DNS finding aani chahiye.

Acceptance criteria (verify)
  • Sample findings list hui, aur tumne kam se kam ek High severity finding padhi.
  • (Optional) Tumhare instance pe DNS pe aadharit ek asli finding aayi.
G2
Security Hub: poore account ka security score
Why

Security Hub (console mein iska naam "Security Hub CSPM" bhi dikh sakta hai) best-practice standards, jaise AWS Foundational Security Best Practices aur CIS, ke controls ko lagataar check karta hai. Saath hi woh GuardDuty, Config, Access Analyzer aur Inspector ki findings ko ek jagah le aata hai. Iska bhi 30 din ka muft trial hai. Controls check karne ke liye Config recorder chalu hona chahiye, isiliye Part F pehle karwaya gaya.

Neeche ki pehli command Security Hub ko default standards ke saath chalu karti hai, aur doosri dikhati hai ki kaunse standards chalu hue:

aws securityhub enable-security-hub --enable-default-standards
aws securityhub get-enabled-standards --query 'StandardsSubscriptions[].[StandardsArn,StandardsStatus]' --output table

Controls ko evaluate hone mein kuch ghante lagte hain, isliye yeh hissa kal dekhna. Security Hub ke Summary mein security score (percentage mein) dikhega. Controls mein fail hue controls dikhenge, jaise IAM.6 (root ke liye hardware MFA), S3.x aur EC2.x, aur har control ke saath use theek karne ka link hoga. Findings mein GuardDuty ki findings bhi dikhengi (product = GuardDuty).

Acceptance criteria (verify)
  • Default standards chalu ho gaye.
  • (Agle din) Tumne security score aur top 5 fail hue controls note kiye.

H (Optional) Control Tower landing zone

Sirf tab karo jab tum iske liye taiyaar ho

Control Tower ka setup 30–60 minute leta hai aur isme 2 naye email addresses chahiye (Log Archive aur Audit accounts ke liye). Yeh har governed account aur region mein AWS Config aur CloudTrail ke resources banata hai, aur agar chalta rahe toh har mahine kuch dollars ka kharcha hota hai. Ise band (decommission) kiya ja sakta hai, lekin naye bane accounts ko alag se close karna padta hai, aur close hone ke baad woh 90 din tak suspended rehte hain. Yeh sirf personal account mein karo. Conflict se bachne ke liye Part F ka Config recorder pehle delete kar do (cleanup list mein tareeka diya hai).

H1
Landing zone set up karo
  1. Control Tower mein Set up landing zone kholo. Home region us-east-1 rakho, Region deny ko off rakho, aur governed regions mein sirf us-east-1 chuno.
  2. OUs mein Foundational OU ka naam Security aur Additional OU ka naam Sandbox rakho.
  3. Shared accounts (Log Archive aur Audit) ke liye naye email aliases do, jaise you+ctlog@gmail.com aur you+ctaudit@gmail.com.
  4. CloudTrail mein organization-level trail chalu rakho, aur kharcha bachane ke liye KMS encryption off rakho. Review karke Set up landing zone dabao; isme lagbhag 30–60 minute lagenge.
Acceptance criteria (verify)
  • Landing zone ka status Available hai, aur Organizations mein Security aur Sandbox OUs aur 2 naye accounts dikh rahe hain.
H2
Controls + Account Factory
  1. Control library mein "Strongly recommended" filter lagao aur koi control chuno, jaise "Disallow public read access to Amazon S3 buckets" (jo detective control hai) ya koi preventive control. Phir Enable on OU dabake use Sandbox OU pe chalu karo.
  2. Account Factory → Create account mein naam deepdive-sbx rakho, ek email alias do, OU mein Sandbox chuno aur Create karo; isme lagbhag 20 minute lagte hain. Phir IAM Identity Center se is account mein login karke dekho ki guardrails pehle se lage hue hain.
  3. Dashboard pe noncompliant resources aur har OU pe chalu controls dekho.

Decommission: kaam khatam hone pe Control Tower ki Settings/Landing zone mein Decommission landing zone chuno aur wahan diya gaya process follow karo. Uske baad Organizations mein jaake Log Archive, Audit aur deepdive-sbx accounts ko close karo.

Acceptance criteria (verify)
  • Sandbox OU pe ek control chalu hai.
  • Account Factory se ek naya account ban gaya.
  • (Khatam karne pe) Tumne landing zone decommission kiya aur accounts close kiye.

I Break & Fix, Challenge, Explain

Break & Fix 1 — key disable = sab data band

aws kms disable-key --key-id $KEY_ID chala ke key ko disable karo, aur phir admin user se bhi aws s3 cp s3://$KMS_BUCKET/plain.txt - chalao. Tumhe KMSInvalidStateException ya AccessDenied milega. Tum admin ho ya nahi, key ke bina encrypted data kisi kaam ka nahi rehta. Isiliye KMS key ko delete karne se pehle 7–30 din ka waiting period hota hai, taaki galti se data hamesha ke liye na kho jaaye. aws kms enable-key --key-id $KEY_ID se key ko wapas chalu kar do.

Break & Fix 2 — Cognito token expire/audience

create-user-pool-client se other-app naam ka ek doosra app client banao, uske ID se login karke token lo, aur woh token D2 wale API ko bhejo. Tumhe 401 milega, kyunki authorizer ka Audience sirf pehle client ka ID accept karta hai. Isse yeh seekh milti hai ki JWT authorizer sirf yeh nahi dekhta ki user kaun hai, balki yeh bhi dekhta hai ki token kis app ke liye bana tha.

Challenge — no steps given

Teen kaam bina steps dekhe karo. 1. Ek EventBridge rule banao jo 7 ya usse zyada severity wali GuardDuty findings ko SNS se email pe bheje. Pattern mein "source": ["aws.guardduty"] aur "detail": {"severity": [{"numeric": [">=", 7]}]} use karo, aur sample findings dobara bana ke test karo. 2. Config rule restricted-ssh pe automatic remediation configure karo (iske liye ek automation role banana padega), phir bad SG dobara banao aur dekho ki woh kitne minute mein apne aap band hota hai. 3. Lab 3 ke RDS ka ek snapshot copy banao jo tumhari customer-managed KMS key se encrypted ho (copy-db-snapshot --kms-key-id se).

Explain it back (interview practice)
  1. KMS mein key policy aur IAM policy ka aapas mein kya rishta hai? Agar "S3 allowed hai phir bhi AccessDenied" aaye, toh tum kya-kya check karoge?
  2. Envelope encryption kya hai, aur iski zaroorat kyun padti hai?
  3. Permission boundary, SCP aur identity policy mein kya farak hai, aur effective permission kaise nikalti hai?
  4. IAM Identity Center, IAM users aur Cognito mein se kaun kiske liye hai?
  5. JWT ke teen hisse kaunse hain, aur API Gateway ka JWT authorizer kya-kya verify karta hai?
  6. WAF kahan-kahan lagaya ja sakta hai, aur rate-based rule kaise kaam karta hai?
  7. Config aur CloudTrail mein kya farak hai? (Config batata hai "kya badla", CloudTrail batata hai "kisne kiya".)
  8. GuardDuty, Security Hub, Inspector aur Macie ko ek-ek line mein samjhao. (Inspector EC2, ECR aur Lambda mein vulnerabilities scan karta hai, aur Macie S3 mein sensitive data dhoondhta hai.)
🧹 Cleanup — billing se bachne ke liye zaroor karo
  • WAF: web ACL se resource ko disassociate karo, phir web ACL aur IP set delete karo. REST API deepdive-rest bhi delete karo.
  • Cognito/API: aws apigatewayv2 delete-api --api-id $API_ID chalao, Lambda deepdive-whoami delete karo, aur aws cognito-idp delete-user-pool --user-pool-id $POOL chalao.
  • GuardDuty: trial khatam hone se pehle aws guardduty delete-detector --detector-id $DET chalao, warna charge lagne lagega.
  • Security Hub: aws securityhub disable-security-hub chalao.
  • Config: pehle rules delete karo. Phir kram se aws configservice stop-configuration-recorder --configuration-recorder-name default, delete-delivery-channel --delivery-channel-name default aur delete-configuration-recorder --configuration-recorder-name default chalao (recorder ka naam describe-configuration-recorders se confirm kar lena). Uske baad Config ka bucket khaali karke delete karo, aur SG deepdive-bad-sg bhi delete karo.
  • KMS: aws s3 rb s3://$KMS_BUCKET --force se bucket hatao, phir aws kms schedule-key-deletion --key-id $KEY_ID --pending-window-in-days 7 se key ka deletion schedule karo.
  • IAM: roles deepdive-kms-test aur deepdive-bounded-admin se inline aur attached policies hatake unhe delete karo, policy DeepdiveDevBoundary delete karo, aur ~/.aws/config se kmstest, bounded aur idc-dev profiles hata do.
  • Access Analyzer: analyzer ko rakh sakte ho kyunki woh muft hai, lekin bucket deepdive-share-... delete kar do.
  • Identity Center: pehle assignment hatao, phir permission set delete karo, aur phir user aur group delete karo. Identity Center ko khud chalu rehne do, kyunki woh muft hai.
  • Control Tower: agar tumne Part H kiya tha, toh landing zone decommission karo aur teeno accounts close karo (H2 dekho).