AWS IAM Identity Center でタグおよびアカウントIDをもとに権限制御する許可セットの例

## はじめに
AWS IAM Identity Center で管理する AWS アカウントが増えてくると、アクセス制御設定を行う管理者の作業負荷も高くなっていきます。この設定権限を各アカウントの管理者に委任したいケースがあります。

一例として IAM Identity Center のアクションをタグおよびアカウント ID の条件ベースで許可するポリシーを付与した Permission Set を作成し、操作を委任するアカウント管理者に割り当てる方法があります。これにより委任対象のアカウント管理者が管理していないアカウントに対するアクセス設定を拒否できます。

## 許可セットの CloudFormation テンプレート例
以下はアカウントID: 123456789012 に対するアクションを許可することを想定した場合の例です。

```template.yaml
Parameters: 
  pAwsSsoInsanceArn: 
    Type: String
    Default: arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx
    Description: Your IAM Identity Center Instance ARN.

Resources:
  rPermissionSetSandboxSSOAdmin:
    Type: AWS::SSO::PermissionSet
    Properties:
      InstanceArn: !Ref pAwsSsoInstanceArn
      Name: Sandbox-SSOAdmin
      Description: "Sandbox Account SSO Administrator"
      ManagedPolicies:
        - arn:aws:iam::aws:policy/AWSSSOReadOnly
        - arn:aws:iam::aws:policy/AWSSSODirectoryReadOnly
      RelayStateType: https://us-east-1.console.aws.amazon.com/iamv2/home?region=ap-northeast-1#/organization/accounts/details/123456789012?section=users
      SessionDuration: "PT2H"
      Tags:
        - Key: "PermissionSetType"
          Value: "SSOAdmin"
      InlinePolicy:
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "AllowSsoInstance",
                    "Effect": "Allow",
                    "Action": [
                        "sso:ProvisionPermissionSet",
                        "sso:CreateAccountAssignment",
                        "sso:DeleteAccountAssignment",
                        "sso:CreatePermissionSet",
                        "sso:DeletePermissionSet",
                        "sso:UpdatePermissionSet",
                        "sso:AttachManagedPolicyToPermissionSet",
                        "sso:DetachManagedPolicyFromPermissionSet",
                        "sso:AttachCustomerManagedPolicyReferenceToPermissionSet",
                        "sso:DetachCustomerManagedPolicyReferenceFromPermissionSet",
                        "sso:DeletePermissionsBoundaryFromPermissionSet",
                        "sso:PutPermissionsBoundaryToPermissionSet",
                        "sso:DeleteInlinePolicyFromPermissionSet",
                        "sso:PutInlinePolicyToPermissionSet",
                        "sso:TagResource"
                    ],
                    "Resource": [
                        "arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx",
                        "arn:aws:sso:::account/123456789012"
                    ]
                },
                {
                    "Sid": "AllowAccountAssignment",
                    "Effect": "Allow",
                    "Action": [
                        "sso:ProvisionPermissionSet",
                        "sso:CreateAccountAssignment",
                        "sso:DeleteAccountAssignment"
                    ],
                    "Resource": "arn:aws:sso:::permissionSet/*/*",
                    "Condition": {
                        "StringNotEquals": {
                            "aws:ResourceTag/PermissionSetType": [
                                "Management",
                                "SSOAdmin"
                            ]
                        }
                    }
                },
                {
                    "Sid": "AlloWritePermissionSet",
                    "Effect": "Allow",
                    "Action": [
                        "sso:CreatePermissionSet",
                        "sso:DeletePermissionSet",
                        "sso:UpdatePermissionSet",
                        "sso:AttachManagedPolicyToPermissionSet",
                        "sso:DetachManagedPolicyFromPermissionSet",
                        "sso:AttachCustomerManagedPolicyReferenceToPermissionSet",
                        "sso:DetachCustomerManagedPolicyReferenceFromPermissionSet",
                        "sso:DeletePermissionsBoundaryFromPermissionSet",
                        "sso:PutPermissionsBoundaryToPermissionSet",
                        "sso:DeleteInlinePolicyFromPermissionSet",
                        "sso:PutInlinePolicyToPermissionSet",
                        "sso:TagResource"
                    ],
                    "Resource": "arn:aws:sso:::permissionSet/*/*",
                    "Condition": {
                        "StringNotEquals": {
                            "aws:ResourceTag/PermissionSetType": [
                                "Share",
                                "Management",
                                "SSOAdmin"
                            ]
                        }
                    }
                }
            ]
        }
```

## インラインポリシーの解説
次のポリシーでは以下のアクションを許可します。

* IAM Identity Center インスタンスに対する許可セットの作成や編集、削除
* 指定したアカウント ID にのみ許可セットのプロビジョニングやアカウント割り当て/削除を許可
    * 複数アカウントに対するオペレーションを許可したい場合、Resource 句に ARN を追加

```json
                {
                    "Sid": "AllowSsoInstance",
                    "Effect": "Allow",
                    "Action": [
                        "sso:ProvisionPermissionSet",
                        "sso:CreateAccountAssignment",
                        "sso:DeleteAccountAssignment",
                        "sso:CreatePermissionSet",
                        "sso:DeletePermissionSet",
                        "sso:UpdatePermissionSet",
                        "sso:AttachManagedPolicyToPermissionSet",
                        "sso:DetachManagedPolicyFromPermissionSet",
                        "sso:AttachCustomerManagedPolicyReferenceToPermissionSet",
                        "sso:DetachCustomerManagedPolicyReferenceFromPermissionSet",
                        "sso:DeletePermissionsBoundaryFromPermissionSet",
                        "sso:PutPermissionsBoundaryToPermissionSet",
                        "sso:DeleteInlinePolicyFromPermissionSet",
                        "sso:PutInlinePolicyToPermissionSet",
                        "sso:TagResource"
                    ],
                    "Resource": [
                        "arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx",
                        "arn:aws:sso:::account/123456789012"
                    ]
                }
```


次のポリシーでは以下のアクションを許可します。

* 特定のタグが設定されていない許可セットのみ、プロビジョニングや作成/削除を許可する

この例ではこの許可セット (Sandbox-SSOAdmin) が一般ユーザーに割り当てられることを防ぐため、`PermissionSetType: SSOAdmin` というタグを付与しています。この許可セットで操作する管理者が、一般ユーザーに同じ許可セットを割り当てようとしても操作が拒否されます。

```json
                {
                    "Sid": "AllowAccountAssignment",
                    "Effect": "Allow",
                    "Action": [
                        "sso:ProvisionPermissionSet",
                        "sso:CreateAccountAssignment",
                        "sso:DeleteAccountAssignment"
                    ],
                    "Resource": "arn:aws:sso:::permissionSet/*/*",
                    "Condition": {
                        "StringNotEquals": {
                            "aws:ResourceTag/PermissionSetType": [
                                "Management",
                                "SSOAdmin"
                            ]
                        }
                    }
                },
```

次のポリシーは以下のアクションを許可します。

* 特定のタグが設定されていない許可セットのみ、許可セットの作成、編集、削除を許可する

この例では、アカウント管理者用の許可セットや、職務別の許可セットなど組織で共用している許可セットに対する変更を防ぐため、`PermissionSetType` タグを条件にしています。
 

```json
                {
                    "Sid": "AlloWritePermissionSet",
                    "Effect": "Allow",
                    "Action": [
                        "sso:CreatePermissionSet",
                        "sso:DeletePermissionSet",
                        "sso:UpdatePermissionSet",
                        "sso:AttachManagedPolicyToPermissionSet",
                        "sso:DetachManagedPolicyFromPermissionSet",
                        "sso:AttachCustomerManagedPolicyReferenceToPermissionSet",
                        "sso:DetachCustomerManagedPolicyReferenceFromPermissionSet",
                        "sso:DeletePermissionsBoundaryFromPermissionSet",
                        "sso:PutPermissionsBoundaryToPermissionSet",
                        "sso:DeleteInlinePolicyFromPermissionSet",
                        "sso:PutInlinePolicyToPermissionSet",
                        "sso:TagResource"
                    ],
                    "Resource": "arn:aws:sso:::permissionSet/*/*",
                    "Condition": {
                        "StringNotEquals": {
                            "aws:ResourceTag/PermissionSetType": [
                                "Share",
                                "Management",
                                "SSOAdmin"
                            ]
                        }
                    }
                }
```


## 参考: 過去記事
https://qiita.com/hayao_k/items/9c824241eb1c83fc9dd5

https://qiita.com/hayao_k/items/9a625bde0ac5c00d6517

以上です。参考になれば幸いです。