私が歌川です

@utgwkk が書いている

AWSのIAMロールに必要な権限が付与されているかシミュレートするCLIツールを書いた

はじめに

表題のようなCLIツール aws-iam-policy-sim を書きました。

github.com

使い方

Statement フィールドに、以下のようなオブジェクトの配列が入っている、というJSONファイルを用意しましょう。

  • Action フィールドにアクション名もしくはその配列
  • Resource フィールドにリソースもしくはその配列

たとえば以下の通りです。うっすらお気づきの方もいると思いますが、実はポリシードキュメントのJSONがそのまま使えます。

{
  "Statement": [
    {
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:GetObjectTagging",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::example-bucket/*"
      ]
    },
    {
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::example-bucket"
    }
  ]
}

このJSONファイルを path/to/statement.json というパスに保存した上で、example-role という名前のIAMロールについてシミュレートしたい場合、以下のようなコマンドを実行します。

$ aws-iam-policy-sim -role-name example-role < path/to/statement.json
time=2024-11-29T21:14:39.062+09:00 level=INFO msg=Allowed action=s3:PutObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.256+09:00 level=INFO msg=Allowed action=s3:GetObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.452+09:00 level=INFO msg=Allowed action=s3:GetObjectTagging resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.645+09:00 level=INFO msg=Allowed action=s3:DeleteObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.839+09:00 level=INFO msg=Allowed action=s3:ListBucket resource=arn:aws:s3:::example-bucket

権限が足りない場合は aws-iam-policy-sim コマンドがexit status 1で終了します。

$ aws-iam-policy-sim -role-name example-role < path/to/statement.json
time=2024-11-29T21:14:39.062+09:00 level=INFO msg=Allowed action=s3:PutObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.256+09:00 level=INFO msg=Allowed action=s3:GetObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.452+09:00 level=INFO msg=Allowed action=s3:GetObjectTagging resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.645+09:00 level=INFO msg=Allowed action=s3:DeleteObject resource=arn:aws:s3:::example-bucket/*
time=2024-11-29T21:14:39.839+09:00 level=ERROR msg="Implicit deny" action=s3:ListBucket resource=arn:aws:s3:::example-bucket
exit status 1

モチベーション

AWSのIAMロールにアタッチした許可ポリシーを整理したいけど、整理の過程で意図せず必要な権限を削ってしまわないか気になりますよね。こういうときにIAM Policy Simulatorを使うことで、指定したIAMロールから、指定したリソースに対するアクションが許可されるかどうか、がシミュレートできます。

docs.aws.amazon.com

しかし、どうしてもコンソールをポチポチ操作しないといけないので、シミュレートしたいものの数が多いと手間だしミスもしてしまうと思います。

さて、AWS CLIを使えばいいんじゃないか、ということはすぐに思いつくでしょう。ドキュメントを読んでみると、aws iam simulate-custom-policy というまさにこのためのコマンドが定義されています。

awscli.amazonaws.com

ですが、aws iam simulate-custom-policy コマンドを使って「あるIAMロールで指定したリソースに対するアクションが許可されるかどうか」をシミュレートするには手間がかかります。具体的には --policy-input-list 引数には許可ポリシーのARNではなくポリシードキュメント (JSON) を指定してあげる必要があります。つまり、こういう手順になるわけです。

  1. シミュレート対象のIAMロールの許可ポリシーのドキュメントを全て列挙する
  2. --policy-input-list 引数にJSONを渡す
  3. --action-names 引数や --resource-arns 引数の値を変えつつシミュレートしていく

これを整理前と整理後で繰り返す必要があります。シェルスクリプトを書いたら自動化はできるだろうけどJSONの取り扱いがやや面倒だったり、ポリシードキュメントを列挙するのが手間だったり*1します。

たぶん手慣れたプログラミング言語で書いてしまうのが早いだろうな~と思って1時間ぐらいやったらできました。

実装のみどころ

ポリシーを列挙するのにイテレータを使っているのがおしゃれなんじゃないでしょうか。iter.Seq2[V, error] 型のイテレータを返す実装パターンをやってみたけどこんな感じなのかな?

github.com

あとはslogを使っているところとかでしょうか。DEBUGレベルのログは -debug 引数に値を渡したときだけ出る、というのがslogのログレベルの仕組みで実現できています。ログ出力の見た目が読みやすいかどうかは諸説あるかも。

おわりに

年末のIAMロール権限掃除にぜひご活用ください。IAMユーザーやグループに対するシミュレートは、自分が必要に駆られていないので実装してません。

シェルスクリプトからAWS CLIを呼ぶのだとちょっと煩雑になる、という場合は、手慣れたプログラミング言語のAWS SDKを使ってCLIを書いてみるのがおすすめです。

*1:list-role-policiesとlist-attached-role-policiesを使い分ける必要があった