IAM, Identity and Access Management


  • IAM 이란 AWS Resources 접근 권한을 관리하는 Global Service 이다.
  • Root Account 는 AWS 계정 생성 시에 기본으로 생성되고 AWS 계정 생성에만 사용한다.
  • 처음 AWS 계정 생성하고 Amazon IAM 에 기본적으로 생성되는 리소스는 아래와 같다.
    • User: 0 개
    • User Group: 0개
    • Roles: AWS 가 자동으로 만드는 SLR, Service-linked role 이 기본적으로 포함되어 있음
    • Policies: AWS managed policy 가 기본적으로 포함되어 있음
    • Identity providers: 0개, SAML/OIDC IdP 는 사용자가 수동 등록

IAM Users & User Groups


  • User 는 하나의 조직 내 사용자에 해당하며 필요하다면 Group 으로 묶을 수 있음
    • User 는 0~10개의 Group 에 속할 수 있음
  • Group 은 User 만을 포함할 수 있으며 Group 을 포함하는 것은 불가능
  • 최소 권한 원칙을 바탕으로 AWS 를 사용하게끔 하기 위해서 IAM User 와 Group 을 사용
  • User 또는 Group 은 JSON 형식으로 이루어진 IAM Policy 를 할당 받을 수 있음

IAM User 생성

  • AWS Management Console 에서 IAM -> Users -> Create user

  • Provide user access to the AWS Management Console 활성화를 통해 User 에게 AWS Management Console 이용 권한 부여
  • Console password 를 Custom password 로 설정해서 User 생성
    • 타인을 위한 IAM User 생성 시 Autogenerated password + User must create a new password at next sign-in 으로 비밀번호 재설정 의무화

  • Create group 으로 User 가 속할 Group 을 만들면서 동시에 Permission policies 까지 할당

  • 마지막 Review 후 Create user 클릭 시 User 생성 완료

  • Users 로 다시 돌아와보면 User 가 성공적으로 생성되어있는 것을 확인 가능

IAM User Access Key for AWS CLI

  • AWS Management Console 에서 IAM -> Users -> User 선택 -> Security credentials 탭 -> Access keys 에서 Create access key

  • CLI 선택후 마지막 화면이 Access Key 와 Secret Access Key 를 저장할 수 있는 유일한 시간
$ aws configure
AWS Access Key ID [None]: ACCESS_KEY
AWS Secret Access Key [None]: SECRET_ACCESS_KEY
Default region name [None]: ap-east-1
Default output format [None]:
  • aws configure 명령어 입력 후 위와 같이 설정하면 CLI 로 AWS API 를 사용 가능
  • 단, EC2 인스턴스와 같이 타인이 접속할 수 있는 머신에서 이 방법을 쓰면 타인이 인스턴스에 입력된 자격 증명 정보를 회수할 수 있기 때문에 best practice 가 아님
  • 따라서 EC2 에서 AWS API 를 사용하길 원할 경우 IAM Role 을 지정하는게 best practice

IAM Policies


  • IAM Policy is a JSON document that allows or denies permissions to AWS resources
    • Follow the security principle of least privilege when granting permissions
    • IAM Policy can be assigned to User Groups or User itself with inline-policy

IAM Policies Structure

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GenerateCredentialReport",
                "iam:GenerateServiceLastAccessedDetails",
                "iam:Get*",
                "iam:List*",
                "iam:SimulateCustomPolicy",
                "iam:SimulatePrincipalPolicy"
            ],
            "Resource": "*"
        }
    ]
}
  • Version: 정책 언어 버전 (Optional, 항상 2012-10-17 명시 권장)
    • 생략하면 policy variables 등 최신 문법을 사용할 수 없음
    • 2008-10-17 은 구버전이며 신규 정책에 사용하지 않음
    • Managed Policy 의 버전(v1, v2 …)과는 전혀 다른 개념
  • Id: 정책 식별자 (Optional)
    • SQS, SNS 등 일부 서비스는 필수이며 고유성을 요구
  • Statement: 하나 이상의 개별 statement (Required)
    • Sid: statement 식별자 (Optional)
    • Effect: Allow 또는 Deny (Required, default 없음)
    • Principal: 이 정책이 적용되는 대상 (Account/User/Role) (Required in some circumstances)
      • Resource-based policy 에서는 필수
      • Identity-based policy 에는 쓸 수 없음, attach 된 principal 이 곧 대상으로 암시(implied)되기 때문
    • Action: 정책이 허용하거나 거부하는 action 목록 (Required)
    • Resource: action 이 적용되는 리소스 목록 (Required in some circumstances)
      • Identity-based policy 에서는 필수
      • Resource-based policy 에서는 리소스에 따라 다름, S3 Bucket Policy 는 필수이고 Role Trust Policy 는 사용하지 않음
      • 리소스 단위 지정을 지원하지 않는 action 은 * 를 사용
    • Condition: 정책이 적용되는 조건 (Optional)
  • Action/NotAction, Principal/NotPrincipal, Resource/NotResource 는 각각 상호 배타적이라 한 statement 에 함께 쓸 수 없음
  • Statement: Effect Principal to Action on Resource when Condition 의 논리인 셈

IAM Policies 종류

  • Identity-based policies: IAM Users, IAM User Groups, IAM Roles 에 적용하는 Policy
    • Managed Policy: 독립된 IAM 객체로 ARN 을 가진다
      • 여러 principal 에 attach 가능하고 버전 관리가 됨 (최대 5개, 그중 하나가 default version)
      • AWS Managed Policy: AWS 에서 기본으로 제공하는 Policy, 여러 계정에서 동일한 Policy 사용 가능
        • e.g. arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
      • Customer Managed Policy: 사용자가 생성한 Custom Policy, 해당 Policy 가 생성된 계정만 사용 가능
        • e.g. arn:aws:iam::123456789012:policy/MyCustomPolicy
    • Inline Policy: 특정 principal(user/group/role) 하나에 embed 되어 있다. ARN 이 없다
      • 명시적으로 할당하는 1대1 Policy, principal 을 삭제하면 함께 사라짐
      • 버전 관리가 없으며 재사용 불가
      • 보통 Managed 를 사용하길 권장
      • 명시적으로 특정 사용자에게 특정 권한을 부여하고 싶을 경우에 사용하면 유용
  • Resource-based policies: AWS Resource 에 적용하는 Policy, 대표적으로 S3 Bucket Policy 가 있음
    • 항상 inline 이며 managed resource-based policy 는 존재하지 않음
    • 정책이 리소스에 붙어 있으므로 Principal 이 필수
    • IAM Role 의 Trust Policy (AssumeRolePolicyDocument) 도 resource-based policy 이며, 누가 이 Role 을 assume 할 수 있는지를 정의
      • IAM 이 지원하는 유일한 resource-based policy
      • Role 은 identity 이면서 동시에 resource 이므로 Trust Policy 와 identity-based policy 를 모두 가짐
  • Permissions boundaries: IAM entity 가 가질 수 있는 권한의 상한선을 정하는 managed policy
    • 자체로는 권한을 부여하지 않으며, identity-based policy 와의 교집합만 유효
  • Organizations SCPs: Organization 의 OU/계정에 적용하는 principal 중심 guardrail
    • 멤버 계정의 IAM principal 이 가질 수 있는 최대 권한을 제한
    • 권한을 부여하지 않으며, management 계정에는 적용되지 않음
  • Organizations RCPs: 멤버 계정의 리소스에 적용하는 resource 중심 guardrail
    • 주로 Organization 외부 principal 의 리소스 접근을 차단하는 데 사용
    • SCP 와 마찬가지로 권한을 부여하지 않음
  • Access control lists - ACLs: 다른 계정의 principal 이 리소스에 접근할 수 있는지를 제어, S3, WAF, VPC 등이 지원
    • JSON policy 언어를 사용하지 않는 유일한 policy 타입
    • 같은 계정 내 principal 에 대한 접근 제어에는 사용할 수 없음
  • Session policies: AssumeRole 등으로 임시 세션 생성 시 파라미터로 전달하는 Policy
    • 해당 세션에 한해 권한을 좁히며, Role 의 권한과의 교집합만 유효

IAM Roles


  • IAM Role 은 AWS Services 를 위한 IAM User 라고 생각할 수 있음
  • An identity that you can assume to gain temporary access to permissions
  • Ideal for situations in which access to services or resources needs to be granted temporarily, instead of long-term
  • To grant users in one AWS account access to resources in another AWS account
  • IAM Users 의 권한을 쉽게 관리하기 위해 IAM User Groups 를 사용하는데, 권한이 다양해지면 관리가 복잡해지고 이를 해결하기 위해 IAM Roles 를 사용
  • User Group 에 권한을 바로 부여하는 대신, Role 을 만들고 User 또는 User Group 에 할당
    • 임시 세션토큰을 발급하여 일시적인 권한을 위임

Trust Policy

  • Role 은 두 종류의 Policy 를 동시에 가짐
    • Permission policy (identity-based): 이 Role 이 무엇을 할 수 있는가
    • Trust policy (resource-based): 누가 이 Role 을 assume 할 수 있는가
  • Trust policy 는 Role 의 AssumeRolePolicyDocument 속성으로 저장되며 GetRole 로만 조회 가능
    • ListAttachedRolePoliciesListRolePolicies 는 permission policy 만 반환하므로 Role 감사 시 GetRole 이 필요
  • Role 자신이 곧 리소스이므로 Resource 를 쓰지 않고, action 은 sts:AssumeRole 을 지정
  • Principaltype
    • AWS: 다른 계정 또는 같은 계정의 IAM User/Role
    • Service: AWS 서비스 (e.g. ec2.amazonaws.com, lambda.amazonaws.com)
    • Federated: SAML/OIDC IdP (e.g. EKS IRSA, GitHub Actions OIDC)

Terraform Code 예시

# AssumeRolePolicyDocument (trust policy). aws_iam_role.assume_role_policy 의 인자
data "aws_iam_policy_document" "trust" {
  statement {
    sid     = "TrustRelationship"
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
 
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::XXXXXXXXXXXX:role/staff-aws-audit-org-read-role"]
    }
    # resources 없음 — 아래 Role 자신이 리소스
  }
}
 
resource "aws_iam_role" "audit" {
  name               = "system-aws-audit-iam-read-role"
  assume_role_policy = data.aws_iam_policy_document.trust.json  # Required
}
 
# AttachedManagedPolicies 중 AWS Managed. "aws_iam_role_policy_attachment" (ARN 참조만)
resource "aws_iam_role_policy_attachment" "security_audit" {
  role       = aws_iam_role.audit.name
  policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
}
 
# AttachedManagedPolicies 중 Customer Managed. "aws_iam_policy" 로 객체 생성 후 attach
data "aws_iam_policy_document" "iam_read" {
  statement {
    sid       = "IAMReadAccess"
    effect    = "Allow"
    actions   = ["iam:ListRoles", "iam:ListUsers", "iam:ListPolicies"]
    resources = ["*"]
    # principals 없음 — attach 되는 Role 이 곧 principal
  }
}
 
resource "aws_iam_policy" "iam_read" {
  name   = "system-aws-audit-iam-read-policy"
  policy = data.aws_iam_policy_document.iam_read.json
  # arn:aws:iam::111122223333:policy/system-aws-audit-iam-read-policy
}
 
resource "aws_iam_role_policy_attachment" "iam_read" {
  role       = aws_iam_role.audit.name
  policy_arn = aws_iam_policy.iam_read.arn
}
 
# RolePolicyList (inline policies). "aws_iam_role_policy" (Role 에 직접 embed, ARN 없음)
data "aws_iam_policy_document" "deny_self_modify" {
  statement {
    sid       = "DenySelfModification"
    effect    = "Deny"
    actions   = ["iam:*"]
    resources = [aws_iam_role.audit.arn]
  }
}
 
resource "aws_iam_role_policy" "deny_self_modify" {
  name   = "deny-self-modification"
  role   = aws_iam_role.audit.id
  policy = data.aws_iam_policy_document.deny_self_modify.json
}

IAM Security Tools


IAM Credential Reports (account-level)

  • AWS Management Console 에서 IAM -> Credential report -> Download Report
  • A report that lists all account’s users and the status of their various credentials

IAM Access Advisor (user-level)

  • AWS Management Console 에서 IAM -> Users -> User 선택 -> Access Advisor 탭
  • 어떤 AWS Services 에 마지막으로 접근했는지 확인 가능
    • 접근하지 않는 Resources 는 제한하여 principle of least privilege 를 지킬 수 있음

IAM 권한 검증 절차


IAM User 가 S3 를 사용하고 싶은 경우

  1. IAM User 에게 S3 사용 Policy 가 부여되었는가?
  2. IAM User 가 속한 IAM User Group 에 S3 사용 Policy 가 부여되었는가?
  3. IAM User 에게 위임된 Role 에 S3 사용 Policy 가 부여되었는가?
  4. OK 또는 Fail

Lambda 가 S3 를 이용하고 싶은 경우

  1. Lambda 에 S3 사용 Role 이 부여되었는가?
  2. OK 또는 Fail
  • IAM Access Analyzer
    • Identifies whether an Amazon S3 bucket or an IAM role has been shared with an external entity such as another AWS account
    • Checks access policies and offers actionable recommendations to help users set secure and functional policies
  • IAM Credential Report
    • To audit its password and access key rotation details for compliance purposes
  • AWS Security Token Service (STS)
    • To request temporary, limited-privilege credentials for users

IAM Conditions


aws:SourceIp

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
	            "NotIpAddress": {
		            "aws:SourceIp": [
			            "192.0.2.0/24",
			            "203.0.113.0/24"
		            ]
	            }
            }
        }
    ]
}
  • Restrict the client IP from which the API calls are being made

aws:RequestedRegion

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
	            "StringEquals": {
		            "aws:RequestedRegion": [
			            "eu-central-1",
			            "eu-west-1"
		            ]
	            }
            }
        }
    ]
}
  • Restrict the Region the API calls are made to

ec2:ResourceTag

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*",
            "Condition": {
	            "StringEquals": {
		            "aws:ResourceTag/Project": "DataAnalytics"
	            }
            }
        }
    ]
}
  • Restrict based on tags

aws:MultiFactorAuthPresent

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
	            "BoolIfExists": {
		            "aws:MultiFactorAuthPresent": false
	            }
            }
        }
    ]
}
  • To force MFA

IAM for S3


  • s3:ListBucket permission applies to arn:aws:s3:::test
    • Bucket level permission
  • s3:GetObject permission applies to arn:aws:s3:::test/*
    • Object level permission

Resource Policies & aws:PrincipalOrgID


  • aws:PrincipalOrgID can be used in any resource policies to restrict access to accounts that are members of an AWS Organization

IAM Role vs Resource-Based Policies


  • In Cross-Account situation
    • Resource-Based Policy can be attached to a resource (e.g. S3 bucket policy)
    • OR use a Role as a proxy
  • When using Assume Role, original permissions will not work
  • When using Resource-Based Policy, resource allows given permissions

Amazon EventBridge - Security

  • When a rule runs, it needs permissions on the target
    • Resource-Based Policy: Lambda, SNS, SQS, CloudWatch Logs, API Gateway, …
    • IAM Role: Kinesis Stream, Systems Manager Run Command, ECS task, …

IAM Permission Boundaries


  • IAM Permission Boundaries are supported for users and roles (not group)
  • Advanced feature to use a managed policy to set the maximum permissions an IAM entity can get
  • Can be used in combinations of AWS Org SCP

References