Skip to content

🔐 IAM Fundamentals

Level: Foundation Solves: Thiết kế và quản lý identity & access management theo chuẩn enterprise security

🎯 Mục tiêu (Outcomes)

Sau khi áp dụng kiến thức trong trang này, bạn sẽ có khả năng:

  • Thiết kế IAM Strategy theo nguyên tắc least privilege cho tổ chức enterprise
  • Triển khai Role-Based Access thay thế hoàn toàn IAM Users cho human access
  • Xây dựng Cross-Account Access an toàn với ExternalId và MFA requirements
  • Áp dụng Permission Boundaries cho delegated administration
  • Cấu hình IAM Access Analyzer để phát hiện và remediate access risks
  • Thiết lập Access Auditing với CloudTrail và automated compliance checks

Khi nào dùng

IAM Roles (Ưu tiên sử dụng)

Use CaseTại sao dùng RoleVí dụ
Human accessTemporary credentials, SSO integrationDeveloper assume role để deploy
EC2/Lambda/ECSInstance profiles, automatic rotationLambda function access S3
Cross-accountNo credential sharing, auditableCI/CD từ account A deploy sang account B
Third-party integrationsExternalId protectionSaaS vendor access logs

IAM Users (Hạn chế tối đa)

Use CaseTại sao vẫn cầnBiện pháp bảo vệ
Programmatic access (legacy)Một số tools chưa support AssumeRoleAccess key rotation 90 ngày
Break glass accountsEmergency access khi SSO downHardware MFA, sealed envelope
Service accounts (exceptional)Services không support rolesStrict IP conditions, key rotation

Khi nào KHÔNG dùng

PatternVấn đềThay thế
IAM Users cho developersLong-term credentials, khó revokeSSO + AssumeRole
Shared IAM credentialsKhông thể audit ai làm gìIndividual identities
Hardcoded access keysSecurity breach chờ xảy raIAM Roles + Secrets Manager
Wildcard permissionsBlast radius vô hạnScoped policies với conditions
Root user cho daily operationsUltimate privilege, không audit đượcIAM Roles với MFA

⚠️ Cảnh báo từ Raizo

"Tôi đã forensic vụ breach của một công ty. Nguyên nhân? Developer commit AWS access key lên GitHub public repo. Key có AdministratorAccess. Hacker phát hiện trong 15 phút, spin lên 200 EC2 mining crypto. Bill $50,000 trong 2 ngày. Nếu dùng IAM Roles, chuyện này KHÔNG THỂ xảy ra."

Core Concepts

Principal Types

┌─────────────────────────────────────────────────────────────────┐
│                    IAM PRINCIPAL TYPES                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  IAM User   │  │  IAM Role   │  │  Federated  │              │
│  │             │  │             │  │   Identity  │              │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘              │
│         │                │                │                     │
│         ▼                ▼                ▼                     │
│  • Long-term creds  • Temporary creds  • External IdP           │
│  • Access keys      • AssumeRole       • SAML/OIDC              │
│  • Console password • Trust policy     • SSO                    │
│                                                                 │
│  ⚠️ ENTERPRISE RECOMMENDATION:                                  │
│  • NO IAM Users for humans → Use SSO/Identity Center            │
│  • IAM Users ONLY for service accounts (with rotation)          │
│  • Prefer IAM Roles for everything                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Policy Evaluation Logic

Least Privilege Implementation

Anti-Pattern: Overly Permissive

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

❌ Tại sao đây là anti-pattern?

  • Cho phép DELETE tất cả buckets
  • Cho phép PUBLIC access configuration
  • Không giới hạn resource scope
  • Không có conditions

Best Practice: Scoped Permissions

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowReadFromSpecificBucket",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-app-data-bucket",
        "arn:aws:s3:::my-app-data-bucket/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/team": "data-engineering"
        },
        "Bool": {
          "aws:SecureTransport": "true"
        }
      }
    }
  ]
}

Role Assumption Pattern

Cross-Account Access

┌─────────────────────────────────────────────────────────────────┐
│                 CROSS-ACCOUNT ROLE ASSUMPTION                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Account A (Source)              Account B (Target)             │
│  ┌─────────────────┐            ┌─────────────────┐             │
│  │                 │            │                 │             │
│  │  ┌───────────┐  │            │  ┌───────────┐  │             │
│  │  │ IAM Role  │  │  AssumeRole│  │ IAM Role  │  │             │
│  │  │ (Caller)  │──┼────────────┼─►│ (Target)  │  │             │
│  │  └───────────┘  │            │  └───────────┘  │             │
│  │                 │            │       │         │             │
│  │                 │            │       ▼         │             │
│  │                 │            │  ┌───────────┐  │             │
│  │                 │            │  │ Resources │  │             │
│  │                 │            │  └───────────┘  │             │
│  └─────────────────┘            └─────────────────┘             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Trust Policy (Target Role)

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:role/CrossAccountCaller"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "unique-external-id-12345"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

💡 External ID

External ID ngăn chặn "confused deputy" attack. Luôn sử dụng khi cho phép third-party assume role vào account của bạn.

Permission Boundaries

Use Case: Delegated Administration

┌─────────────────────────────────────────────────────────────────┐
│              PERMISSION BOUNDARY CONCEPT                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │              Permission Boundary                         │    │
│  │  ┌───────────────────────────────────────────────────┐  │    │
│  │  │                                                   │  │    │
│  │  │    ┌─────────────────────────────────────┐        │  │    │
│  │  │    │      Identity Policy                │        │  │    │
│  │  │    │                                     │        │  │    │
│  │  │    │   ████████ EFFECTIVE ████████       │        │  │    │
│  │  │    │   ████████ PERMISSIONS ██████       │        │  │    │
│  │  │    │                                     │        │  │    │
│  │  │    └─────────────────────────────────────┘        │  │    │
│  │  │                                                   │  │    │
│  │  └───────────────────────────────────────────────────┘  │    │
│  │                                                         │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                 │
│  Effective = Identity Policy ∩ Permission Boundary              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Permission Boundary Policy

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowedServices",
      "Effect": "Allow",
      "Action": [
        "s3:*",
        "dynamodb:*",
        "lambda:*",
        "logs:*",
        "cloudwatch:*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyPrivilegeEscalation",
      "Effect": "Deny",
      "Action": [
        "iam:CreateUser",
        "iam:CreateRole",
        "iam:AttachUserPolicy",
        "iam:AttachRolePolicy",
        "iam:PutUserPolicy",
        "iam:PutRolePolicy"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::*:policy/DeveloperBoundary"
        }
      }
    }
  ]
}

IAM Access Analyzer

Finding Types

Finding TypeDescriptionSeverity
External AccessResource accessible from outside accountHigh
Cross-AccountResource shared with another accountMedium
Public AccessResource publicly accessibleCritical
Unused AccessPermissions not used in 90 daysLow

Automated Remediation

Auditing & Compliance

CloudTrail IAM Events

json
{
  "eventSource": "iam.amazonaws.com",
  "eventName": "AttachRolePolicy",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "AROAEXAMPLE:admin-session",
    "arn": "arn:aws:sts::123456789012:assumed-role/AdminRole/admin-session"
  },
  "requestParameters": {
    "roleName": "ProductionRole",
    "policyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
  }
}

Key Events to Monitor

  • CreateUser, DeleteUser
  • CreateRole, DeleteRole
  • AttachUserPolicy, AttachRolePolicy
  • CreateAccessKey, DeleteAccessKey
  • UpdateAssumeRolePolicy
  • PutUserPermissionsBoundary

Best Practices Checklist

  • [ ] No IAM Users for human access (use SSO)
  • [ ] MFA required for all console access
  • [ ] Access keys rotated every 90 days
  • [ ] Permission boundaries for delegated admin
  • [ ] IAM Access Analyzer enabled
  • [ ] CloudTrail logging all IAM events
  • [ ] Regular access reviews (quarterly)
  • [ ] Unused credentials disabled after 90 days

⚖️ Trade-offs

Trade-off 1: Security vs Developer Experience

Khía cạnhStrict IAMRelaxed IAM
Security postureMinimized blast radiusLarger attack surface
Developer velocityChậm hơn, cần request permissionsNhanh hơn, ít friction
Operational overheadCao, cần process governanceThấp
Audit readinessDễ dàng demonstrate complianceKhó justify trong audits

Ngữ cảnh enterprise: Team Platform của một fintech phải balance giữa PCI-DSS compliance và developer productivity. Họ implement "tiered access":

  • Tier 1 (Production): Strict least-privilege, break-glass only
  • Tier 2 (Staging): Moderate permissions với approval workflow
  • Tier 3 (Dev/Sandbox): Broader permissions nhưng vẫn có boundaries

Trade-off 2: Centralized vs Decentralized IAM Management

Khía cạnhCentralized (Platform team)Decentralized (Each team)
ConsistencyUniform policiesPolicy drift possible
AgilityBottleneck tại platform teamTeams tự phục vụ
ExpertiseConcentrated, deepDistributed, varied
GovernanceEasier to enforceHarder to monitor

Khuyến nghị: Hybrid approach:

  • Centralized: Permission Boundaries, SCPs, core security policies
  • Decentralized: Teams tự tạo roles TRONG boundaries đã định

Trade-off 3: Fine-grained vs Coarse-grained Policies

Khía cạnhFine-grainedCoarse-grained
Policy sizeNhiều statements, complexÍt statements, simple
MaintenanceCần update thường xuyênỔn định hơn
Blast radiusNhỏ nhất có thểLớn hơn
DebuggingKhó hơn khi access deniedDễ troubleshoot

Ví dụ thực tế:

json
// Fine-grained (khuyến nghị cho production)
{
  "Action": ["s3:GetObject"],
  "Resource": "arn:aws:s3:::bucket/prefix/${aws:PrincipalTag/team}/*"
}

// Coarse-grained (chỉ cho dev/sandbox)
{
  "Action": ["s3:*"],
  "Resource": "arn:aws:s3:::dev-*"
}

🚨 Failure Modes

Failure Mode 1: Privilege Escalation qua iam:PassRole

🔥 Incident Pattern

Developer có quyền iam:PassRolelambda:CreateFunction. Họ tạo Lambda function với AdminRole attached, execute code với full admin privileges trong account.

Cách phát hiệnCách phòng tránh
CloudTrail monitor iam:PassRole eventsRestrict PassRole to specific roles với conditions
Detect Lambda/EC2 với high-privilege rolesSCP deny PassRole cho admin roles
Access Analyzer unused permissionsRegular review roles có thể bị passed

Policy để prevent:

json
{
  "Sid": "RestrictPassRole",
  "Effect": "Allow",
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::*:role/Lambda-*",
  "Condition": {
    "StringEquals": {
      "iam:PassedToService": "lambda.amazonaws.com"
    }
  }
}

Failure Mode 2: Stale Credentials và Unused Permissions

┌─────────────────────────────────────────────────────────────────┐
│                 CREDENTIAL LIFECYCLE PROBLEM                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Day 1:              Day 90:             Day 365:               │
│  ┌────────────┐      ┌────────────┐      ┌────────────┐         │
│  │ Key created│  →   │ Still active│  →  │ COMPROMISED│         │
│  │ for project│      │ project done│     │ attacker   │         │
│  │ XYZ        │      │ key unused  │     │ uses key   │         │
│  └────────────┘      └────────────┘      └────────────┘         │
│                                                                 │
│  Root cause: Không có lifecycle management                      │
└─────────────────────────────────────────────────────────────────┘
Cách phát hiệnCách phòng tránh
IAM Credential ReportAutomated key rotation policy
Access Analyzer unused access findings90-day inactive credential disable
CloudTrail last used analysisAutomated cleanup Lambda

Failure Mode 3: Policy Conflicts và Unexpected Denies

Cách phát hiệnCách phòng tránh
Developer reports "Access Denied" unexpectedlyDocument policy interaction matrix
IAM Policy Simulator testingTest policies trước khi deploy
CloudTrail với errorCode: AccessDeniedAlert on unusual deny patterns

Debug workflow:

bash
# Sử dụng Policy Simulator
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/MyRole \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::my-bucket/my-key

🔐 Security Baseline

IAM Configuration Requirements

RequirementImplementationVerification
No human IAM UsersSSO/Identity Center mandatoryConfig Rule: iam-user-no-policies-check
MFA everywhereSSO MFA + AssumeRole MFACredential Report + CloudTrail
Password policy14+ chars, complexity, 90-day rotationiam-password-policy Config Rule
Access key rotation90-day maximumCustom Lambda + Credential Report
Root user lockdownNo access keys, MFA enabledroot-account-mfa-enabled

Keys/Secrets Management

┌─────────────────────────────────────────────────────────────────┐
│               IAM CREDENTIAL HIERARCHY                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Level 1 - Root (NEVER USE):                                    │
│  └── Root credentials → Sealed envelope, vault, hardware MFA    │
│                                                                 │
│  Level 2 - Admin (Rare use):                                    │
│  └── Break-glass IAM User → Hardware MFA, 2-person rule         │
│                                                                 │
│  Level 3 - Operations (Daily use):                              │
│  └── SSO → Permission Sets → AssumeRole per account             │
│                                                                 │
│  Level 4 - Applications:                                        │
│  └── IAM Roles → Instance Profiles, Task Roles                  │
│  └── Service Accounts → If needed, Secrets Manager rotation     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Data Access Patterns

Principal TypeAllowed Data AccessRestrictions
Developers (SSO)Dev/Staging data onlyNo production PII
CI/CD RolesDeploy artifacts, configsNo data plane access
Application RolesSpecific resources per serviceLeast privilege, tagged resources
Audit RolesRead-only, logs onlyNo data plane, cross-account aggregate

📊 Ops Readiness

Metrics cần Monitoring

MetricNguồnAlert Threshold
IAM Users với console accessIAM API> 0 (ngoại trừ break-glass)
Access keys > 90 ngàyCredential Report> 0
Roles với AdminPolicyIAM APISpike pattern
AssumeRole failuresCloudTrail> 10/hour per principal
Access Analyzer findingsAccess AnalyzerCritical/High > 0
Unused permissionsAccess AnalyzerReview weekly

Alerting Configuration

json
{
  "EventPattern": {
    "source": ["aws.iam"],
    "detail-type": ["AWS API Call via CloudTrail"],
    "detail": {
      "eventSource": ["iam.amazonaws.com"],
      "eventName": [
        "CreateUser",
        "CreateAccessKey",
        "AttachUserPolicy",
        "AttachRolePolicy",
        "PutRolePolicy",
        "UpdateAssumeRolePolicy"
      ]
    }
  }
}

Runbook Entry Points

Tình huốngRunbook
Access key leakedrunbook/credential-compromise.md
Privilege escalation detectedrunbook/privilege-escalation-response.md
Access Analyzer high findingrunbook/access-analyzer-remediation.md
Role permission change in prodrunbook/iam-change-review.md
Break-glass activationrunbook/break-glass-procedure.md
Quarterly access reviewrunbook/access-review-process.md

Design Review Checklist

Kiến trúc IAM

  • [ ] Không có IAM Users cho human access (chỉ SSO)
  • [ ] Mọi Role có Permission Boundary attached
  • [ ] Cross-account access dùng ExternalId
  • [ ] Trust policies không có Principal: "*"

Security Controls

  • [ ] MFA enforced cho tất cả console access
  • [ ] Password policy meets compliance requirements
  • [ ] Access keys có rotation schedule
  • [ ] Root user locked down, MFA hardware

Monitoring & Audit

  • [ ] IAM Access Analyzer enabled
  • [ ] CloudTrail logging IAM events
  • [ ] Alerts cho high-risk IAM operations
  • [ ] Quarterly access reviews scheduled

Governance

  • [ ] IAM policy naming convention
  • [ ] Role tagging strategy
  • [ ] Policy review process documented
  • [ ] Least privilege documentation per role

📎 Liên kết