Cert Notes/ 출퇴근 학습 노트
로드맵
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
  • Week 1
    • 1.개발자 시점에서 본 AWS: 리전, 인프라, 그리고 책임의 경계
    • 2.IAM의 4대 엔터티: User, Group, Role, Policy
    • 3.STS와 정책 조건: 임시 자격증명의 깊은 세계
    • 4.AWS CLI와 SDK: 자격증명 체이닝부터 SigV4까지
    • 5.Week 1 종합: 인프라와 IAM이 만드는 신뢰의 사슬
  • Week 2
    • 1.EC2의 해부학: Nitro, 인스턴스 패밀리, AMI의 내부
    • 2.개발자가 만져야 하는 네트워크 경계: Security Group, Key Pair, User Data
    • 3.EC2의 디스크 layer: EBS, Instance Store, 그리고 그 위의 EFS·FSx
    • 4.트래픽을 분산하는 layer: ALB·NLB·GWLB, 그리고 Auto Scaling Group
    • 5.Week 2 종합: EC2 layer가 한 시스템 안에서 맞물리는 방식
  • Week 3
    • 1.Lambda Execution Model: Firecracker MicroVM이 함수를 실행하는 방법
    • 2.Lambda 이벤트 소스 매핑: SQS·Kinesis·DynamoDB Streams 내부 폴링 메커니즘
    • 3.Lambda 버전·별칭·레이어: Immutable 배포와 의존성 분리의 원리
    • 4.Lambda 동시성 제어: Token Bucket 알고리즘과 에러 처리 계층
    • 5.Week 3 복습: Lambda 종합 시나리오로 실전 감각 다지기
  • Week 4
    • 1.API Gateway REST API: 요청이 백엔드에 도달하기까지의 전체 경로
    • 2.API Gateway 통합 유형과 VTL 매핑 템플릿: Lambda 없이 DynamoDB를 직접 호출하기
    • 3.API Gateway 보안·캐싱·스로틀링: SigV4부터 Token Bucket까지 요청이 통제되는 방법
    • 4.WebSocket API와 HTTP API: 실시간 연결과 경량 프록시의 내부 동작
    • 5.Week 4 복습: API Gateway 종합 시나리오로 실전 감각 다지기
  • Week 5
    • 1.S3: 객체 스토리지의 철학과 스토리지 클래스 설계
    • 2.S3: 버전 관리, 수명 주기 정책, 그리고 복제의 내부 동작
    • 3.S3 보안: 버킷 정책, 암호화, 그리고 접근 제어의 계층 구조
    • 4.S3 성능 최적화: 멀티파트 업로드, 전송 가속화, 접두사 설계
    • 5.S3 고급 기능 + Week 5 종합 복습
  • Week 6
    • 1.DynamoDB: NoSQL의 철학과 파티션 설계의 수학
    • 2.DynamoDB: 파티션 키 설계의 수학, LSI/GSI 내부 동작, Single-Table Design
    • 3.DynamoDB: RCU/WCU 수학, DAX 아키텍처, Streams 처리
    • 4.DynamoDB: 트랜잭션, 조건부 쓰기, TTL의 내부 동작
    • 5.Week 6 종합 복습: DynamoDB 전체 지형도
  • Week 7
    • 1.RDS: 관리형 RDBMS의 두 얼굴, Multi-AZ와 Read Replica
    • 2.RDS의 보안·백업·모니터링: Capital One 사고가 남긴 교훈들
    • 3.ElastiCache: 인메모리 캐시는 어떻게 DB를 살리는가
    • 4.Aurora: AWS가 RDBMS의 스토리지 레이어를 다시 쓴 이야기
    • 5.Week 7 종합: 데이터 계층 의사결정의 모든 것
  • Week 8
    • 1.CodeCommit과 CodeBuild: AWS가 그린 CI/CD의 첫 두 칸
    • 2.CodeDeploy: 배포라는 가장 위험한 순간을 안전하게
    • 3.CodePipeline: CI/CD 흐름의 지휘자
    • 4.Elastic Beanstalk: AWS가 만든 가장 친절한 PaaS
    • 5.Week 8 종합 복습: CI/CD 파이프라인을 머릿속에서 끝까지 돌려보기
  • Week 9
    • 1.KMS: 암호화 키를 직접 만지지 않고 다루는 기술
    • 2.Secrets Manager와 Parameter Store: 비밀을 코드 밖으로 꺼내기
    • 3.Cognito: 인증과 인가를 두 개의 풀로 나눈 이유
    • 4.WAF, Shield, ACM: 트래픽이 앱에 닿기 전에 거르는 세 겹
    • 5.Week 9 복습: 보안은 한 줄의 설정이 아니라 계층의 합이다
  • Week 10
    • 1.CloudWatch: 지표 하나가 어떻게 알람과 자동화로 이어지는가
    • 2.X-Ray: "어디서 느린가"를 답하는 분산 추적
    • 3.CloudTrail과 EventBridge: 감사와 반응의 두 축
    • 4.CloudWatch 고급: 컨테이너, 합성 모니터링, 그리고 ML 이상 탐지
    • 5.Week 10 종합: 모니터링이라는 하나의 이야기
  • Week 11
    • 1.SQS: 큐 하나가 어떻게 시스템을 떼어놓는가
    • 2.SNS: 한 번 발행하면 모두가 듣는다
    • 3.Kinesis: 흐르는 데이터를 붙잡아두는 로그
    • 4.Step Functions와 AppSync: 흐름을 코드 밖으로 꺼내다
    • 5.Week 11 종합: 메시징의 모델을 가르는 질문들
  • Week 12
    • 1.ECS와 Fargate: 컨테이너를 "서버 없이" 돌린다는 말의 진짜 의미
    • 2.CloudFormation: 인프라를 "선언"한다는 발상
    • 3.SAM: 서버리스를 위해 CloudFormation을 압축하다
    • 4.CDK와 서버리스 아키텍처: "인프라를 코드로 쓴다"의 끝, 그리고 좋은 설계의 문법
    • 5.Week 12 종합 복습: 컨테이너와 IaC를 하나의 그림으로 꿰기
  • Week 13
    • 1.최종 복습 1: IAM, EC2, Lambda, API Gateway
    • 2.최종 복습 2: S3, DynamoDB, RDS, ElastiCache
    • 3.최종 복습 3: 보안, 모니터링, CI/CD
    • 4.최종 복습 4: 메시징, 컨테이너, 아키텍처 패턴
    • 5.최종 모의고사 + 시험 준비 완료
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
SCS-C03 · SpecialtySecurity - Specialty
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
합격 후기
← DVA-C02/Week 1/Day 2
DVA-C02· AssociateWeek 1 · Day 2읽기 약 19분

Day 2 - IAM의 4대 엔터티: User, Group, Role, Policy

콘솔에서 처음 IAM 메뉴를 열면 사용자·그룹·역할·정책이라는 네 가지 항목이 나란히 보인다. 신규 개발자에게 이걸 설명할 때 가장 흔한 실수는 "User는 사람, Role은 서버"라고 단순화하는 것이다. 틀린 말은 아니지만, 이 모델로는 "왜 Lambda에 사용자 access key를 박으면 안 되는지", "왜 EC2 인스턴스에 attach한 Role이 SSO 사용자보다 안전한지"를 설명할 수 없다.

IAM은 클라우드에서 누가(Principal) 무엇을(Action) 어떤 자원에(Resource) 어떤 조건에서(Condition) 할 수 있는지를 결정하는 권한 부여(authorization) 엔진이다. 이 한 줄이 IAM 전체의 설계 철학을 압축한다. 오늘 우리가 볼 것은 그 엔진의 네 부품 — User, Group, Role, Policy — 이 어떻게 맞물려 동작하는지다.

왜 클라우드는 새로운 권한 모델이 필요했을까

전통적인 인증·인가 모델은 두 가지 패턴이 지배했다. DAC(Discretionary Access Control, 1970년대 Unix file permission)은 소유자가 권한을 줬다 뺐다 한다. MAC(Mandatory Access Control, 1973년 Bell-LaPadula model)은 시스템이 분류 레이블에 따라 강제로 통제한다. 그 위에 1992년 Ferraiolo & Kuhn의 RBAC(Role-Based Access Control)가 산업 표준이 되며 LDAP·Active Directory의 토대가 됐다.

클라우드가 등장하며 이 모델들이 깨졌다. 첫째, 자원이 API로 동적으로 생기고 사라진다. RBAC의 정적 role assignment로는 "방금 만든 S3 버킷에 접근할 권한"을 표현하기 어렵다. 둘째, 자원이 여러 계정·서비스 간을 넘나든다. AD의 도메인 경계로 묶을 수 없다. 셋째, 머신이 머신을 호출하는 빈도가 사람의 로그인보다 압도적으로 많아졌다(Lambda → DynamoDB, EC2 → S3, ECS → Secrets Manager 등). 사람용 자격증명을 그대로 머신에 쓰면 키 유출 위험이 폭증한다.

AWS는 이 세 압력에 대응하며 IAM을 ABAC(Attribute-Based Access Control, 2014년 NIST SP 800-162로 표준화) 기반으로 진화시켰다. Condition key로 aws:RequestTag, aws:PrincipalTag 같은 속성을 검사하면 "Engineering 부서 태그가 붙은 사용자는 Engineering 태그가 붙은 자원에만 접근"이라는 동적 규칙이 가능해진다.

💡 관련 이론: RBAC vs ABAC의 trade-off는 분명하다. RBAC는 단순하고 감사가 쉽지만 자원 수가 늘면 role 폭발(role explosion) 문제가 생긴다(예: 100개 프로젝트 × 5개 역할 = 500개 role). ABAC는 정책 개수가 적게 유지되지만 디버깅이 어려워진다("왜 이 사용자가 거부됐는지"가 여러 속성의 조합에 달려 있다). 실무에서는 **상위 권한 구조는 RBAC(Group), 세부 자원 제어는 ABAC(Tag)**로 혼합하는 것이 일반적이다.

User: 사람이거나, 사람처럼 행동하는 시스템

IAM User는 장기 자격증명(long-term credential)을 가진 엔터티다. 로그인 비밀번호로 콘솔에 들어오거나, Access Key ID + Secret Access Key로 CLI/SDK에 인증한다. 자격증명이 만료되지 않는다는 점이 가장 큰 위험이자 IAM Role과 갈리는 결정적 지점이다.

자격증명 종류만료회전 책임적합한 용도
Console password정책으로 강제사용자사람의 콘솔 로그인
Access Key (AK/SK)없음 (수동 회전)사용자/관리자CLI, SDK, 외부 시스템
MFA token30초 (TOTP)자동추가 인증
STS 임시 자격증명15분 ~ 12시간자동Role assume, Federation

🔍 더 깊이: IAM User의 access key는 IAM Access Analyzer가 "last used" 정보를 추적한다. aws iam get-access-key-last-used --access-key-id AKIA...로 마지막 사용 시간을 확인하고, 90일 이상 미사용 키는 비활성화하는 것이 보안 모범 사례다. AWS 자체 보안 가이드(IAM Best Practices)는 **사람용 자격증명을 IAM User 대신 AWS IAM Identity Center(구 SSO)**로 옮기라고 강력히 권장한다. SSO는 ID Provider(Okta, Azure AD 등)와 SAML 2.0 또는 OIDC로 연동하며, 최종적으로는 STS로 임시 자격증명을 발급하므로 장기 키가 아예 존재하지 않는다.

📚 사례: 2014년 6월 Code Spaces 사건. GitHub 코드 호스팅 회사였던 Code Spaces가 AWS root account 자격증명을 탈취당해 EC2·S3·EBS·AMI·스냅샷이 전부 삭제됐고, 18시간 만에 회사가 폐업했다. 직접 원인은 MFA 미적용 + 단일 자격증명 의존이었다. AWS는 이 사건 직후 root account에 MFA 강제, IAM User에 MFA 강제 정책 변수(aws:MultiFactorAuthPresent) 같은 안전장치들을 더 적극적으로 권장하기 시작했다.

Group: 권한 묶음의 단위

IAM Group은 사람을 묶는 컨테이너지, 권한의 주체가 아니다. Group에 정책을 attach하면 그 그룹의 모든 User에게 권한이 전파된다. Group 자체는 자원을 호출하지 못한다(Group은 Principal이 될 수 없다).

[ Engineering Group ]
    ├── Alice (User)
    ├── Bob (User)
    └── Policy: AmazonS3ReadOnlyAccess
                 ↓
        Alice, Bob 모두 S3 읽기 가능

Group의 핵심 가치는 권한의 재사용과 감사 가능성이다. 50명 엔지니어에게 일일이 정책을 붙이면 누가 무슨 권한이 있는지 추적이 불가능하다. Group으로 묶으면 "Engineering Group이 가진 권한 = Alice의 권한"이 되어 변경 추적이 쉬워진다. 다만 Group은 nested(중첩)될 수 없고, User는 최대 10개 Group에 속할 수 있다. 단순한 구조가 의도다.

Role: 임시 자격증명의 생산자

IAM Role은 IAM의 가장 강력한 무기이자 가장 자주 시험에 나오는 개념이다. Role은 누구도 소유하지 않은 권한 묶음이고, 누군가가 그 Role을 "assume"하면 STS가 임시 자격증명을 발급해준다. 임시 자격증명은 ① Access Key ID, ② Secret Access Key, ③ Session Token(이게 핵심) 3종 세트로 구성되며, 기본 1시간 후 자동 만료된다.

1. Lambda 함수가 시작됨
2. Lambda 런타임이 STS AssumeRole 호출
3. STS가 임시 자격증명 발급 (1시간 유효)
4. Lambda 코드가 그 자격증명으로 DynamoDB 호출
5. 1시간 후 만료되면 SDK가 자동으로 재발급

EC2 인스턴스에 attach한 Role은 더 미묘하게 동작한다. EC2는 IMDS(인스턴스 메타데이터 서비스)를 통해 자격증명을 노출한다. SDK가 169.254.169.254/latest/meta-data/iam/security-credentials/<RoleName>을 GET하면 임시 자격증명이 JSON으로 반환된다. 이 자격증명은 약 6시간 유효하지만 SDK는 만료 15분 전에 자동 갱신한다.

🔍 더 깊이: AssumeRole의 내부 동작은 다음과 같다. (1) Principal이 sts:AssumeRole API를 호출하며 RoleArn을 지정한다. (2) STS는 Role의 Trust Policy(누가 이 Role을 assume할 수 있는지 정의)를 평가한다. (3) 통과하면 Role의 Permission Policy(이 Role이 무엇을 할 수 있는지)를 부여한다. (4) STS가 임시 자격증명을 발급하며 JWT-like 구조의 Session Token에 권한·만료 시간을 서명해 담는다. (5) 이후 API 호출은 Signature V4로 서명되고, AWS는 Session Token을 디코드해 권한을 확인한다. Trust Policy와 Permission Policy 둘 다 통과해야 한다는 점이 자주 헷갈리는 부분이다.

Role 사용 시나리오Trust Policy의 Principal
EC2 인스턴스 프로파일ec2.amazonaws.com (Service)
Lambda 실행 역할lambda.amazonaws.com (Service)
Cross-Account 접근arn:aws:iam::123456789012:root (다른 계정)
Federation (SAML, OIDC)arn:aws:iam::...:saml-provider/...
AWS Identity Centersso.amazonaws.com

💡 암기 팁: User는 "장기 자격증명을 가진 사람", Role은 "임시 자격증명을 발급해주는 권한 묶음". 시험 시나리오에 **"EC2 인스턴스가 S3에 접근"**이 보이면 99% Role 답. **"키를 코드에 하드코딩"**이 보이면 절대 정답이 아니다.

Policy: JSON으로 표현된 권한의 명세서

Policy는 권한을 JSON으로 적은 문서다. Effect / Action / Resource / Condition / Principal 5개 필드가 핵심이다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::my-bucket/users/${aws:username}/*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": "ap-northeast-2"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

이 정책은 "MFA 인증되고 서울 리전 요청일 때만, 자기 사용자명에 해당하는 S3 prefix에서 GET/PUT 허용"이라는 의미다. ${aws:username}은 policy variable로, 평가 시점에 호출자의 사용자명으로 치환된다. 이게 ABAC의 핵심 메커니즘이다.

Policy 종류어디에 붙는가평가 우선순위
Identity-basedUser / Group / Role표준 평가
Resource-basedS3 bucket, SQS queue, Lambda 등Identity와 합집합
Permission BoundaryUser / Role상한선 (cap)
SCP (Service Control Policy)OU / Account (Organizations)절대 상한선
Session PolicyAssumeRole 시점그 세션에만 적용

🔍 더 깊이: AWS IAM 평가 로직은 명확한 우선순위가 있다. (1) Explicit Deny가 있으면 무조건 거부(가장 강력). (2) SCP(Organizations 수준)에 Allow가 없으면 거부. (3) Permission Boundary가 있고 그 안에 Allow가 없으면 거부. (4) Identity-based 또는 Resource-based 정책에 Allow가 있어야 허용. 즉 **"Allow는 합집합으로 추가되지만, Deny는 어느 한 곳이라도 있으면 즉시 차단"**이라는 비대칭성이 핵심이다. 이 비대칭 때문에 SCP는 "절대 못 하게 만들기"에 적합하다(예: root user의 액션 차단, 특정 리전 사용 금지).

⚠️ 함정: "Resource": "*"와 "Action": "*"가 같이 있는 정책은 거의 항상 AdministratorAccess 수준이다. CloudFormation 템플릿이나 SAM 정의에서 개발자가 "권한 문제 빨리 해결하려고" 이런 정책을 박는 경우가 흔한데, IAM Access Analyzer가 이걸 감지하고 알림을 보낸다. 시험에서도 "least privilege" 키워드가 보이면 * 정책은 거의 항상 오답이다.

📚 사례: 2017년 Verizon의 DCS(데이터 통합 회사) 협력업체 NICE Systems가 S3 버킷 공개 설정으로 1,400만 명의 통화 기록을 노출시켰다. 버킷 정책에 "Principal": "*"와 "Effect": "Allow"가 같이 있었다. 이 사고 이후 AWS는 (1) 모든 신규 버킷에 Block Public Access 기본 활성화, (2) S3 콘솔에 공개 버킷 빨간 경고 배지, (3) IAM Access Analyzer(2019년 12월 출시)로 외부에 노출된 리소스 자동 탐지 등 일련의 안전장치를 추가했다.

Identity-based vs Resource-based: 같은 권한을 두 방향에서

같은 "Alice가 my-bucket에 PutObject 가능"을 두 방법으로 표현할 수 있다.

// Identity-based (Alice의 User에 attach)
{
  "Effect": "Allow",
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::my-bucket/*"
}
 
// Resource-based (my-bucket의 Bucket Policy)
{
  "Effect": "Allow",
  "Principal": {"AWS": "arn:aws:iam::123456789012:user/Alice"},
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::my-bucket/*"
}

차이는 cross-account 시나리오에서 드러난다. 같은 계정 안이라면 둘 중 하나만 있으면 충분하지만, 다른 계정의 Alice에게 권한을 줄 때는 양쪽 모두 있어야 한다. 우리 계정의 bucket policy로 Alice를 허용하고, Alice의 계정에서도 Alice의 User에 우리 버킷 접근을 허용해야 한다. 한쪽만 있으면 cross-account에선 거부된다.

S3·KMS·SQS·SNS·Lambda·Secrets Manager·ECR 등이 Resource-based policy를 지원한다. DynamoDB·EBS·CloudWatch 같은 서비스는 지원하지 않으므로 cross-account 접근을 위해선 항상 IAM Role을 거쳐야 한다.

Permission Boundary와 SCP: 권한의 상한선

큰 조직에서 자주 쓰는 두 가지 안전장치다. Permission Boundary는 IAM User/Role의 권한 상한선을 정한다. Identity-based policy로 AdministratorAccess가 붙어도, Permission Boundary가 ReadOnlyAccess라면 실제 효과는 ReadOnly다.

SCP(Service Control Policy)는 AWS Organizations의 OU/Account 수준에서 절대 상한선을 정한다. SCP가 "us-east-1, us-west-2 외 리전 거부"라면, 그 OU 안의 어떤 사용자/역할도 다른 리전에서 동작할 수 없다. SCP는 권한을 부여하지 않고 제한만 한다(deny-only filter라고 생각하면 정확).

💡 암기 팁: SCP는 회사 차원의 헌법, Permission Boundary는 개인의 신분증, Identity-based policy는 실제 활동 권한. 어느 하나가 차단하면 활동 불가.

CLI로 권한 시뮬레이션

aws iam simulate-principal-policy는 시험엔 잘 안 나오지만 실무에서 디버깅에 황금이다.

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/path/to/file.txt

응답에 EvalDecision: allowed | explicitDeny | implicitDeny가 나온다. implicitDeny는 "어디서도 명시적으로 Allow를 안 줬다"는 뜻이고, explicitDeny는 "어딘가에 Deny가 있다"는 뜻이다. 후자는 SCP나 Permission Boundary나 Resource Policy를 살펴야 한다.

정리하며

오늘 본 네 부품은 클라우드 권한 모델의 ABC다. User는 사람의 장기 자격증명, Group은 권한 묶음의 단위, Role은 누구든 assume해서 임시 자격증명을 받는 권한 보관소, Policy는 JSON으로 표현된 권한의 명세서. 이 네 가지가 IAM 평가 엔진의 입력이 되고, 엔진은 SCP → Permission Boundary → Identity-based → Resource-based → Session Policy 순서로 평가해 결과를 낸다.

다음 글에서는 이 위에 올라가는 STS(임시 자격증명 발급소), 정책 조건(Condition), Resource-based policy의 cross-account 패턴을 깊이 본다. Capital One 사고가 IMDSv1에서 IAM Role 자격증명이 새어나간 사건이었다는 점을 떠올리면, IAM 심화가 단지 이론이 아니라 실제 사고 방지의 핵심임이 분명해진다.

📝 연습 문제

선택지를 클릭하면 정답·해설이 펼쳐집니다.

문제 1

한 개발자가 EC2 인스턴스에서 S3에 접근하려고 한다. 가장 안전한 방법은?

문제 2

다음 정책 평가 결과를 예측하라. Identity-based policy에 `s3:GetObject` Allow가 있고, SCP에 `s3:*` Deny가 있다.

문제 3

다음 중 IAM Role을 사용해야 하는 시나리오가 아닌 것은?

문제 4

한 회사가 모든 개발자에게 AdministratorAccess를 주고 싶지만 us-east-1과 ap-northeast-2 외 리전은 못 쓰게 하고 싶다. 가장 적합한 도구는?

문제 5

Cross-Account 시나리오: 계정 A의 Alice가 계정 B의 my-bucket에 접근해야 한다. 필요한 설정은?

문제 6

Permission Boundary와 Identity-based policy의 관계로 옳은 것은?

문제 7

한 개발자가 "코드가 ValidationException과 함께 'Cross-account pass role is not allowed'을 반환한다"고 호소한다. 가장 가능성 높은 원인은?

이전개발자 시점에서 본 AWS: 리전, 인프라, 그리고 책임의 경계Week 1 · Day 1다음 STS와 정책 조건: 임시 자격증명의 깊은 세계Week 1 · Day 3

이 페이지

  • 왜 클라우드는 새로운 권한 모델이 필요했을까
  • User: 사람이거나, 사람처럼 행동하는 시스템
  • Group: 권한 묶음의 단위
  • Role: 임시 자격증명의 생산자
  • Policy: JSON으로 표현된 권한의 명세서
  • Identity-based vs Resource-based: 같은 권한을 두 방향에서
  • Permission Boundary와 SCP: 권한의 상한선
  • CLI로 권한 시뮬레이션
  • 정리하며
  • 연습 문제