Belajar Cloud Security Engineer - Cloud IAM & Identity
Episode 3 of 28

Belajar Cloud Security Engineer - Cloud IAM & Identity

Menguasai fondasi keamanan cloud: users, roles, dan policies, prinsip least privilege, service accounts, permission boundary, serta SCP, lengkap dengan praktik setup IAM role dan policy yang benar lewat CLI dan Terraform beserta kesalahan umum seperti wildcard action dan access key berumur panjang

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Setelah di episode 2 kita memetakan shared responsibility dan lapisan-lapisan security cloud, sekarang kita turun ke lapisan pertama dan paling menentukan: identity. Di cloud modern, identitas adalah perimeter baru. Firewall yang sempurna tidak berarti apa-apa jika sebuah IAM policy memberi izin *:* kepada service account yang tokennya bisa dicuri.

Mengapa episode ini sangat penting? Karena mayoritas privilege escalation dan exfiltrasi data di cloud dimulai dari konfigurasi IAM yang terlalu longgar — bukan dari eksploitasi kernel yang eksotis. Menguasai IAM berarti kalian bisa menutup kelas serangan terbesar di cloud dengan kode beberapa baris policy.

Anatomi IAM: Users, Roles, Policies

Tiga objek dasar yang wajib kalian bedakan dengan tajam:

ObjekDefinisiKapan Dipakai
UserIdentitas permanen untuk manusia atau systemSeminimal mungkin — prefer federasi
RoleIdentitas yang diasumsikan sementara, tanpa password/key permanenDefault untuk service dan lintas-akun
PolicyDokumen JSON yang mendefinisikan izinMenempel pada user, role, atau resource

Aturan emas: role over user. Role menghasilkan kredensial sementara (STS token) yang otomatis kedaluwarsa, sedangkan user dengan access key statis adalah bom waktu — key yang bocor tetap valid sampai dirotasi manual.

Policy JSON punya struktur Effect, Action, Resource, dan opsional Condition. Contoh policy read-only untuk satu bucket tertentu:

policy-s3-read-one-bucket.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::app-assets-prod",
        "arn:aws:s3:::app-assets-prod/*"
      ]
    }
  ]
}

Perhatikan Resource yang spesifik hingga ARN bucket — inilah lawan dari arn:aws:s3:::* yang memberi akses ke seluruh storage organisasi.

Least Privilege dalam Praktik

Least privilege mudah dikatakan, sulit dieksekusi karena izin nyata baru terlihat setelah beban kerja berjalan. Alur kerja yang pragmatis:

  1. Mulai dari minimum, tambah izin hanya saat error AccessDenied muncul.
  2. Gunakan IAM Access Analyzer policy generation — ia membaca log CloudTrail dan menghasilkan policy dari aktivitas nyata selama rentang waktu tertentu.
  3. Tinjau berkali-kali dengan Access Analyzer untuk menemukan resource yang bisa diakses dari luar akun (external trust).
  4. Terapkan permission boundary pada role developer agar eskalasi massal mustahil meski policy-nya ditulis salah.

Contoh men-generate policy dari aktivitas nyata:

Generate policy dari CloudTrail activity
aws iam generate-organizations-access-report --entity-path o-xxxxx/account/123456789012-role/app-runtime
aws accessanalyzer start-policy-generation \
  --policy-generation-details principalArn=arn:aws:iam::123456789012:role/app-runtime,cloudTrailDetails='{}'

Tip

Metrik yang layak dilaporkan tiap bulan: jumlah identitas dengan akses administratif dan persentase policy yang memakai wildcard. Jika angka itu naik, least privilege kalian sedang tergerus — bahkan tanpa insiden apa pun.

Service Accounts dan Workload Identity

Aplikasi juga butuh identitas — dan di sinilah kesalahan paling mahal sering terjadi. Prinsipnya: satu workload, satu role, nol kredensial statis.

  • Di AWS, instance/profile role melekat kredensial sementara pada EC2/ECS/Lambda tanpa perlu secret di environment variable.
  • Di GCP, service account per-service dengan Workload Identity untuk pod Kubernetes.
  • Di Azure, managed identity menghilangkan kredensial sama sekali.

Perbandingan pola yang benar vs salah:

Resources:
  AppRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument: {Statement: [{Effect: Allow, Principal: {Service: ec2.amazonaws.com}, Action: sts:AssumeRole}]}
      ManagedPolicyArns: [arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess]

Versi "benar" memberi kredensial yang dirotasi otomatis oleh platform dan bisa dicabut dengan menghapus role.

Guardrail Organisasi: SCP dan Permission Boundary

Dua mekanisme yang membuat least privilege bertahan skala besar:

  • Service Control Policy (SCP) di AWS Organizations / org policy di GCP / Azure Policy membatasi apa yang bisa dilakukan siapa pun di seluruh akun — misalnya melarang region non-approved atau melarang melepas block public access.
  • Permission boundary menutup plafon izin sebuah role — bahkan jika admin akun memberinya AdministratorAccess, boundary tetap memotong.

Contoh SCP yang mencegah region liar:

scp-region-lock.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "DenyNonApprovedRegions",
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
      "StringNotEqualsIfExists": {"aws:RequestedRegion": ["ap-southeast-1", "us-east-1"]}
    }
  }]
}

Guardrail semacam ini bekerja sebelum resource lahir — jauh lebih murah daripada remediation sesudahnya. Episode 11 dan 25 akan memperluas pola ini ke policy-as-code dan architecture review.

Praktik: Setup IAM Role yang Benar

Mari bangun role untuk aplikasi yang hanya boleh membaca objek dari satu bucket. Pertama lewat Terraform — cara yang direkomendasikan karena tereview dan ter-versi:

app-role.tf
resource "aws_iam_role" "app_runtime" {
  name = "app-runtime"
 
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}
 
resource "aws_iam_role_policy" "app_s3_read" {
  name = "s3-read-app-assets"
  role = aws_iam_role.app_runtime.id
 
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["s3:GetObject"]
      Resource = "arn:aws:s3:::app-assets-prod/*"
    }]
  })
}

Terapkan dan verifikasi:

Deploy dan uji role
terraform init && terraform apply -auto-approve
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/app-runtime \
  --action-names s3:GetObject s3:DeleteObject \
  --resource-arns arn:aws:s3:::app-assets-prod/file.png

simulate-principal-policy adalah alat verifikasi favorit: ia menjawab "boleh atau tidak" tanpa harus mencoba aksi aslinya. Hasil yang diharapkan: s3:GetObject bernilai allowed, s3:DeleteObject bernilai explicitDeny atau implicitDeny.

Common Pitfalls

  • Wildcard ganda Action: "*", Resource: "*" — izin dewa; hampir selalu hasil copy-paste tutorial.
  • Access key berumur panjang untuk CI/CD — solusi modern: OIDC federation (GitHub Actions → STS), kita bahas di episode 14.
  • Trust policy terlalu luasPrincipal: "*" pada assume role mempersilakan akun lain mengambil role kalian.
  • Izin tersembunyi di grup/policy terkelola lama — audit berkala wajib; izin yang tidak dipakai dalam 90 hari layak dicabut.

Warning

Aktifkan MFA enforcement sekarang, bukan nanti: policy Deny dengan kondisi aws:MultiFactorAuthPresent = false untuk semua aksi sensitif. Akun konsol tanpa MFA adalah vektor takeover termudah di cloud.

Penutup

Inti yang harus dibawa pulang:

  • Identitas adalah perimeter cloud: users, roles, policies — dan role over user sebagai default.
  • Least privilege dieksekusi lewat siklus: mulai minimal, generate dari log nyata, audit dengan Access Analyzer, tutup plafon dengan permission boundary dan SCP.
  • Workload identity harus bebas kredensial statis: instance role, managed identity, Workload Identity.
  • Verifikasi izin dengan simulate-principal-policy, bukan trial-and-error di production.

Di episode 4 selanjutnya kita naik ke lapisan kedua: cloud network security — desain VPC, security groups vs NACL, segmentasi, dan egress control yang membuat lateral movement jadi sulit. Sampai jumpa!