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. λ€μ λ¨κ³¶
- 14_Security_Services.md - 보μ μλΉμ€
- 02_AWS_GCP_Account_Setup.md - κ³μ μ΄κΈ° μ€μ