IAM ポリシーでのリソースに対する設定について

はじめに

AWS IAM の機能を使うとユーザーや EC2 に付けるロールの権限を細かく設定できて不慮の事故などを防ぐことができます。

IAM ポリシーの設定をリソースに対して行うと例えば本番環境へのリソースを間違って削除したり更新する事故を予防できると思います。

開発環境で色々な機能を扱うときに本番リソースに影響がないかなど不安が出てきて IAM 設定方法を調べて見たためまとめておきます。

権限の評価方法

IAM JSON ポリシーの評価論理 - AWS Identity and Access Management

こちらに書かれていました。

以下のような流れで評価されるようです。

  • 一つでも Deny ポリシーが当てはまると explicit deny
  • 一つでも Allow ポリシーが当てはまると Allow
  • なにも無いと Deny

リソースに対する設定が難しい

リソースに対するポリシーの付け方は難しくなっていると感じました。

例えば EC2 だと関連する IAM 権限についてはこちらに書かれていますが

Actions, Resources, and Condition Keys for Amazon EC2 - AWS Identity and Access Management

これを見てもリソースは インスタンスやイメージ、サブネット、VPC など様々あって しかもアクションによって関連するリソースも違うためどうやって設定すればいいのか全然わかりません。

AWS IAM Policy Summaries Now Help You Identify Errors and Correct Permissions in Your IAM Policies | AWS Security Blog

この記事によくある間違った設定方法が書かれていましたが、このように書きたいというのはよく分かります。

This policy does not work. Do not copy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ThisPolicyDoesNotGrantAllListandGetActions",
            "Effect": "Allow",
            "Action": ["s3:List*",
                       "s3:GetObject"],
            "Resource": ["arn:aws:s3:::HumanResources"]
        }
    ]
}

これがうまく動かないのはリソースが関連しないIAMアクションが有効にならないからです。

記事の後半の方に正しい設定方法について書かれています。 リソースが関係ないIAMアクションについては別にしてステートメントにレコードを追加するというやり方です。

しかしリソースからアクションを絞り込んで設定するというのが手動で簡単にできるとは思えません。

アクションを一つ一つ見て設定していくことは時間をかければできると思いますが、メンテナンスすることは難しい気がします。 複雑なポリシーを書いてそれが正しいことを確認することもかなり難しいと思います。

しばらく悩んでリソースについての権限は Deny のポリシーを活用するといいのではないかという考えが浮かびました。

例えば EC2 インスタンスに Environment のタグを付けて、これが development でないインスタンスへの全てのアクションを禁止するには下のように書けます。 Condition の Null の条件はインスタンスの起動時などタグがついてない場合に禁止にならないようにするために付けました。 これだとアクションを一つ一つ書かなくてすみます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "ec2:*"
            ],
            "Resource": [
                "arn:aws:ec2:*:accountid:instance/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "ec2:ResourceTag/Environment": "development"
                },
                "Null": {
                    "ec2:ResourceTag/Environment": "false"
                }
            }
        }
    ]
}

これだけだと Deny だけで何もできないのでユーザーまたはロールに別に AmazonEC2FullAccess のポリシーをつけます。 FullAccess だとつけすぎかもしれませんがその場合は許可用のポリシーを用意するなどします。 タグを付ける部分の権限もポリシーに入れる方がいいかもしれません。

意図したように権限設定できていることを aws cli で確認してみました。 ec2 に関するアクションは --dry-run というオプションを使うと簡単に試すことができます。

上のは development 以外禁止というポリシーですが逆に production のみ禁止なども書けます。 またサブネットや VPC のリソースについて Deny で同様に設定を作るということができます。

まとめ

IAM でのリソースに関する権限設定の方法について検討してみました。 個人的には Deny を使った設定を活用すると設定しやすいのではという結論になりました。 Allow のみで細かい設定を作る場合は手動でポリシーを作成するのは難しいので、 設定項目を管理可能なパラメーターで入力してポリシーを生成するようなツールを作ったりする方法もあるかなと思いました。