AWS: MFA 인증받은 IAM 사용자가 보안 자격 증명(Security credentials) 페이지에서 본인 자격 증명 관리하기
AWS: MFA 인증받은 IAM 사용자가 보안 자격 증명(Security credentials) 페이지에서 본인 자격 증명 관리하기
이 예시는 다중 인증(MFA)으로 인증한 IAM 사용자가 Security credentials 페이지에서 본인 자격 증명을 관리하도록 허용하는 자격 증명 기반 정책을 만드는 방법을 보여드려요. 이 콘솔 페이지에는 계정 ID, canonical user ID 같은 계정 정보가 표시되고, 사용자는 본인의 비밀번호·액세스 키·MFA 디바이스·X.509 인증서·SSH 키·Git 자격 증명을 보고 편집할 수 있어요.
이 정책은 AWS에서 다른 작업을 하기 전에 먼저 MFA를 설정하고 인증하도록 요구해요. MFA 없이 본인 자격 증명을 관리하게 하려면 AWS: Allows IAM users to manage their own credentials 문서를 참고하세요.
출처: 문서
본문
이 예시 정책에는 페이지의 모든 정보를 보고 편집하는 데 필요한 권한이 들어 있어요. 그리고 사용자가 다른 어떤 AWS 작업을 수행하기 전에 MFA를 설정하고 인증하게 해요.
참고 사항
- 이 예시 정책은 사용자가 AWS Management Console에 처음 로그인할 때 비밀번호를 리셋하는 것을 허용하지 않아요. 신규 사용자에게는 로그인을 한 뒤에 권한을 부여하는 것을 권장해요. 또한 비밀번호가 만료된 사용자가 로그인 중에 비밀번호를 리셋하지 못하게 해요. 이 기능을 허용하려면
iam:ChangePassword와iam:GetAccountPasswordPolicy액션을DenyAllExceptListedIfNoMFA스테이트먼트에 추가하면 돼요. 다만 MFA 없이 비밀번호를 바꾸는 것을 허용하는 건 보안상 위험할 수 있어 권장하지 않아요. - 이 정책을 프로그래매틱 액세스에 쓰려면 MFA로 인증하기 위해
GetSessionToken을 호출해야 해요.
이 정책이 하는 일
AllowViewAccountInfo 스테이트먼트는 계정 수준 정보를 볼 수 있게 해줘요. 이 권한들은 리소스 ARN을 지정하지 않는(또는 지정할 필요가 없는) 권한이라 별도의 스테이트먼트로 분리하며, 대신 "Resource" : "*"를 지정해요. 이 스테이트먼트가 허용하는 액션은 다음과 같아요.
GetAccountPasswordPolicy– 본인 IAM 사용자 비밀번호를 변경할 때 계정 비밀번호 요건을 볼 수 있어요.ListVirtualMFADevices– 사용자에게 활성화된 가상 MFA 디바이스에 대한 상세 정보를 볼 수 있어요.
AllowManageOwnPasswords 스테이트먼트는 본인 비밀번호를 변경할 수 있게 해줘요. 이 스테이트먼트는 My security credentials 페이지의 대부분 정보를 보는 데 필요한 GetUser 액션도 포함해요.
AllowManageOwnAccessKeys 스테이트먼트는 본인 액세스 키를 생성·업데이트·삭제할 수 있게 해줘요. 지정한 액세스 키가 마지막으로 사용된 시점에 대한 정보도 가져올 수 있어요.
AllowManageOwnSigningCertificates 스테이트먼트는 본인 서명 인증서를 업로드·업데이트·삭제할 수 있게 해줘요.
AllowManageOwnSSHPublicKeys 스테이트먼트는 CodeCommit용 본인 SSH 공개 키를 업로드·업데이트·삭제할 수 있게 해줘요.
AllowManageOwnGitCredentials 스테이트먼트는 CodeCommit용 본인 Git 자격 증명을 생성·업데이트·삭제할 수 있게 해줘요.
AllowManageOwnVirtualMFADevice 스테이트먼트는 본인 가상 MFA 디바이스를 생성할 수 있게 해줘요. 이 스테이트먼트의 리소스 ARN은 어떤 이름으로든 MFA 디바이스를 만들 수 있게 하지만, 정책의 다른 스테이트먼트들은 현재 로그인한 사용자에게만 디바이스를 연결하도록 허용해요.
AllowManageOwnUserMFA 스테이트먼트는 본인 사용자의 가상·U2F·하드웨어 MFA 디바이스를 보거나 관리할 수 있게 해줘요. 이 스테이트먼트의 리소스 ARN은 사용자 본인의 IAM 사용자에게만 액세스를 허용해요. 다른 사용자의 MFA 디바이스는 보거나 관리할 수 없어요.
DenyAllExceptListedIfNoMFA 스테이트먼트는 사용자가 MFA로 로그인하지 않은 경우, 나열된 몇 개 액션을 제외한 모든 AWS 서비스의 모든 액션에 대한 액세스를 거부해요. 이 스테이트먼트는 "Deny"와 "NotAction"을 조합해 나열되지 않은 모든 액션에 대한 액세스를 명시적으로 거부해요. 나열된 항목은 이 스테이트먼트로 거부되거나 허용되지 않지만, 다른 스테이트먼트에서 허용돼요. 이 논리에 대한 자세한 내용은 NotAction with Deny 문서를 참고하세요.
만약 사용자가 MFA로 로그인했다면 Condition 테스트가 실패해서 이 스테이트먼트는 어떤 액션도 거부하지 않아요. 이 경우 사용자에 대한 다른 정책이나 스테이트먼트가 사용자 권한을 결정해요. 이 스테이트먼트는 사용자가 MFA로 로그인하지 않았을 때 나열된 액션만 수행할 수 있게 보장해요. 그리고 나열된 액션도 다른 스테이트먼트나 정책이 허용할 때에만 수행할 수 있어요.
iam:ChangePassword 액션은 MFA 인증 없이 허용하면 안 되기 때문에, 이 정책은 사용자가 로그인 시에 비밀번호를 만드는 것을 허용하지 않아요. Bool 연산자의 ...IfExists 버전은 aws:MultiFactorAuthPresent 키가 없으면 조건이 true를 반환하게 해줘요. 즉 액세스 키 같은 장기 자격 증명으로 API에 접근하는 사용자는 IAM 외의 API 작업에 대한 액세스가 거부돼요.
이 정책은 IAM 콘솔의 Users 페이지를 보거나 그 페이지에서 본인 사용자 정보에 접근하는 것을 허용하지 않아요. 이 기능을 허용하려면 iam:ListUsers 액션을 AllowViewAccountInfo 스테이트먼트와 DenyAllExceptListedIfNoMFA 스테이트먼트에 추가하면 돼요. 또한 본인 사용자 페이지에서 비밀번호를 변경하는 것도 허용하지 않아요. 이 기능을 허용하려면 iam:GetLoginProfile과 iam:UpdateLoginProfile 액션을 AllowManageOwnPasswords 스테이트먼트에 추가하면 돼요. 사용자가 MFA로 로그인하지 않고 본인 사용자 페이지에서 비밀번호를 변경하게 하려면 iam:UpdateLoginProfile 액션을 DenyAllExceptListedIfNoMFA 스테이트먼트에도 추가하면 돼요.
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "AllowViewAccountInfo",
"Effect": "Allow",
"Action": [
"iam:GetAccountPasswordPolicy",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowManageOwnPasswords",
"Effect": "Allow",
"Action": [
"iam:ChangePassword",
"iam:GetUser"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"iam:UpdateAccessKey",
"iam:GetAccessKeyLastUsed"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnSigningCertificates",
"Effect": "Allow",
"Action": [
"iam:DeleteSigningCertificate",
"iam:ListSigningCertificates",
"iam:UpdateSigningCertificate",
"iam:UploadSigningCertificate"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnSSHPublicKeys",
"Effect": "Allow",
"Action": [
"iam:DeleteSSHPublicKey",
"iam:GetSSHPublicKey",
"iam:ListSSHPublicKeys",
"iam:UpdateSSHPublicKey",
"iam:UploadSSHPublicKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnGitCredentials",
"Effect": "Allow",
"Action": [
"iam:CreateServiceSpecificCredential",
"iam:DeleteServiceSpecificCredential",
"iam:ListServiceSpecificCredentials",
"iam:ResetServiceSpecificCredential",
"iam:UpdateServiceSpecificCredential"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/*"
},
{
"Sid": "AllowManageOwnUserMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}