|
| 1 | +| name | description | |
| 2 | +|------|-------------| |
| 3 | +| cloud-infrastructure-security | Use this skill when deploying to cloud platforms, configuring infrastructure, managing IAM policies, setting up logging/monitoring, or implementing CI/CD pipelines. Provides cloud security checklist aligned with best practices. | |
| 4 | + |
| 5 | +# Cloud & Infrastructure Security Skill |
| 6 | + |
| 7 | +This skill ensures cloud infrastructure, CI/CD pipelines, and deployment configurations follow security best practices and comply with industry standards. |
| 8 | + |
| 9 | +## When to Activate |
| 10 | + |
| 11 | +- Deploying applications to cloud platforms (AWS, Vercel, Railway, Cloudflare) |
| 12 | +- Configuring IAM roles and permissions |
| 13 | +- Setting up CI/CD pipelines |
| 14 | +- Implementing infrastructure as code (Terraform, CloudFormation) |
| 15 | +- Configuring logging and monitoring |
| 16 | +- Managing secrets in cloud environments |
| 17 | +- Setting up CDN and edge security |
| 18 | +- Implementing disaster recovery and backup strategies |
| 19 | + |
| 20 | +## Cloud Security Checklist |
| 21 | + |
| 22 | +### 1. IAM & Access Control |
| 23 | + |
| 24 | +#### Principle of Least Privilege |
| 25 | + |
| 26 | +```yaml |
| 27 | +# ✅ CORRECT: Minimal permissions |
| 28 | +iam_role: |
| 29 | + permissions: |
| 30 | + - s3:GetObject # Only read access |
| 31 | + - s3:ListBucket |
| 32 | + resources: |
| 33 | + - arn:aws:s3:::my-bucket/* # Specific bucket only |
| 34 | + |
| 35 | +# ❌ WRONG: Overly broad permissions |
| 36 | +iam_role: |
| 37 | + permissions: |
| 38 | + - s3:* # All S3 actions |
| 39 | + resources: |
| 40 | + - "*" # All resources |
| 41 | +``` |
| 42 | +
|
| 43 | +#### Multi-Factor Authentication (MFA) |
| 44 | +
|
| 45 | +```bash |
| 46 | +# ALWAYS enable MFA for root/admin accounts |
| 47 | +aws iam enable-mfa-device \ |
| 48 | + --user-name admin \ |
| 49 | + --serial-number arn:aws:iam::123456789:mfa/admin \ |
| 50 | + --authentication-code1 123456 \ |
| 51 | + --authentication-code2 789012 |
| 52 | +``` |
| 53 | + |
| 54 | +#### Verification Steps |
| 55 | + |
| 56 | +- [ ] No root account usage in production |
| 57 | +- [ ] MFA enabled for all privileged accounts |
| 58 | +- [ ] Service accounts use roles, not long-lived credentials |
| 59 | +- [ ] IAM policies follow least privilege |
| 60 | +- [ ] Regular access reviews conducted |
| 61 | +- [ ] Unused credentials rotated or removed |
| 62 | + |
| 63 | +### 2. Secrets Management |
| 64 | + |
| 65 | +#### Cloud Secrets Managers |
| 66 | + |
| 67 | +```typescript |
| 68 | +// ✅ CORRECT: Use cloud secrets manager |
| 69 | +import { SecretsManager } from '@aws-sdk/client-secrets-manager'; |
| 70 | + |
| 71 | +const client = new SecretsManager({ region: 'us-east-1' }); |
| 72 | +const secret = await client.getSecretValue({ SecretId: 'prod/api-key' }); |
| 73 | +const apiKey = JSON.parse(secret.SecretString).key; |
| 74 | + |
| 75 | +// ❌ WRONG: Hardcoded or in environment variables only |
| 76 | +const apiKey = process.env.API_KEY; // Not rotated, not audited |
| 77 | +``` |
| 78 | + |
| 79 | +#### Secrets Rotation |
| 80 | + |
| 81 | +```bash |
| 82 | +# Set up automatic rotation for database credentials |
| 83 | +aws secretsmanager rotate-secret \ |
| 84 | + --secret-id prod/db-password \ |
| 85 | + --rotation-lambda-arn arn:aws:lambda:region:account:function:rotate \ |
| 86 | + --rotation-rules AutomaticallyAfterDays=30 |
| 87 | +``` |
| 88 | + |
| 89 | +#### Verification Steps |
| 90 | + |
| 91 | +- [ ] All secrets stored in cloud secrets manager (AWS Secrets Manager, Vercel Secrets) |
| 92 | +- [ ] Automatic rotation enabled for database credentials |
| 93 | +- [ ] API keys rotated at least quarterly |
| 94 | +- [ ] No secrets in code, logs, or error messages |
| 95 | +- [ ] Audit logging enabled for secret access |
| 96 | + |
| 97 | +### 3. Network Security |
| 98 | + |
| 99 | +#### VPC and Firewall Configuration |
| 100 | + |
| 101 | +```terraform |
| 102 | +# ✅ CORRECT: Restricted security group |
| 103 | +resource "aws_security_group" "app" { |
| 104 | + name = "app-sg" |
| 105 | + |
| 106 | + ingress { |
| 107 | + from_port = 443 |
| 108 | + to_port = 443 |
| 109 | + protocol = "tcp" |
| 110 | + cidr_blocks = ["10.0.0.0/16"] # Internal VPC only |
| 111 | + } |
| 112 | + |
| 113 | + egress { |
| 114 | + from_port = 443 |
| 115 | + to_port = 443 |
| 116 | + protocol = "tcp" |
| 117 | + cidr_blocks = ["0.0.0.0/0"] # Only HTTPS outbound |
| 118 | + } |
| 119 | +} |
| 120 | +
|
| 121 | +# ❌ WRONG: Open to the internet |
| 122 | +resource "aws_security_group" "bad" { |
| 123 | + ingress { |
| 124 | + from_port = 0 |
| 125 | + to_port = 65535 |
| 126 | + protocol = "tcp" |
| 127 | + cidr_blocks = ["0.0.0.0/0"] # All ports, all IPs! |
| 128 | + } |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +#### Verification Steps |
| 133 | + |
| 134 | +- [ ] Database not publicly accessible |
| 135 | +- [ ] SSH/RDP ports restricted to VPN/bastion only |
| 136 | +- [ ] Security groups follow least privilege |
| 137 | +- [ ] Network ACLs configured |
| 138 | +- [ ] VPC flow logs enabled |
| 139 | + |
| 140 | +### 4. Logging & Monitoring |
| 141 | + |
| 142 | +#### CloudWatch/Logging Configuration |
| 143 | + |
| 144 | +```typescript |
| 145 | +// ✅ CORRECT: Comprehensive logging |
| 146 | +import { CloudWatchLogsClient, CreateLogStreamCommand } from '@aws-sdk/client-cloudwatch-logs'; |
| 147 | + |
| 148 | +const logSecurityEvent = async (event: SecurityEvent) => { |
| 149 | + await cloudwatch.putLogEvents({ |
| 150 | + logGroupName: '/aws/security/events', |
| 151 | + logStreamName: 'authentication', |
| 152 | + logEvents: [{ |
| 153 | + timestamp: Date.now(), |
| 154 | + message: JSON.stringify({ |
| 155 | + type: event.type, |
| 156 | + userId: event.userId, |
| 157 | + ip: event.ip, |
| 158 | + result: event.result, |
| 159 | + // Never log sensitive data |
| 160 | + }) |
| 161 | + }] |
| 162 | + }); |
| 163 | +}; |
| 164 | +``` |
| 165 | + |
| 166 | +#### Verification Steps |
| 167 | + |
| 168 | +- [ ] CloudWatch/logging enabled for all services |
| 169 | +- [ ] Failed authentication attempts logged |
| 170 | +- [ ] Admin actions audited |
| 171 | +- [ ] Log retention configured (90+ days for compliance) |
| 172 | +- [ ] Alerts configured for suspicious activity |
| 173 | +- [ ] Logs centralized and tamper-proof |
| 174 | + |
| 175 | +### 5. CI/CD Pipeline Security |
| 176 | + |
| 177 | +#### Secure Pipeline Configuration |
| 178 | + |
| 179 | +```yaml |
| 180 | +# ✅ CORRECT: Secure GitHub Actions workflow |
| 181 | +name: Deploy |
| 182 | + |
| 183 | +on: |
| 184 | + push: |
| 185 | + branches: [main] |
| 186 | + |
| 187 | +jobs: |
| 188 | + deploy: |
| 189 | + runs-on: ubuntu-latest |
| 190 | + permissions: |
| 191 | + contents: read # Minimal permissions |
| 192 | + |
| 193 | + steps: |
| 194 | + - uses: actions/checkout@v4 |
| 195 | + |
| 196 | + # Scan for secrets |
| 197 | + - name: Secret scanning |
| 198 | + uses: trufflesecurity/trufflehog@main |
| 199 | + |
| 200 | + # Dependency audit |
| 201 | + - name: Audit dependencies |
| 202 | + run: npm audit --audit-level=high |
| 203 | + |
| 204 | + # Use OIDC, not long-lived tokens |
| 205 | + - name: Configure AWS credentials |
| 206 | + uses: aws-actions/configure-aws-credentials@v4 |
| 207 | + with: |
| 208 | + role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole |
| 209 | + aws-region: us-east-1 |
| 210 | +``` |
| 211 | +
|
| 212 | +#### Supply Chain Security |
| 213 | +
|
| 214 | +```json |
| 215 | +// package.json - Use lock files and integrity checks |
| 216 | +{ |
| 217 | + "scripts": { |
| 218 | + "install": "npm ci", // Use ci for reproducible builds |
| 219 | + "audit": "npm audit --audit-level=moderate", |
| 220 | + "check": "npm outdated" |
| 221 | + } |
| 222 | +} |
| 223 | +``` |
| 224 | + |
| 225 | +#### Verification Steps |
| 226 | + |
| 227 | +- [ ] OIDC used instead of long-lived credentials |
| 228 | +- [ ] Secrets scanning in pipeline |
| 229 | +- [ ] Dependency vulnerability scanning |
| 230 | +- [ ] Container image scanning (if applicable) |
| 231 | +- [ ] Branch protection rules enforced |
| 232 | +- [ ] Code review required before merge |
| 233 | +- [ ] Signed commits enforced |
| 234 | + |
| 235 | +### 6. Cloudflare & CDN Security |
| 236 | + |
| 237 | +#### Cloudflare Security Configuration |
| 238 | + |
| 239 | +```typescript |
| 240 | +// ✅ CORRECT: Cloudflare Workers with security headers |
| 241 | +export default { |
| 242 | + async fetch(request: Request): Promise<Response> { |
| 243 | + const response = await fetch(request); |
| 244 | + |
| 245 | + // Add security headers |
| 246 | + const headers = new Headers(response.headers); |
| 247 | + headers.set('X-Frame-Options', 'DENY'); |
| 248 | + headers.set('X-Content-Type-Options', 'nosniff'); |
| 249 | + headers.set('Referrer-Policy', 'strict-origin-when-cross-origin'); |
| 250 | + headers.set('Permissions-Policy', 'geolocation=(), microphone=()'); |
| 251 | + |
| 252 | + return new Response(response.body, { |
| 253 | + status: response.status, |
| 254 | + headers |
| 255 | + }); |
| 256 | + } |
| 257 | +}; |
| 258 | +``` |
| 259 | + |
| 260 | +#### WAF Rules |
| 261 | + |
| 262 | +```bash |
| 263 | +# Enable Cloudflare WAF managed rules |
| 264 | +# - OWASP Core Ruleset |
| 265 | +# - Cloudflare Managed Ruleset |
| 266 | +# - Rate limiting rules |
| 267 | +# - Bot protection |
| 268 | +``` |
| 269 | + |
| 270 | +#### Verification Steps |
| 271 | + |
| 272 | +- [ ] WAF enabled with OWASP rules |
| 273 | +- [ ] Rate limiting configured |
| 274 | +- [ ] Bot protection active |
| 275 | +- [ ] DDoS protection enabled |
| 276 | +- [ ] Security headers configured |
| 277 | +- [ ] SSL/TLS strict mode enabled |
| 278 | + |
| 279 | +### 7. Backup & Disaster Recovery |
| 280 | + |
| 281 | +#### Automated Backups |
| 282 | + |
| 283 | +```terraform |
| 284 | +# ✅ CORRECT: Automated RDS backups |
| 285 | +resource "aws_db_instance" "main" { |
| 286 | + allocated_storage = 20 |
| 287 | + engine = "postgres" |
| 288 | + |
| 289 | + backup_retention_period = 30 # 30 days retention |
| 290 | + backup_window = "03:00-04:00" |
| 291 | + maintenance_window = "mon:04:00-mon:05:00" |
| 292 | + |
| 293 | + enabled_cloudwatch_logs_exports = ["postgresql"] |
| 294 | + |
| 295 | + deletion_protection = true # Prevent accidental deletion |
| 296 | +} |
| 297 | +``` |
| 298 | + |
| 299 | +#### Verification Steps |
| 300 | + |
| 301 | +- [ ] Automated daily backups configured |
| 302 | +- [ ] Backup retention meets compliance requirements |
| 303 | +- [ ] Point-in-time recovery enabled |
| 304 | +- [ ] Backup testing performed quarterly |
| 305 | +- [ ] Disaster recovery plan documented |
| 306 | +- [ ] RPO and RTO defined and tested |
| 307 | + |
| 308 | +## Pre-Deployment Cloud Security Checklist |
| 309 | + |
| 310 | +Before ANY production cloud deployment: |
| 311 | + |
| 312 | +- [ ] **IAM**: Root account not used, MFA enabled, least privilege policies |
| 313 | +- [ ] **Secrets**: All secrets in cloud secrets manager with rotation |
| 314 | +- [ ] **Network**: Security groups restricted, no public databases |
| 315 | +- [ ] **Logging**: CloudWatch/logging enabled with retention |
| 316 | +- [ ] **Monitoring**: Alerts configured for anomalies |
| 317 | +- [ ] **CI/CD**: OIDC auth, secrets scanning, dependency audits |
| 318 | +- [ ] **CDN/WAF**: Cloudflare WAF enabled with OWASP rules |
| 319 | +- [ ] **Encryption**: Data encrypted at rest and in transit |
| 320 | +- [ ] **Backups**: Automated backups with tested recovery |
| 321 | +- [ ] **Compliance**: GDPR/HIPAA requirements met (if applicable) |
| 322 | +- [ ] **Documentation**: Infrastructure documented, runbooks created |
| 323 | +- [ ] **Incident Response**: Security incident plan in place |
| 324 | + |
| 325 | +## Common Cloud Security Misconfigurations |
| 326 | + |
| 327 | +### S3 Bucket Exposure |
| 328 | + |
| 329 | +```bash |
| 330 | +# ❌ WRONG: Public bucket |
| 331 | +aws s3api put-bucket-acl --bucket my-bucket --acl public-read |
| 332 | + |
| 333 | +# ✅ CORRECT: Private bucket with specific access |
| 334 | +aws s3api put-bucket-acl --bucket my-bucket --acl private |
| 335 | +aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json |
| 336 | +``` |
| 337 | + |
| 338 | +### RDS Public Access |
| 339 | + |
| 340 | +```terraform |
| 341 | +# ❌ WRONG |
| 342 | +resource "aws_db_instance" "bad" { |
| 343 | + publicly_accessible = true # NEVER do this! |
| 344 | +} |
| 345 | +
|
| 346 | +# ✅ CORRECT |
| 347 | +resource "aws_db_instance" "good" { |
| 348 | + publicly_accessible = false |
| 349 | + vpc_security_group_ids = [aws_security_group.db.id] |
| 350 | +} |
| 351 | +``` |
| 352 | + |
| 353 | +## Resources |
| 354 | + |
| 355 | +- [AWS Security Best Practices](https://aws.amazon.com/security/best-practices/) |
| 356 | +- [CIS AWS Foundations Benchmark](https://www.cisecurity.org/benchmark/amazon_web_services) |
| 357 | +- [Cloudflare Security Documentation](https://developers.cloudflare.com/security/) |
| 358 | +- [OWASP Cloud Security](https://owasp.org/www-project-cloud-security/) |
| 359 | +- [Terraform Security Best Practices](https://www.terraform.io/docs/cloud/guides/recommended-practices/) |
| 360 | + |
| 361 | +**Remember**: Cloud misconfigurations are the leading cause of data breaches. A single exposed S3 bucket or overly permissive IAM policy can compromise your entire infrastructure. Always follow the principle of least privilege and defense in depth. |
0 commit comments