【IAM】ABACで遊んで、ABACできる操作とできない操作を調べてみた！！

# ABACとは
以下の記事が**とても**わかりやすいです。

https://zenn.dev/jimatomo/articles/f75a60e9673cc9


失礼ですが、抜粋し超雑にまとめます。

> - RBAC(ABACの先輩)はRole-Based Access Controlの略で、ロール（人々のグループ）を中心に権限管理を行う仕組みです。
> - ABACはAttribute-Based Access Controlの略で、属性を中心に権限管理を行う仕組みです。
> - ABACの場合、RBACで付与された大まかな権限に加えて、操作先・操作元の属性値を使って追加の許可・拒否条件を導入できるのです。

**操作先・操作元の属性値を使って追加の許可・拒否条件を導入できる**のです。

すごい！便利じゃん！！

つまり、RBAC、ABACを適切に設定することで、こんな感じの運用ができます。

1. グループAの人はEC2サービスを自由に触って良いですよ～（RBAC）

1. ただし、 ```"Importance": "High"``` タグのついたEC2は操作できませんよ～（ABAC）

試してみます！

# 動作確認
## IAMポリシーの準備

今回はあまり深いことを考えず、以下のポリシーを用意しました。

```policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SampleRBAC"
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*",
        },
        {
            "Sid": "SampleABAC"
            "Effect": "Deny",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StopInstances",
                "ec2:RebootInstances",
                "ec2:DeleteTags",
                "ec2:CreateTags"
            ],
            "Condition": {
                "Null": {
                    "aws:ResourceTag/Importance": "false"
                },
                "StringEquals": {
                    "aws:ResourceTag/Importance": "High"
                }
            },
            "Resource": "*",
        }
    ]
}
```

### RBACの雰囲気を掴む

```policy.json
    "Statement": [
        {
            "Sid": "SampleRBAC"
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*",
        },
        ...
```

RBAC思想で設定されている箇所です。
ロールに対し、大まかな権限を設定しています。

```"Action": "ec2:*",``` が大事で、EC2の操作のみを許可するポリシーとなっています。

グループAの人はEC2サービス（だけ）を自由に触って良いですよ～（RBAC）の部分ですね。

### ABACの雰囲気を掴む

ABAC思想で設定されている箇所です。
```policy.json
    "Statement": [
        ...
        {
            "Sid": "SampleABAC"
            "Effect": "Deny",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StopInstances",
                "ec2:RebootInstances",
                "ec2:DeleteTags",
                "ec2:CreateTags"
            ],
            "Condition": {
                "Null": {
                    "aws:ResourceTag/Importance": "false"
                },
                "StringEquals": {
                    "aws:ResourceTag/Importance": "High"
                }
            },
            "Resource": "*",
        }
    ]
```

ややこしいので、少しずつ見ていきます。
#### statementで権限を管理するアクションの指定
```
    "Action": [
        "ec2:TerminateInstances",
        "ec2:StopInstances",
        "ec2:RebootInstances",
        "ec2:DeleteTags",
        "ec2:CreateTags"
    ],
```

許可または拒否するアクションを提示しています。
EC2のやばい操作や、タグの変更です。拒否されそうな雰囲気が凄いです。

#### アクションの明示的な拒否
```
    "Effect": "Deny",
```

```Deny``` でリストしたアクションを拒否しています。

#### 拒否設定の適応条件
Conditionブロックで、Denyする条件を定義しています。

```
    "Condition": {
        "Null": {
            "aws:ResourceTag/Importance": "false"
        },
        "StringEquals": {
            "aws:ResourceTag/Importance": "High"
        }
    },
```

ちょっと複雑なので、1つずつ確認します。

##### Importanceタグの値を確認するCondition
```
    "StringEquals": {
        "aws:ResourceTag/Importance": "High"
    }
```

```"aws:ResourceTag/Importance": "High"``` で、リソースタグのImportanceがHighなリソースに対して、Denyを適用するように設定しています。

##### Importanceタグが存在しない場合のCondition
```
    "Null": {
        "aws:ResourceTag/Importance": "false"
    },
```

```"aws:ResourceTag/Importance": "false"``` で、リソースタグのImportanceが存在しない場合、条件がどう評価されるかを設定しています。

```"false"``` にしているため、リソースタグにImpotanceが存在しない場合、Conditionはfalseとなり、Denyは適応されません。

### ABACの雰囲気まとめ
このように、操作先のリソースの属性値（タグ）の値を参照し、Deny権限を設定しています。
上述した**操作先・操作元の属性値を使って追加の許可・拒否条件を導入できる**をやってみた感じです。


## 動作確認
3台のEC2を用意しました。

![cap10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/a237ba50-9849-4928-ab46-e9372a8c1b67.png)

何もタグのないインスタンスと、

![cap09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/9a5f4ebb-e7a4-5e71-fee1-6bf31132cb87.png)

"Importance": "Low"のインスタンスと、

![cap11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/6a8b6db4-ad11-828a-99e0-f9167dfec590.png)

"Importance": "High"のインスタンスです。

作成したロールで操作してみます。

### 何もタグのないインスタンス

![cap13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/9443ee9c-c6dc-37db-f081-efbf0d88ee3f.png)

Stopできました

### "Importance": "Low"のインスタンス

![cap12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/a9d5bf70-d0c6-70b9-7f0e-ca6a26b78fa0.png)

Stopできました

### "Importance": "High"のインスタンス

![cap14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/bc953b7b-7940-b6f6-673b-a0bd94be6067.png)

Stopできません！

良い感じにRBAC、ABACできていることが確認できました。

# ABACできない操作の確認方法
本題です。

公式のドキュメントにある通り、ABACに対応しているサービスと、そうではないサービスが存在します。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html

![cap15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/73574f68-5a5f-86ec-a32a-a20582339fe2.png)

S3などが「部分的」と記載されています。
クリックするとこのような記載が表示されます。

![cap16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/ca96b970-e8b2-7d4c-5094-0ca234e072a4.png)

・・・もう少し納得いく説明がほしい！

## ちょっと深掘り
そこで確認すべきなのが以下のドキュメントです。

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html

![cap22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/aad2e698-0cfb-3181-7a24-9fa193a1a14e.png)

IAMポリシーで使用することのできるActionや、Actionそれぞれが、Conditionにどのような条件を付与できるかが記載されています。

EC2のRunInstancesアクションを見てみます。

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonec2.html

![cap17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/b9247e82-ce0e-510f-b711-4fc1c92baf65.png)

条件キーに ```aws:ResourceTag/${TagKey}``` が存在することが確認できます。
リソースのタグを条件にIAMポリシーを評価できるわけです。
ABACできそうです。

S3のlistAllMyBucketアクションを見てみます。

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazons3.html

![cap18_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/58686573-7147-2790-4125-dac4280c0f54.png)

条件キーに ```aws:ResourceTag/${TagKey}``` が存在**しない**ことが確認できます。
リソースのタグを条件にIAMポリシーを評価できなさそうですね。

![cap19_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d3f6c737-55c5-664f-fb19-c9eebaab5f25.png)

その他一部のアクションは条件キーに ```aws:ResourceTag/${TagKey}``` が存在することが確認できました。

![cap21.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/38370833-4937-148d-afd3-a076cc6df285.png)

また、上記で ```Amazon S3 は、オブジェクトリソースに対してのみタグベースの認可をサポートしています。``` と記載されていましたが、ドキュメントでは条件キーに ```aws:ResourceTag/${TagKey}``` が存在しませんでした。

けっこうカタカタで、部分的に対応してるなーって感じですね。

# 感想まとめ
- 自社のアカウント運営チームが普段苦しんでいるABACで遊んでみた！
- 柔軟に設定できる一方で、複雑さが増して、サイロな組織だと軋轢が生まれそう！
- 削除保護やIaC化を進め、壊れるようなオペレーションをいったん他のやり方で防御したほうが幸せかも！
- AWSのドキュメントって、なんでこんなにボロボロなんだろう！