IAM (Identity and Access Management)

IAM (Identity and Access Management)

1. IAM κ°œμš”

1.1 IAMμ΄λž€?

IAM은 ν΄λΌμš°λ“œ λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ 접근을 μ•ˆμ „ν•˜κ²Œ μ œμ–΄ν•˜λŠ” μ„œλΉ„μŠ€μž…λ‹ˆλ‹€.

핡심 질문: - λˆ„κ°€ (Who): μ‚¬μš©μž, κ·Έλ£Ή, μ—­ν•  - 무엇을 (What): λ¦¬μ†ŒμŠ€ - μ–΄λ–»κ²Œ (How): κΆŒν•œ (ν—ˆμš©/κ±°λΆ€)

1.2 AWS vs GCP IAM 비ꡐ

ν•­λͺ© AWS IAM GCP IAM
λ²”μœ„ 계정 μˆ˜μ€€ 쑰직/ν”„λ‘œμ νŠΈ μˆ˜μ€€
μ •μ±… λΆ€μ°© μ‚¬μš©μž/κ·Έλ£Ή/역할에 λ¦¬μ†ŒμŠ€μ—
μ—­ν•  역할을 맑음 (AssumeRole) μ—­ν•  바인딩
μ„œλΉ„μŠ€ 계정 μ—­ν•  + μΈμŠ€ν„΄μŠ€ ν”„λ‘œνŒŒμΌ μ„œλΉ„μŠ€ 계정

2. AWS IAM

2.1 핡심 κ°œλ…

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  AWS 계정                                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚  IAM                                                    β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚β”‚
β”‚  β”‚  β”‚    μ‚¬μš©μž     β”‚  β”‚     κ·Έλ£Ή      β”‚                   β”‚β”‚
β”‚  β”‚  β”‚  (Users)      β”‚  β”‚  (Groups)     β”‚                   β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚β”‚
β”‚  β”‚         ↓                  ↓                            β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚β”‚
β”‚  β”‚  β”‚              μ •μ±… (Policies)                β”‚        β”‚β”‚
β”‚  β”‚  β”‚  { "Effect": "Allow",                       β”‚        β”‚β”‚
β”‚  β”‚  β”‚    "Action": "s3:*",                        β”‚        β”‚β”‚
β”‚  β”‚  β”‚    "Resource": "*" }                        β”‚        β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚β”‚
β”‚  β”‚                     ↓                                   β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚β”‚
β”‚  β”‚  β”‚              μ—­ν•  (Roles)                         β”‚  β”‚β”‚
β”‚  β”‚  β”‚  - EC2 μΈμŠ€ν„΄μŠ€ μ—­ν•                               β”‚  β”‚β”‚
β”‚  β”‚  β”‚  - Lambda μ‹€ν–‰ μ—­ν•                                β”‚  β”‚β”‚
β”‚  β”‚  β”‚  - ꡐ차 계정 μ—­ν•                                  β”‚  β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2.2 μ‚¬μš©μž 및 κ·Έλ£Ή

# μ‚¬μš©μž 생성
aws iam create-user --user-name john

# 둜그인 λΉ„λ°€λ²ˆν˜Έ μ„€μ •
aws iam create-login-profile \
    --user-name john \
    --password 'TempPassword123!' \
    --password-reset-required

# μ•‘μ„ΈμŠ€ ν‚€ 생성 (ν”„λ‘œκ·Έλž˜λ° μ ‘κ·Ό)
aws iam create-access-key --user-name john

# κ·Έλ£Ή 생성
aws iam create-group --group-name Developers

# 그룹에 μ‚¬μš©μž μΆ”κ°€
aws iam add-user-to-group --group-name Developers --user-name john

# κ·Έλ£Ή 멀버 확인
aws iam get-group --group-name Developers

2.3 μ •μ±… (Policies)

μ •μ±… ꡬ쑰:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowS3Read",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "203.0.113.0/24"
                }
            }
        }
    ]
}
# κ΄€λ¦¬ν˜• μ •μ±… μ—°κ²°
aws iam attach-user-policy \
    --user-name john \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# μ»€μŠ€ν…€ μ •μ±… 생성
aws iam create-policy \
    --policy-name MyS3Policy \
    --policy-document file://policy.json

# 그룹에 μ •μ±… μ—°κ²°
aws iam attach-group-policy \
    --group-name Developers \
    --policy-arn arn:aws:iam::123456789012:policy/MyS3Policy

# 인라인 μ •μ±… μΆ”κ°€
aws iam put-user-policy \
    --user-name john \
    --policy-name InlinePolicy \
    --policy-document file://inline-policy.json

2.4 μ—­ν•  (Roles)

EC2 μΈμŠ€ν„΄μŠ€ μ—­ν• :

# μ‹ λ’° μ •μ±… (λˆ„κ°€ 역할을 맑을 수 μžˆλŠ”μ§€)
cat > trust-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {"Service": "ec2.amazonaws.com"},
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF

# μ—­ν•  생성
aws iam create-role \
    --role-name EC2-S3-Access \
    --assume-role-policy-document file://trust-policy.json

# μ •μ±… μ—°κ²°
aws iam attach-role-policy \
    --role-name EC2-S3-Access \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# μΈμŠ€ν„΄μŠ€ ν”„λ‘œνŒŒμΌ 생성 및 μ—­ν•  μΆ”κ°€
aws iam create-instance-profile --instance-profile-name EC2-S3-Profile
aws iam add-role-to-instance-profile \
    --instance-profile-name EC2-S3-Profile \
    --role-name EC2-S3-Access

# EC2에 μΈμŠ€ν„΄μŠ€ ν”„λ‘œνŒŒμΌ μ—°κ²°
aws ec2 associate-iam-instance-profile \
    --instance-id i-1234567890abcdef0 \
    --iam-instance-profile Name=EC2-S3-Profile

ꡐ차 계정 μ—­ν• :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::OTHER_ACCOUNT_ID:root"},
            "Action": "sts:AssumeRole"
        }
    ]
}
# λ‹€λ₯Έ κ³„μ •μ—μ„œ μ—­ν•  λ§‘κΈ°
aws sts assume-role \
    --role-arn arn:aws:iam::TARGET_ACCOUNT:role/CrossAccountRole \
    --role-session-name MySession

3. GCP IAM

3.1 핡심 κ°œλ…

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  쑰직 (Organization)                                        β”‚
β”‚  β”œβ”€β”€ 폴더 (Folder)                                          β”‚
β”‚  β”‚   └── ν”„λ‘œμ νŠΈ (Project)                                 β”‚
β”‚  β”‚       └── λ¦¬μ†ŒμŠ€ (Resource)                              β”‚
β”‚  └─────────────────────────────────────────────────────────│
β”‚                                                             β”‚
β”‚  IAM 바인딩:                                                β”‚
β”‚  주체 (Member) + μ—­ν•  (Role) = λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ κΆŒν•œ           β”‚
β”‚                                                             β”‚
β”‚  예: user:john@example.com + roles/storage.admin            β”‚
β”‚      β†’ gs://my-bucket에 λŒ€ν•œ κ΄€λ¦¬μž κΆŒν•œ                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3.2 μ—­ν•  μœ ν˜•

μœ ν˜• μ„€λͺ… μ˜ˆμ‹œ
κΈ°λ³Έ μ—­ν•  넓은 κΆŒν•œ Owner, Editor, Viewer
μ‚¬μ „μ •μ˜ μ—­ν•  μ„œλΉ„μŠ€λ³„ μ„ΈλΆ„ν™” roles/storage.admin
μ»€μŠ€ν…€ μ—­ν•  μ‚¬μš©μž μ •μ˜ my-custom-role

3.3 μ—­ν•  바인딩

# ν”„λ‘œμ νŠΈ μˆ˜μ€€ μ—­ν•  λΆ€μ—¬
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="user:john@example.com" \
    --role="roles/compute.admin"

# 버킷 μˆ˜μ€€ μ—­ν•  λΆ€μ—¬
gsutil iam ch user:john@example.com:objectViewer gs://my-bucket

# μ—­ν•  바인딩 쑰회
gcloud projects get-iam-policy PROJECT_ID

# μ—­ν•  제거
gcloud projects remove-iam-policy-binding PROJECT_ID \
    --member="user:john@example.com" \
    --role="roles/compute.admin"

3.4 μ„œλΉ„μŠ€ 계정

# μ„œλΉ„μŠ€ 계정 생성
gcloud iam service-accounts create my-service-account \
    --display-name="My Service Account"

# μ—­ν•  λΆ€μ—¬
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:my-service-account@PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/storage.admin"

# ν‚€ 파일 생성 (ν”„λ‘œκ·Έλž˜λ° μ ‘κ·Ό)
gcloud iam service-accounts keys create key.json \
    --iam-account=my-service-account@PROJECT_ID.iam.gserviceaccount.com

# Compute Engine에 μ„œλΉ„μŠ€ 계정 μ—°κ²°
gcloud compute instances create my-instance \
    --service-account=my-service-account@PROJECT_ID.iam.gserviceaccount.com \
    --scopes=cloud-platform

3.5 μ›Œν¬λ‘œλ“œ 아이덴티티 (GKE)

# μ›Œν¬λ‘œλ“œ 아이덴티티 ν’€ ν™œμ„±ν™”
gcloud container clusters update my-cluster \
    --region=asia-northeast3 \
    --workload-pool=PROJECT_ID.svc.id.goog

# Kubernetes μ„œλΉ„μŠ€ 계정과 GCP μ„œλΉ„μŠ€ 계정 μ—°κ²°
gcloud iam service-accounts add-iam-policy-binding \
    my-gcp-sa@PROJECT_ID.iam.gserviceaccount.com \
    --role=roles/iam.workloadIdentityUser \
    --member="serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/K8S_SA]"

4. μ΅œμ†Œ κΆŒν•œ 원칙

4.1 원칙

μ΅œμ†Œ κΆŒν•œ = μž‘μ—… μˆ˜ν–‰μ— ν•„μš”ν•œ μ΅œμ†Œν•œμ˜ κΆŒν•œλ§Œ λΆ€μ—¬

잘λͺ»λœ 예:
- Admin κΆŒν•œμ„ λͺ¨λ“  μ‚¬μš©μžμ—κ²Œ
- * (λͺ¨λ“  λ¦¬μ†ŒμŠ€)에 λŒ€ν•œ κΆŒν•œ

μ˜¬λ°”λ₯Έ 예:
- ν•„μš”ν•œ Action만 λͺ…μ‹œ
- νŠΉμ • λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ κΆŒν•œ
- 쑰건뢀 μ ‘κ·Ό

4.2 AWS μ •μ±… μ˜ˆμ‹œ

λ‚˜μœ 예:

{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
}

쒋은 예:

{
    "Effect": "Allow",
    "Action": [
        "s3:GetObject",
        "s3:PutObject"
    ],
    "Resource": "arn:aws:s3:::my-bucket/uploads/*",
    "Condition": {
        "StringEquals": {
            "s3:x-amz-acl": "private"
        }
    }
}

4.3 GCP μ—­ν•  선택

# κΆŒν•œμ΄ λ„ˆλ¬΄ 넓은 μ—­ν•  (ν”Όν•  것)
roles/owner
roles/editor

# μ μ ˆν•œ μ—­ν• 
roles/storage.objectViewer  # 객체 읽기만
roles/compute.instanceAdmin.v1  # μΈμŠ€ν„΄μŠ€ κ΄€λ¦¬λ§Œ
roles/cloudsql.client  # SQL μ—°κ²°λ§Œ

5. 쑰건뢀 μ ‘κ·Ό

5.1 AWS 쑰건

{
    "Effect": "Allow",
    "Action": "s3:*",
    "Resource": "*",
    "Condition": {
        "IpAddress": {
            "aws:SourceIp": "203.0.113.0/24"
        },
        "Bool": {
            "aws:MultiFactorAuthPresent": "true"
        },
        "DateGreaterThan": {
            "aws:CurrentTime": "2024-01-01T00:00:00Z"
        },
        "StringEquals": {
            "aws:RequestedRegion": "ap-northeast-2"
        }
    }
}

5.2 GCP 쑰건

# 쑰건뢀 μ—­ν•  바인딩
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="user:john@example.com" \
    --role="roles/compute.admin" \
    --condition='expression=request.time < timestamp("2024-12-31T23:59:59Z"),title=Temporary Access,description=Access until end of year'

# IP 기반 쑰건 (VPC Service Controls와 ν•¨κ»˜)
expression: 'resource.name.startsWith("projects/PROJECT_ID/zones/asia-northeast3")'

6. κΆŒν•œ 뢄석

6.1 AWS IAM Access Analyzer

# Access Analyzer 생성
aws accessanalyzer create-analyzer \
    --analyzer-name my-analyzer \
    --type ACCOUNT

# 뢄석 κ²°κ³Ό 쑰회
aws accessanalyzer list-findings --analyzer-arn arn:aws:access-analyzer:...:analyzer/my-analyzer

# μ •μ±… 검증
aws accessanalyzer validate-policy \
    --policy-document file://policy.json \
    --policy-type IDENTITY_POLICY

6.2 GCP Policy Analyzer

# IAM μ •μ±… 뢄석
gcloud asset analyze-iam-policy \
    --organization=ORG_ID \
    --identity="user:john@example.com"

# κΆŒν•œ 확인
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --filter="bindings.members:john@example.com" \
    --format="table(bindings.role)"

7. MFA (닀쀑 인증)

7.1 AWS MFA

# 가상 MFA ν™œμ„±ν™”
aws iam create-virtual-mfa-device \
    --virtual-mfa-device-name john-mfa \
    --outfile qrcode.png \
    --bootstrap-method QRCodePNG

# MFA λ””λ°”μ΄μŠ€ μ—°κ²°
aws iam enable-mfa-device \
    --user-name john \
    --serial-number arn:aws:iam::123456789012:mfa/john-mfa \
    --authentication-code1 123456 \
    --authentication-code2 789012

# MFA ν•„μˆ˜ μ •μ±…
{
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
        "BoolIfExists": {
            "aws:MultiFactorAuthPresent": "false"
        }
    }
}

7.2 GCP 2단계 인증

# 쑰직 μˆ˜μ€€μ—μ„œ 2FA κ°•μ œ (Admin Consoleμ—μ„œ)
# Google Workspace Admin β†’ Security β†’ 2-Step Verification

# μ„œλΉ„μŠ€ 계정은 MFA λΆˆκ°€ β†’ λŒ€μ‹ :
# - ν‚€ 파일 μ•ˆμ „ 관리
# - μ›Œν¬λ‘œλ“œ 아이덴티티 μ‚¬μš©
# - 단기 토큰 μ‚¬μš©

8. 일반적인 μ—­ν•  νŒ¨ν„΄

8.1 AWS 일반 μ—­ν• 

μ—­ν•  κΆŒν•œ μš©λ„
AdministratorAccess 전체 κ΄€λ¦¬μž
PowerUserAccess IAM μ œμ™Έ 전체 개발자
ReadOnlyAccess 읽기 μ „μš© 감사/λ·°μ–΄
AmazonS3FullAccess S3 전체 μŠ€ν† λ¦¬μ§€ 관리
AmazonEC2FullAccess EC2 전체 μ»΄ν“¨νŒ… 관리

8.2 GCP 일반 μ—­ν• 

μ—­ν•  κΆŒν•œ μš©λ„
roles/owner 전체 κ΄€λ¦¬μž
roles/editor IAM μ œμ™Έ νŽΈμ§‘ 개발자
roles/viewer 읽기 μ „μš© λ·°μ–΄
roles/compute.admin Compute 전체 인프라 관리
roles/storage.admin Storage 전체 μŠ€ν† λ¦¬μ§€ 관리

9. λ³΄μ•ˆ λͺ¨λ²” 사둀

β–‘ Root/Owner 계정은 일상 업무에 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ
β–‘ Root/Owner 계정에 MFA ν™œμ„±ν™”
β–‘ μ΅œμ†Œ κΆŒν•œ 원칙 적용
β–‘ κ·Έλ£Ή/역할을 ν†΅ν•œ κΆŒν•œ 관리 (κ°œλ³„ μ‚¬μš©μž X)
β–‘ 정기적인 κΆŒν•œ κ²€ν†  (λ―Έμ‚¬μš© κΆŒν•œ 제거)
β–‘ μ„œλΉ„μŠ€ 계정 ν‚€ 파일 μ•ˆμ „ 관리
β–‘ μž„μ‹œ 자격 증λͺ… μ‚¬μš© (STS, μ›Œν¬λ‘œλ“œ 아이덴티티)
β–‘ 쑰건뢀 μ ‘κ·Ό ν™œμš© (IP, μ‹œκ°„, MFA)
β–‘ 감사 둜그 ν™œμ„±ν™” (CloudTrail, Cloud Audit Logs)
β–‘ μ •μ±… λ³€κ²½ μ•Œλ¦Ό μ„€μ •

10. λ‹€μŒ 단계


참고 자료

to navigate between lessons