정책 템플릿
정책 템플릿 (Policy templates)
정책 템플릿은 파트너가 고객의 계정에서 요청하는 임시 권한을 정의하기 위해 설계된 새로운 IAM 구조예요. 일반 IAM 정책처럼 Effect, Action, Resource, Condition 요소가 있는 구문으로 권한을 정의해요. 핵심 차이는 정책 템플릿이 위임 요청을 만들 때 실제 값으로 대체되는 파라미터(예: @{bucketName})를 포함한다는 점이에요.
출처: 문서
본문
정책 템플릿의 동작 원리
온보딩 절차의 일부로 정책 템플릿을 AWS에 등록해요. AWS는 각 템플릿에 위임 요청을 만들 때 참조하는 고유한 ARN을 할당해요.
위임 요청을 만들 때 다음을 지정해요.
- 정책 템플릿 ARN
- 템플릿에 대체할 파라미터 값
AWS는 템플릿과 파라미터 값을 결합해 표준 IAM 정책을 생성해요. 고객은 위임 요청을 승인할 때 이 최종 렌더링된 정책을 검토하며, 어떤 권한이 부여될지 정확히 보게 돼요.
참고
최종 렌더링된 정책에는 최대 2048자의 크기 제한이 있어요.
템플릿 대체가 어떻게 작동하는지 보여주는 간단한 예시예요.
정책 템플릿:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::@{bucketName}/*"
}
]
}
위임 요청에서 제공된 파라미터:
{
"Name": "bucketName",
"Values": ["customer-data-bucket"],
"Type": "String"
}
최종 렌더링된 정책 (고객이 보는 것):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::customer-data-bucket/*"
}
]
}
템플릿 문법
정책 템플릿은 유연성을 제공하기 위해 두 가지 핵심 기능을 사용해요: 파라미터 대체(parameter substitution) 와 조건부 구문(conditional statements). 파라미터 대체를 사용하면 템플릿에서 위임 요청을 만들 때 실제 값으로 대체되는 자리 표시자를 정의할 수 있어요. 조건부 구문을 사용하면 파라미터 값에 따라 전체 정책 구문을 포함하거나 제외할 수 있어요.
파라미터 대체 및 유형
정책 템플릿에서 파라미터를 정의하려면 @{parameterName} 문법을 사용해요. 위임 요청을 만들 때 각 파라미터의 유형을 지정해야 해요.
-
String — 템플릿에 직접 대체되는 단일 값입니다.
- 템플릿:
"Resource": "arn:aws:s3:::@{bucketName}/*" - 파라미터:
{"Name": "bucketName", "Values": ["my-bucket"], "Type": "String"} - 렌더링 결과:
"Resource": "arn:aws:s3:::my-bucket/*"
- 템플릿:
-
StringList — 여러 리소스 항목을 생성하는 여러 값입니다. StringList 파라미터가 리소스 ARN에서 사용되면 각 값에 대해 별도의 리소스 항목을 만들도록 확장됩니다.
- 템플릿:
"Resource": "arn:aws:s3:::@{bucketNames}/*" - 파라미터:
{"Name": "bucketNames", "Values": ["bucket-1", "bucket-2"], "Type": "StringList"} - 렌더링 결과:
"Resource": [ "arn:aws:s3:::bucket-1/*", "arn:aws:s3:::bucket-2/*" ]
- 템플릿:
-
교차 곱 동작 (Cross-Product Behavior) — 같은 리소스 ARN에서 여러 파라미터가 사용될 때 StringList 파라미터는 모든 조합의 교차 곱을 만듭니다.
- 템플릿:
"Resource": "arn:aws:s3:::@{bucketNames}/@{prefix}/*" - 파라미터: bucketNames(StringList, ["bucket-1","bucket-2"]), prefix(String, ["data"])
- 렌더링 결과:
"Resource": [ "arn:aws:s3:::bucket-1/data/*", "arn:aws:s3:::bucket-2/data/*" ]
- 템플릿:
조건부 구문 (Conditional Statements)
@Enabled 지시어를 사용해 파라미터 값에 따라 전체 구문을 조건부로 포함하거나 제외할 수 있어요.
문법:
@Enabled: "parameterName"— 파라미터 값이"True"일 때 구문 포함@Enabled: "!parameterName"— 파라미터 값이"True"가 아닐 때 구문 포함(부정)
템플릿:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "*"
},
{
"@Enabled": "ENABLE_S3_WRITE",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::@{bucketName}/*"
}
]
}
ENABLE_S3_WRITE가 "True"일 때 파라미터:
[
{
"Name": "bucketName",
"Values": ["my-bucket"],
"Type": "String"
},
{
"Name": "ENABLE_S3_WRITE",
"Values": ["True"],
"Type": "String"
}
]
렌더링 결과 (두 구문 모두 포함):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
ENABLE_S3_WRITE가 "False"일 때 파라미터:
[
{
"Name": "bucketName",
"Values": ["my-bucket"],
"Type": "String"
},
{
"Name": "ENABLE_S3_WRITE",
"Values": ["False"],
"Type": "String"
}
]
렌더링 결과 (조건부 구문 제외):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "*"
}
]
}
ENABLE_S3_WRITE가 "True"로 설정되면 조건부 구문이 포함되고, "False"로 설정되면 구문이 렌더링된 정책에서 제외돼요.
추가 예시
다음 예시는 임시 위임에서 정책 템플릿을 사용하는 일반적인 패턴을 보여줘요. 장기 액세스를 위한 권한 경계가 있는 IAM 역할 생성에 초점을 맞추고, 특정 리소스로 권한을 범위 지정하는 다양한 전략을 보여줘요. ARN 접두사, 리소스 태깅, 권한 경계 업데이트 같은 기법으로 유연성과 보안의 균형을 맞추는 방법을 보여줘요.
예시 1: 특정 리소스에 장기 액세스 부여
다음 권한 경계가 "partner.com"용 "SQSAccessorBoundary"로 제출됩니다.
{
"Effect": "Allow",
"Action": [
"sqs:DeleteMessage",
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:*:*:*",
"Condition": {
"StringEquals": {
"aws:ResourceAccount": "${aws:PrincipalAccount}"
}
}
}
참고
이 경계는 열린 리소스 정책이 있는 다른 계정의 대기열에 액세스를 부여하지 않도록 같은 계정 조건을 포함해요. 경계가 모든 고객에 걸쳐 공유되고 템플릿화될 수 없으므로 고객의 계정 ID에 대한 직접 참조는 포함할 수 없어요.
이 정책은 첫 버전이므로 그 ARN은 arn:aws:iam::partner:policy/permissions-boundary/partner.com/SQSAccessorBoundary_2025_01_15 입니다.
임시 액세스 권한을 위해 제출된 정책 템플릿:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:ListQueues"
],
"Resource": "arn:aws:sqs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:PutRolePermissionsBoundary",
"iam:PutRolePolicy"
],
"Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::partner:policy/permissions-boundary/partner.com/SQSAccessorBoundary_2025_01_15"
}
}
}
]
}
예시 2: ARN 접두사 사용
권한 경계는 리소스 ARN 접두사를 지정해 액세스를 제한할 수 있어요.
"Resource": "arn:aws:sqs:*:@{AccountId}:PartnerPrefix*"
이렇게 하면 해당 접두사가 있는 리소스로만 액세스가 제한되어 액세스 가능한 리소스의 범위가 줄어들어요.
예시 3: 리소스 액세스 제어에 태그 사용
임시 위임 액세스 중에 리소스에 태그를 지정하고 장기 액세스 통제에 그 태그를 사용할 수 있어요.
태그된 리소스에 대한 액세스를 허용하는 권한 경계:
{
"Effect": "Allow",
"Action": [
"sqs:DeleteMessage",
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:*:*:*",
"Condition": {
"Null": {
"aws:ResourceTag/ManagedByPartnerDotCom": "false"
},
"StringEquals": {
"aws:ResourceAccount": "${aws:PrincipalAccount}"
}
}
}
생성 시 새 대기열에 태그를 지정하는 정책 템플릿:
{
"Effect": "Allow",
"Action": [
"sqs:CreateQueue",
"sqs:TagQueue"
],
"Resource": "arn:aws:sqs:*:*:*",
"Condition": {
"Null": {
"aws:RequestTag/ManagedByPartnerDotCom": "false"
}
}
}
기존 대기열에 태그를 지정하고 역할을 만드는 정책 템플릿:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:TagQueue"
],
"Resource": "arn:aws:sqs:*:@{AccountId}:@{QueueName}",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": "ManagedByPartnerDotCom"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:PutRolePermissionsBoundary",
"iam:PutRolePolicy"
],
"Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::partner:policy/permissions-boundary/partner.com/SQSAccessorBoundary_2025_01_15"
}
}
}
]
}
이 방식은 고객이 장기적으로 액세스할 수 있는 특정 리소스를 명시적으로 확인할 수 있게 해줘요.
예시 4: 권한 경계 업데이트
권한 경계를 업데이트하려면 새 날짜 접미사가 있는 새 버전을 등록하고 그것을 교체할 권한을 요청해요.
추가 권한이 있는 업데이트된 권한 경계:
{
"Effect": "Allow",
"Action": [
"sqs:DeleteMessage",
"sqs:PurgeQueue",
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:*:*:*",
"Condition": {
"StringEquals": {
"aws:ResourceAccount": "${aws:PrincipalAccount}"
}
}
}
이 정책은 두 번째 버전이므로 ARN은 arn:aws:iam::partner:policy/permissions-boundary/partner.com/SQSAccessorBoundary_2025_01_20 입니다.
기존 역할의 권한 경계를 업데이트하는 정책 템플릿:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:PutRolePermissionsBoundary"
],
"Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::partner:policy/permissions-boundary/partner.com/SQSAccessorBoundary_2025_01_20"
}
}
}
]
}
기존 역할의 권한 경계를 업데이트하려면 고객이 이 위임 요청을 승인해야 해요.