Cloud Security Interview Questions and Answers
Beginner Level (Questions 1-8)
1. What is the shared responsibility model in cloud security?
Answer:
The shared responsibility model defines which party (cloud provider vs. customer) is responsible for securing different layers of cloud infrastructure.
Key Concept:
- Cloud providers secure the infrastructure (physical security, hardware, hypervisor)
- Customers secure everything above that (applications, data, identity, access)
Examples:
| Layer | AWS Responsibility | Your Responsibility |
|---|---|---|
| Physical Security | Locks, guards, cameras, CCTV | N/A |
| Hardware | Servers, network equipment | N/A |
| Hypervisor | Virtual machine isolation | N/A |
| Guest OS | N/A | Patches, updates, hardening |
| Applications | N/A | Code, dependencies, config |
| Data | N/A | Encryption, access control, backup |
| Networking | Network infrastructure | Security groups, firewalls |
| Identity | IAM system | User accounts, policies |
Critical Point: Data security is ALWAYS your responsibility. If the cloud provider is breached, your encrypted data is still protected.
2. What is the principle of least privilege?
Answer:
Least privilege means granting users or applications only the minimum permissions necessary to perform their job.
Why It Matters:
- Limits damage if credentials are compromised
- Reduces insider threat risk
- Simplifies compliance audits
- Makes it easier to detect anomalies (if admin gets unusual permissions)
Example - BAD:
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
This grants all permissions on all resources. If this user's credentials leak, an attacker has complete access.
Example - GOOD:
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-app-bucket/*"
}
This grants only read-only access to one specific S3 bucket. Even if credentials leak, damage is limited.
How to Implement:
- Ask: "What actions does this user need?"
- Ask: "What resources do they need to access?"
- Write policy with only those specific actions and resources
- Review quarterly (remove unused permissions)
3. What is the difference between authentication and authorization?
Answer:
| Authentication | Authorization |
|---|---|
| What? Verifying who you are | What? Verifying what you can do |
| Example: Password, MFA | Example: IAM policy |
| Question: "Are you really Alice?" | Question: "Can Alice access S3?" |
| Result: Token/session | Result: Allow/Deny |
Real-World Analogy:
- Authentication: Airport shows your ID to the agent ("Yes, you're really John Smith")
- Authorization: Agent checks your boarding pass ("Yes, John, you can board Flight 123 to NYC")
In Cloud:
1. AUTHENTICATION (sign in)
User provides: username + password + MFA code
System verifies: credentials are correct
System returns: temporary access token
2. AUTHORIZATION (access resource)
User presents: access token + requests S3:GetObject
System checks: does this user's IAM policy allow S3:GetObject?
System returns: Allow/Deny
4. What is multi-factor authentication (MFA) and why is it important?
Answer:
Multi-factor authentication (MFA) requires two or more verification methods before granting access.
Factors:
- Something You Know: Password, PIN
- Something You Have: Phone, hardware key, security token
- Something You Are: Fingerprint, facial recognition
Types of MFA:
| Type | Examples | Security | Convenience |
|---|---|---|---|
| SMS/Email | Text code, email link | ⭐⭐ (vulnerable to sim-swap) | ⭐⭐⭐⭐ |
| Authenticator App | Google Authenticator, Authy | ⭐⭐⭐ (time-based codes) | ⭐⭐⭐ |
| Hardware Key | YubiKey, Titan Key | ⭐⭐⭐⭐⭐ (phishing-proof) | ⭐ |
| Biometric | Face ID, fingerprint | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
Why It Matters:
WITHOUT MFA:
Attacker has password → Full access (COMPROMISED)
WITH MFA:
Attacker has password → Need phone/key too → Can't access
(Unless they also steal your phone, which is much harder)
Best Practices:
- Mandatory for admin users (not optional)
- Mandatory for any privileged access
- Use authenticator app or hardware key (not SMS)
- Backup codes stored safely (if MFA device lost)
5. What is encryption at rest?
Answer:
Encryption at rest means data stored on disks, databases, or storage systems is encrypted and unreadable without the encryption key.
Why It Matters:
| Scenario | Without Encryption | With Encryption |
|---|---|---|
| Hard drive theft | Attacker reads all data | Attacker gets gibberish |
| Decommissioned hardware | Data recoverable | Data unreadable |
| Insider threat | Admin can read data | Admin gets gibberish |
| Backup leak | Data exposed | Data protected |
How It Works:
ORIGINAL DATA: password123
ENCRYPTED: 7$#9@2kL9@$2lK!@#$
DECRYPTED (with key): password123
(key required!)
Implementation:
AWS S3 Bucket:
┌─────────────────────────────────┐
│ Uploaded file: credit_card.pdf │
├─────────────────────────────────┤
│ S3 automatically encrypts │
│ (AES-256 by default) │
├─────────────────────────────────┤
│ Stored as encrypted binary │
│ 7$#9@2kL9@$2lK!@#$... │
└─────────────────────────────────┘
When you download:
├─ You provide key
├─ S3 decrypts data
└─ You get original file
Key Management:
- Provider-Managed: AWS manages encryption keys (simple but provider has access)
- Customer-Managed: You manage keys (complex but maximum control)
6. What is encryption in transit?
Answer:
Encryption in transit means data is encrypted while moving between systems (usually using HTTPS/TLS).
Why It Matters:
| Scenario | Without Encryption | With Encryption |
|---|---|---|
| Public WiFi | Attacker on WiFi reads traffic | Attacker sees gibberish |
| Network interception | Man-in-middle attack possible | Data protected by TLS |
| ISP logging | ISP could log data | ISP sees only encrypted tunnel |
TLS/HTTPS:
DON'T: HTTP (unencrypted)
GET http://bank.com
username: alice
password: mypassword123
(visible in plain text!)
DO: HTTPS (encrypted with TLS)
GET https://bank.com
[All data encrypted]
[Bank identity verified with certificate]
[No one can eavesdrop]
Verification:
# Check TLS version
openssl s_client -connect example.com:443
# Look for: "TLSv1.2" or "TLSv1.3" (good)
# Check certificate
curl -vI https://example.com
# Look for: valid certificate, not expired
Best Practices:
- Always use HTTPS (redirect HTTP to HTTPS)
- Use TLS 1.2 or higher (1.0/1.1 are deprecated)
- Enforce strong ciphers
- Use valid certificates from trusted CAs
7. What are the differences between a public and private key?
Answer:
Public-key cryptography uses two keys: public (shared) and private (secret).
How It Works:
SCENARIO: Alice wants to send Bob a secret message
Step 1: Key Generation
├─ Bob generates: public key + private key
├─ Public key: given to Alice (can be public)
└─ Private key: kept secret by Bob (never shared)
Step 2: Encryption
├─ Alice encrypts message with Bob's PUBLIC key
└─ Encrypted message: [gibberish]
Step 3: Transmission
├─ Alice sends encrypted message
└─ Only Bob's private key can decrypt it
Step 4: Decryption
├─ Bob receives encrypted message
├─ Bob decrypts with his PRIVATE key
└─ Bob reads original message
KEY INSIGHT:
├─ Anything encrypted with PUBLIC key
├─ Can ONLY be decrypted with PRIVATE key
└─ So only Bob can read it
In Cloud Computing:
| Use Case | Key Type | Example |
|---|---|---|
| HTTPS/TLS | Public | Website certificate (public), private key on server |
| SSH Access | Public | Your public key in .ssh/authorized_keys |
| AWS KMS | Public | Customer-managed key (you control) |
| Signing Data | Private | Sign API requests, verify signature |
Important Properties:
- Public Key: Can be shared freely, derived from private key
- Private Key: Never shared, must be protected, loss = data loss
8. What is IAM role assumption and when would you use it?
Answer:
IAM role assumption allows a principal (user, service, or role) to temporarily assume a different role and get temporary credentials.
Why It's Better Than Long-Term Keys:
| Long-Term Keys | Role Assumption |
|---|---|
| Static credentials (never expire) | Temporary credentials (expire in minutes) |
| Hard to rotate | Easy to rotate (just revoke) |
| If leaked, active until manual deletion | If leaked, expires automatically |
| No audit trail of who used key | Full audit trail |
| Can't revoke without replacing | Revoke immediately |
How It Works:
┌─────────────┐
│ Alice │ Wants to perform admin task
│ (IAM User) │
└──────┬──────┘
│
│ "Assume Admin Role"
↓
┌─────────────────────────┐
│ Security Token Service │ Validates:
│ (STS) │ ├─ Is Alice authorized?
│ │ ├─ Role exists?
│ │ └─ Trust relationship?
└──────┬──────────────────┘
│
│ Approved!
↓
┌──────────────────────────┐
│ Temporary Credentials │ Expires in:
│ ├─ AccessKeyId │ ├─ 15 minutes (default)
│ ├─ SecretAccessKey │ ├─ 12 hours (maximum)
│ └─ SessionToken │ └─ Can't extend beyond expiry
└──────────────────────────┘
↓
Alice now has
Admin permissions
(temporarily)
Use Cases:
-
Service-to-Service Communication
Lambda function needs to access S3
├─ Don't embed AWS keys in Lambda code
├─ Instead: Lambda assumes role
├─ Role has S3 permissions
└─ Lambda code: assume role → get credentials → access S3 -
Cross-Account Access
User in Account A needs to work in Account B
├─ Create role in Account B
├─ Set up trust relationship (Account A users)
├─ User in Account A assumes role in Account B
└─ Now has permissions in Account B (temporarily) -
Federated Access
External company employees need access
├─ They login to their Okta/Azure AD
├─ Exchange their token for AWS role
├─ Get temporary AWS credentials
└─ Access AWS resources (limited, temporary)
Intermediate Level (Questions 9-16)
9. How would you implement a secure CI/CD pipeline?
Answer:
A secure CI/CD pipeline ensures code and deployments are secure before reaching production.
Security Layers:
DEVELOPMENT
↓
┌──────────────────────────────┐
│ 1. CODE SCANNING │
│ ├─ Secret scanning │ Prevent secrets in code
│ │ (git-secrets, truffleHog) │
│ ├─ SAST (static analysis) │ Find code vulnerabilities
│ │ (SonarQube, Snyk) │ (SQL injection, XSS, etc.)
│ └─ Dependency scanning │ Check libraries for CVEs
│ (npm audit, pip audit) │
└──────────────────────────────┘
↓
┌──────────────────────────────┐
│ 2. BUILD │
│ ├─ Compile code │
│ ├─ Build Docker image │
│ ├─ Scan image for │ Check for known CVEs
│ │ vulnerabilities │ in base image, libraries
│ │ (Trivy, Snyk) │
│ └─ Sign image │ Image provenance
└──────────────────────────────┘
↓
┌──────────────────────────────┐
│ 3. AUTOMATED TESTING │
│ ├─ Unit tests │
│ ├─ Integration tests │
│ ├─ DAST (dynamic analysis) │ Test running app
│ │ (OWASP ZAP, Burp Suite) │ for vulnerabilities
│ └─ Security tests │ Authentication, authz
└──────────────────────────────┘
↓
┌──────────────────────────────┐
│ 4. DEPLOYMENT │
│ ├─ Use short-lived tokens │ Not long-term keys
│ ├─ Deploy to staging first │
│ ├─ Run tests in staging │
│ ├─ Require approval for prod │
│ └─ Deploy with audit logs │
└──────────────────────────────┘
↓
PRODUCTION
Implementation Example (GitHub Actions):
name: Secure CI/CD Pipeline
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
# 1. Secret Scanning
- uses: actions/checkout@v3
- name: Secret Scanning
run: |
pip install detect-secrets
detect-secrets scan
# 2. SAST
- name: SonarQube Analysis
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# 3. Dependency Scanning
- name: Dependency Check
uses: dependency-check/Dependency-Check_Action@main
# 4. Build Docker Image
- name: Build Docker Image
run: docker build -t myapp:${{ github.sha }} .
# 5. Image Scanning
- name: Scan Image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
# 6. Deploy (with approval)
- name: Deploy to Staging
if: github.ref == 'refs/heads/main'
run: |
# Use OIDC (short-lived token) not long-term key
aws sts assume-role-with-web-identity \
--role-arn ${{ secrets.AWS_ROLE_ARN }} \
--web-identity-token $ACTIONS_ID_TOKEN_REQUEST_TOKEN \
--role-session-name github-actions
Key Practices:
- Never store long-term AWS keys → use OIDC tokens
- Scan for secrets before building
- Scan dependencies for known CVEs
- Scan built images for vulnerabilities
- Require approval before production deployment
- Maintain audit logs of all deployments
10. What is a security group and how do you use it?
Answer:
A security group is a virtual firewall that controls inbound and outbound traffic to cloud resources.
How It Works:
┌──────────────────────────────────────┐
│ EC2 Instance │
│ ├─ Running web application │
│ └─ Assigned Security Group "web-sg" │
└──────────────────────┬───────────────┘
│
│ All traffic DENIED by default
│ Only explicitly allowed traffic passes
↓
┌───────────────────────────┐
│ Security Group Rules │
│ ├─ Allow port 443 from │
│ │ 0.0.0.0/0 (HTTPS) │
│ ├─ Allow port 22 from │
│ │ 10.0.0.0/8 (SSH, internal)
│ └─ Allow port 3306 from │
│ app-sg (MySQL) │
└───────────────────────────┘
Inbound Rules Example:
# Allow HTTPS from anywhere
aws ec2 authorize-security-group-ingress \
--group-id sg-12345 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0
# Allow SSH only from office
aws ec2 authorize-security-group-ingress \
--group-id sg-12345 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.0/32 # Office IP
# Allow app traffic from another security group
aws ec2 authorize-security-group-ingress \
--group-id sg-db \
--protocol tcp \
--port 3306 \
--source-group sg-app
Best Practices:
- Default Deny: Block all traffic by default, allow specific needed traffic
- Use CIDR blocks wisely:
0.0.0.0/0allows everyone (only for public access) - Use security group references:
sg-appcan talk tosg-db(more secure than CIDR) - Separate by tier: web-sg, app-sg, db-sg (not all in one)
- Document purpose: "This rule allows internal APIs to access database"
11. What is cloud access logs and why are they important?
Answer:
Cloud access logs record all actions taken in your cloud account (who, what, when, where).
Why Important:
- Compliance: Required for SOC 2, HIPAA, PCI-DSS, ISO 27001
- Incident Investigation: "Who deleted the database?"
- Forensics: Detect and investigate breaches
- Anomaly Detection: Alert on unusual activity
- Audit Trail: Legal evidence of security
Types of Logs:
| Log Type | What It Records | Example |
|---|---|---|
| API Call Logs | All API calls made | CreateSecurityGroup, GetObject, AssumeRole |
| Network Logs | Network traffic | IP source, destination, protocol, bytes |
| Application Logs | App events | Login attempts, database queries, errors |
| Auth Logs | Authentication attempts | Failed logins, successful logins, MFA attempts |
| Change Logs | Configuration changes | Security group modified, policy attached |
AWS CloudTrail Example:
# Enable CloudTrail logging
aws cloudtrail create-trail \
--name my-trail \
--s3-bucket-name my-logs \
--is-multi-region-trail
# View logs
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=PutBucketPolicy
# Example output:
{
"Time": "2024-01-15T10:30:00Z",
"EventName": "PutBucketPolicy",
"Username": "alice",
"Resources": [{"ARN": "arn:aws:s3:::my-bucket"}],
"EventSource": "s3.amazonaws.com",
"RequestParameters": {"bucketName": "my-bucket"}
}
Using Logs Effectively:
-
Centralize Logs
AWS CloudTrail → S3 → Elasticsearch
Azure Activity Log → Log Analytics
GCP Cloud Audit Logs → BigQuery
→ Single dashboard showing all activity -
Set Alerts
Alert if:
├─ Root account used
├─ Security group modified
├─ IAM policy changed
├─ Multiple failed login attempts
└─ Unusual API calls -
Regular Review
Monthly:
├─ Check for unauthorized access attempts
├─ Review policy changes
├─ Check for misconfigurations
└─ Verify no unusual activity
12. What is a Web Application Firewall (WAF)?
Answer:
A Web Application Firewall (WAF) protects web applications from attacks by filtering and monitoring HTTP/HTTPS traffic.
Common Attacks WAF Protects Against:
| Attack | Example | WAF Rule |
|---|---|---|
| SQL Injection | ' OR '1'='1 | Block requests with SQL keywords in unexpected places |
| Cross-Site Scripting (XSS) | <script>alert('hack')</script> | Block HTML/JS in form inputs |
| Cross-Site Request Forgery | Trick user to click malicious link | Require CSRF tokens |
| DDoS | Flood with requests | Rate limit, block suspicious IPs |
| Bot Attacks | Automated scraping | CAPTCHA, IP reputation |
How WAF Works:
┌─────────────────────────────────────┐
│ Attacker's Request │
│ GET /api/user?id=1' OR '1'='1 │
└──────┬────────────────────────────┬─┘
│ │
└─→ WAF Rules Check ←────────┘
├─ Check for SQL injection patterns
├─ Check for XSS patterns
├─ Check for bot behavior
├─ Rate limit check
└─ Geographic check
┌──────────┐ ┌──────────┐
│ BLOCK │ │ ALLOW │
└──────┬───┘ └────┬─────┘
404 Error Forward to
Returned App Server
Implementation Examples:
# AWS WAF rule (SQL Injection)
aws wafv2 create-web-acl \
--name my-waf \
--region us-east-1 \
--default-action Block={} \
--rules Name=SQLi,Priority=0,Statement='{
ManagedRuleGroupStatement: {
VendorName: "AWS",
Name: "AWSManagedRulesSQLiRuleSet"
}
}'
# Rate limiting rule
{
"Name": "RateLimit",
"Priority": 1,
"Statement": {
"RateBasedStatement": {
"Limit": 2000, # 2000 requests per 5 minutes
"AggregateKeyType": "IP"
}
},
"Action": {"Block": {}},
"VisibilityConfig": {...}
}
Best Practices:
- Block known attack patterns (use managed rules)
- Allow legitimate traffic (whitelist known IPs/patterns)
- Rate limit per IP (prevent brute force, DDoS)
- Monitor alerts (adjust rules based on false positives)
- Regular updates (new attack patterns emerge constantly)
13. How do you secure data in transit across networks?
Answer:
Data in transit must be encrypted to prevent eavesdropping and man-in-the-middle attacks.
Encryption Methods:
| Method | How | When to Use |
|---|---|---|
| HTTPS/TLS | Encrypts HTTP traffic | Web traffic (default) |
| VPN | Encrypted tunnel between networks | Remote workers, site-to-site |
| mTLS | Mutual TLS (both verify each other) | Service-to-service |
| IPsec | Network layer encryption | VPC peering, VPN |
| SSH | Secure shell | CLI administration |
Implementing TLS for HTTPS:
# 1. Create certificate (or get from CA)
openssl req -new -x509 -days 365 \
-nodes -out server.crt -keyout server.key \
-subj "/CN=example.com"
# 2. Configure web server
# Nginx example
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://app;
}
}
# 3. Redirect HTTP to HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
mTLS for Service-to-Service:
Service A Service B
┌──────────────────┐ ┌──────────────────┐
│ Client Cert ✓ │ │ Server Cert ✓ │
│ CA Root Cert ✓ │ │ CA Root Cert ✓ │
└────────┬─────────┘ └────────┬─────────┘
│ │
└─→ Encrypted Connection ←─────┘
├─ Mutual verification
├─ Only authorized services connect
└─ Can't be intercepted
Best Practices:
- Use HTTPS everywhere (not just login pages)
- Use TLS 1.2+ (1.0/1.1 are deprecated)
- Use strong ciphers (disable weak ones)
- Implement certificate pinning (for critical services)
- Automate certificate rotation (90-day expiration)
14. What is a DDoS attack and how do you protect against it?
Answer:
A Distributed Denial of Service (DDoS) attack floods your system with traffic, making it unavailable to legitimate users.
Types of DDoS:
| Type | Attack | Protection |
|---|---|---|
| Layer 3/4 (Network) | Flood with packets | ISP filtering, AWS Shield |
| Layer 7 (Application) | Legitimate-looking requests | WAF, rate limiting |
| Slowloris | Slow requests keeping connection open | Connection limits, timeouts |
Protection Layers:
┌─────────────────────────────────────────────────┐
│ ATTACKER: Sends 1 million requests/second │
└──────┬──────────────────────────────────────────┘
│
└─→ AWS Shield Standard (automatic, free)
├─ Stops obvious Layer 3/4 attacks
└─ Transparent to you
│ Still lots of traffic
↓
└─→ AWS Shield Advanced ($3,000/month)
├─ Advanced DDoS protection
├─ 24/7 DDoS Response Team (DRT)
└─ Automatic mitigation
│ Still legitimate-looking requests
↓
└─→ AWS WAF (Web Application Firewall)
├─ Rate limiting (max 2000 req/IP/5min)
├─ CAPTCHA challenges
├─ IP reputation filtering
└─ Blocks malicious patterns
│ Remaining traffic
↓
└─→ Your Application
├─ Connection pooling
├─ Caching common responses
├─ Auto-scaling for spikes
└─ Graceful degradation
Implementation:
# 1. Enable AWS Shield Standard (automatic)
# No action required, included free
# 2. Enable AWS Shield Advanced
aws shield subscribe --subscription
# 3. Create WAF Rules
aws wafv2 create-web-acl \
--name ddos-protection \
--scope CLOUDFRONT \
--default-action Allow={} \
--rules '[{
"Name": "RateLimit",
"Priority": 0,
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"Action": {"Block": {"CustomResponse": {...}}},
"VisibilityConfig": {...}
}]'
# 4. Connect WAF to CloudFront
aws cloudfront create-distribution \
--distribution-config file://config.json \
--web-acl-id arn:aws:wafv2:...
Best Practices:
- Use CDN (CloudFront, Akamai) to absorb DDoS traffic
- Implement rate limiting per IP
- Use WAF with OWASP rule sets
- Auto-scale infrastructure
- Have incident response plan
15. How do you perform a security audit?
Answer:
A security audit is a systematic review of your cloud security controls, configurations, and practices.
Audit Phases:
PHASE 1: PLANNING
├─ Define scope (what to audit)
├─ Define objectives (what to measure)
├─ Plan timeline
└─ Assign responsibilities
PHASE 2: INFORMATION GATHERING
├─ Document current state
├─ Collect evidence (logs, configs, policies)
├─ Interview team members
└─ Review documentation
PHASE 3: ASSESSMENT
├─ Test controls (attempt unauthorized access)
├─ Check configurations (security groups, IAM)
├─ Analyze logs (suspicious activity)
├─ Verify compliance (vs standards)
└─ Identify gaps
PHASE 4: REPORTING
├─ Document findings
├─ Categorize severity (critical, high, medium, low)
├─ Recommend remediation
└─ Present to management
PHASE 5: FOLLOW-UP
├─ Implement recommendations
├─ Re-test controls
├─ Track remediation status
└─ Schedule next audit
Practical Checklist:
IDENTITY & ACCESS
☐ MFA enabled for all admin users
☐ No unused IAM users
☐ Root account access key disabled
☐ Service accounts use roles (not keys)
☐ Regular access reviews performed
☐ Least privilege enforced
DATA PROTECTION
☐ S3 buckets are private (not public)
☐ Data encrypted at rest (AES-256)
☐ Data encrypted in transit (HTTPS/TLS 1.2+)
☐ Database encryption enabled
☐ Backup encryption enabled
☐ Encryption keys rotated
NETWORK SECURITY
☐ Security groups reviewed
☐ Database in private subnet
☐ NACLs configured
☐ VPC Flow Logs enabled
☐ DDoS protection enabled
MONITORING & LOGGING
☐ CloudTrail/audit logging enabled
☐ All logs stored in secure location
☐ Log retention adequate
☐ Alerts configured for suspicious activity
☐ Regular log review performed
COMPLIANCE
☐ Backup and disaster recovery tested
☐ Incident response plan documented
☐ Security patches applied
☐ Penetration testing performed
☐ Compliance certifications up-to-date
Tools to Help:
# AWS
aws accessanalyzer validate-policy # Validate IAM policies
aws securityhub get-compliance-summary # Compliance status
aws trustedadvisor describe-trusted-advisor-checks # Best practices
# Azure
az security assessment list # Security assessments
# GCP
gcloud iam audit-config get # Audit configuration
gcloud security-scanner run # Security scanning
16. Describe a real security incident and how you'd respond to it.
Answer:
Incident: Unauthorized S3 Access
Scenario:
Monday 10:00 AM:
CEO receives alert from AWS
"S3 bucket with sensitive data is publicly accessible"
Timeline:
9:00 AM - Developer deployed new bucket policy
9:05 AM - Bucket became public by mistake
10:00 AM - AWS security tool detected it
→ Data exposed for ~1 hour
Incident Response (by severity):
SEVERITY: CRITICAL
└─ Exposed: 1000+ customer records (names, emails)
└─ Exposure time: ~1 hour
└─ Public visibility: Unknown
ACTION: IMMEDIATE (0-5 minutes)
├─ Make S3 bucket private
│ aws s3api put-bucket-acl --bucket my-bucket --acl private
├─ Disable object public access
│ aws s3api put-bucket-public-access-block ...
├─ Notify incident response team
│ Page on-call security lead, CTO, CEO
└─ Declare security incident
ACTION: URGENT (5-30 minutes)
├─ Investigate
│ S3 access logs (who accessed what)
│ CloudTrail (what policy changed it)
│ VPC Flow Logs (network access)
├─ Identify:
│ Who made the change? (commit/deployment logs)
│ What data was accessed?
│ How many people accessed it?
├─ Check for:
│ Malicious activity
│ Data exfiltration
│ Signs of compromise
└─ Contact affected customers
"We had a security incident affecting your data"
ACTION: HIGH PRIORITY (30 min - 24 hours)
├─ Root cause analysis
│ Policy template was too permissive
│ No approval process for policy changes
├─ Assessment
│ 100 IP addresses accessed the bucket
│ 10 unique files downloaded
├─ Evidence collection
│ Save all logs
│ Preserve audit trail
└─ Legal/Compliance notification
GDPR: Notify regulators if EU data exposed
HIPAA: Notify HHS if health data exposed
PCI-DSS: Notify payment card companies
ACTION: SHORT TERM (1-7 days)
├─ Implement controls
│ Add bucket policy review step
│ Require approval for policy changes
│ Add monitoring/alerts
├─ Testing
│ Run security tests
│ Verify bucket is truly private
└─ Verify access logs are working
├─ Communication
└─ Public statement if significant exposure
└─ Forensics
└─ Detailed investigation report
ACTION: LONG TERM (1-3 months)
├─ Improve processes
│ Mandatory code review for IAM changes
│ Infrastructure as Code (Terraform)
│ Policy linting before deployment
├─ Training
│ Team training on S3 security
│ Security best practices workshop
├─ Prevention
│ S3 bucket default encryption
│ Block public S3 buckets at account level
│ Real-time alerts on public buckets
└─ Compliance/Audit
└─ Update security documentation
└─ Schedule security audit
└─ Report to board/investors
Key Learnings:
- Speed matters: Public bucket was fixed in minutes
- Prevention is key: Could have been prevented with code review + policy linting
- Process improvement: Add approval workflow for security changes
- Monitoring is critical: Alert fired automatically
- Communication: Notify customers, regulators, team quickly
Advanced Level (Questions 17-25)
17. How do you implement a zero trust security model?
Answer:
Zero trust assumes "never trust, always verify"—every access request is verified regardless of network location.
Traditional Security (Trust the Network):
┌──────────────────────┐
│ "Trusted" Network │
│ Anyone inside can │
│ access anything │
└──────────────────────┘
↓
Firewall blocks external access
↓
Once inside, minimal authorization
Zero Trust (Never Trust):
┌──────────────────────────────────────────────┐
│ EVERY ACCESS REQUEST IS VERIFIED │
├──────────────────────────────────────────────┤
│ 1. Identity: Who are you? │
│ ├─ MFA required │
│ ├─ Device registration required │
│ └─ Continuous verification │
├──────────────────────────────────────────────┤
│ 2. Device: Is your device secure? │
│ ├─ OS up-to-date │
│ ├─ Antivirus running │
│ ├─ Disk encrypted │
│ └─ Not known to be compromised │
├──────────────────────────────────────────────┤
│ 3. Network: Where are you connecting from? │
│ ├─ Approved network/VPN │
│ ├─ Not from Tor/Proxy │
│ └─ Not from high-risk location │
├──────────────────────────────────────────────┤
│ 4. Context: Why do you need this access? │
│ ├─ Justification provided │
│ ├─ Approved by manager │
│ └─ Time-limited (minutes, not years) │
├──────────────────────────────────────────────┤
│ 5. Monitoring: Is this behavior suspicious? │
│ ├─ Normal for this user? │
│ ├─ Normal time of day? │
│ └─ Normal volume of access? │
└──────────────────────────────────────────────┘
↓
GRANT ACCESS (with continuous monitoring)
Implementation Example (Kubernetes):
# Zero Trust RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
# LEAST PRIVILEGE: only specific resources, specific actions
---
# Network Policy (zero trust networking)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# Default: DENY ALL
---
# Allow specific traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
Key Principles:
- Never trust implicitly: Verify every access
- Verify explicitly: Use strong authentication + MFA
- Least privilege: Minimal permissions, temporary access
- Continuous verification: Monitor ongoing access
- Secure every layer: Network, application, data
18. What is a threat model and how do you create one?
Answer:
A threat model is a systematic analysis of potential attacks against your system and how to defend against them.
Threat Modeling Process:
STEP 1: Define System
├─ What is the system?
├─ What are the components?
└─ What are the data flows?
STEP 2: Identify Threats
├─ Who would attack?
├─ What would they target?
├─ How would they attack?
└─ What damage could they cause?
STEP 3: Identify Vulnerabilities
├─ What weaknesses exist?
├─ What could be exploited?
└─ How likely is exploitation?
STEP 4: Mitigate Risks
├─ What controls help?
├─ What's the residual risk?
└─ Is it acceptable?
STEP 5: Document & Review
├─ Document threats and mitigations
├─ Review regularly
└─ Update when system changes
Example: Web Application Threat Model
System Diagram:
┌──────────────┐
│ Users │
└───────┬──────┘
│ HTTPS
↓
┌──────────────────────┐
│ Web Application │
│ (Load Balancer) │
└──────┬───────────────┘
│ Internal Network
↓
┌──────────────────────┐
│ Application Servers │
└──────┬───────────────┘
│
↓
┌──────────────────────┐
│ Database │
│ (Customer Data) │
└──────────────────────┘
Threat #1: SQL Injection
├─ Threat: Attacker injects malicious SQL
├─ Impact: Read/modify customer data (HIGH)
├─ Likelihood: High (common attack)
├─ Mitigation:
│ ├─ Use parameterized queries
│ ├─ Input validation
│ ├─ WAF rule for SQL injection
│ └─ Principle of least privilege (app user can't drop tables)
└─ Residual Risk: Low (controlled)
Threat #2: Man-in-the-Middle
├─ Threat: Attacker intercepts HTTPS traffic
├─ Impact: Read passwords, session tokens (HIGH)
├─ Likelihood: Low (HTTPS breaks this attack)
├─ Mitigation:
│ ├─ Enforce HTTPS everywhere
│ ├─ Use TLS 1.2+
│ ├─ HSTS header to prevent downgrade
│ └─ Certificate pinning for critical APIs
└─ Residual Risk: Very Low (controlled)
Threat #3: Insider Threat
├─ Threat: Database admin accesses customer data
├─ Impact: Data breach, regulatory fines (CRITICAL)
├─ Likelihood: Medium (depends on hiring/training)
├─ Mitigation:
│ ├─ Least privilege (DBA only accesses needed tables)
│ ├─ Audit all database access
│ ├─ Data encryption (DBA can't read encrypted data)
│ └─ Background checks and NDAs
└─ Residual Risk: Medium (hard to eliminate)
Threat #4: Denial of Service
├─ Threat: Attacker floods application with requests
├─ Impact: Service unavailability (HIGH)
├─ Likelihood: Medium (easy attack)
├─ Mitigation:
│ ├─ DDoS protection (AWS Shield)
│ ├─ Rate limiting
│ ├─ Auto-scaling
│ └─ WAF
└─ Residual Risk: Low (controlled)
Tools for Threat Modeling:
- STRIDE: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege
- DREAD: Damage, Reproducibility, Exploitability, Affected Users, Discoverability
- PASTA: Process for Attack Simulation and Threat Analysis
19. How do you secure a microservices architecture?
Answer:
Microservices introduce new security challenges: more components, more network boundaries, more complexity.
Challenges:
Traditional Monolith:
One app, one database, one firewall
Easy to secure, hard to scale
Microservices:
Service A ←→ Service B ←→ Service C
↓ ↓ ↓
DB A DB B DB C
Challenges:
├─ Many network boundaries (more attack surface)
├─ Service-to-service authentication
├─ Data isolation between services
├─ Complex audit trails
└─ Distributed secrets management
Security Architecture:
┌──────────────────────────────────────────────┐
│ API Gateway (Authentication, Rate Limiting) │
│ ├─ Validate API keys
│ ├─ Rate limit per user
│ ├─ WAF protection
│ └─ Audit logging
└──────┬───────────────────────────────────────┘
│
├─→ ┌─────────────────────────────┐
│ │ Service A (User Service) │
│ ├─ Running in container │
│ ├─ Limited permissions │
│ ├─ No database password in │
│ │ code (use role assumption) │
│ └─ Encrypted secrets │
│ ┌─────────────────────────────┐
│ │ Private Database │
│ │ ├─ No internet access │
│ │ ├─ Encrypted │
│ │ └─ Only Service A access │
│ └─────────────────────────────┘
│
├─→ ┌─────────────────────────────┐
│ │ Service B (Order Service) │
│ ├─ Service Mesh (Istio) │
│ │ ├─ mTLS enabled (auto) │
│ │ ├─ Network policies │
│ │ └─ Distributed tracing │
│ └─ Vault integration │
│ ┌─────────────────────────────┐
│ │ Private Database │
│ │ ├─ Encrypted │
│ │ └─ Only Service B access │
│ └─────────────────────────────┘
│
└─→ ┌─────────────────────────────┐
│ Service C (Payment) │
├─ Highest security │
├─ HSM for keys │
├─ PCI-DSS compliance │
└─ Regular penetration tests │
┌─────────────────────────────┐
│ Payment Database │
│ ├─ Encryption (AES-256) │
│ ├─ Minimal data retention │
│ └─ Only Service C access │
└─────────────────────────────┘
CROSS-SERVICE COMMUNICATION:
Service A → Service B
├─ Request goes through Service Mesh
├─ Istio intercepts and enforces:
│ ├─ mTLS encryption
│ ├─ Mutual authentication
│ ├─ Rate limiting
│ ├─ Retries
│ └─ Circuit breaking
└─ Audit log of communication
Best Practices:
# Kubernetes Network Policy (Default Deny)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Allow Service A to talk to Service B
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-a-to-b
spec:
podSelector:
matchLabels:
app: service-b
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: service-a
ports:
- protocol: TCP
port: 8080
---
# Istio PeerAuthentication (enforce mTLS)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT # All traffic must be mTLS
---
# Istio AuthorizationPolicy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: service-a-policy
spec:
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/service-a"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/v1/users*"]
Key Practices:
- Service Mesh: Use Istio/Linkerd for mTLS, network policies
- API Gateway: Single entry point, authenticate once
- Service Accounts: Each service has unique identity
- Network Policies: Default deny, allow specific flows
- Secrets: Use Vault, not hardcoded in code
- Monitoring: Centralized logging and tracing
20. How do you handle secrets in cloud environments?
Answer:
Secrets (API keys, passwords, certificates) must be managed securely, not hardcoded in code.
DON'T: Hardcode Secrets
# BAD - Secrets in code
export DB_PASSWORD="mysecretpassword123"
export AWS_ACCESS_KEY="AKIAIOSFODNN7EXAMPLE"
export API_KEY="sk-1234567890abcdef"
Problems:
├─ Visible in source code forever (even if deleted)
├─ Visible in git history
├─ Visible in build artifacts
├─ Visible in running process memory
└─ Everyone has access to production secrets
DO: Use Secrets Manager
| Solution | How | Pros | Cons |
|---|---|---|---|
| AWS Secrets Manager | Cloud-managed | Easy, automatic rotation, audit logs | AWS-only |
| HashiCorp Vault | Self-hosted or SaaS | Multi-cloud, flexible, encryption | Complex setup |
| Azure Key Vault | Cloud-managed | Azure integration, HSM available | Azure-only |
| GCP Secret Manager | Cloud-managed | GCP integration, free tier | GCP-only |
Best Practice: HashiCorp Vault
# 1. Store secret in Vault
vault kv put secret/myapp/db \
username="dbuser" \
password="$(openssl rand -base64 32)"
# 2. Application requests secret
export VAULT_ADDR="https://vault.company.com:8200"
export VAULT_TOKEN=$(get-temporary-token)
vault kv get secret/myapp/db
# Returns:
# username: dbuser
# password: generatedpassword123
# 3. Token automatically rotates
# 4. Vault logs all access
# 5. Secrets never touch code
Implementation in Kubernetes:
# Step 1: Store secret in Vault
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
---
# Step 2: Vault Kubernetes Auth
# Configure Vault to trust Kubernetes service accounts
---
# Step 3: Pod retrieves secret
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
serviceAccountName: myapp
containers:
- name: myapp
image: myapp:latest
env:
- name: VAULT_ADDR
value: "https://vault.default.svc.cluster.local:8200"
# NO HARDCODED SECRETS!
---
# Step 4: Init container retrieves secret
initContainers:
- name: vault-init
image: vault:latest
command:
- sh
- -c
- |
# Get token from service account
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
# Login to Vault
VAULT_TOKEN=$(curl -X POST \
-d "{\"jwt\":\"$TOKEN\",\"role\":\"myapp\"}" \
https://vault.default.svc.cluster.local:8200/v1/auth/kubernetes/login | jq -r '.auth.client_token')
# Retrieve secrets
curl -H "X-Vault-Token: $VAULT_TOKEN" \
https://vault.default.svc.cluster.local:8200/v1/secret/data/myapp/db \
> /app/secrets/db.json
Security Best Practices:
-
Never Log Secrets
# BAD
logger.info(f"Connecting with password: {password}")
# GOOD
logger.info("Connecting to database")
# Password never appears in logs -
Rotate Regularly
# Automatic rotation every 30 days
vault write -f /sys/leases/revoke/secret/myapp/db/token -
Least Privilege Access
# Vault policy - app can only read its own secrets
path "secret/data/myapp/*" {
capabilities = ["read", "list"]
} -
Audit All Access
# Log who accessed which secret and when
vault audit list
vault audit logs -
Separate Secrets by Environment
Production: vault.prod.company.com
Staging: vault.stage.company.com
Development: vault.dev.company.com
(Different credentials for each)
Key Takeaways
- Shared Responsibility: Provider secures infrastructure; you secure everything else
- Least Privilege: Grant only minimum permissions necessary
- Defense in Depth: Multiple security layers (IAM, encryption, network, monitoring)
- Encryption Everywhere: Data at rest and in transit
- Monitor & Audit: Continuous monitoring, regular audits
- Incident Response: Have plan before incident happens
- Zero Trust: Never trust, always verify