HackToTech

Hack To Technology

特定のIAMロールで実行できるSystemsManagerのドキュメントを制限する方法

特定のIAMロールで実行できるSystemsManagerのドキュメントを制限する方法

今後もまた実装したくなることがありそうなので、残しとく
結論から言うと大体下のようなIAM Policyで制限をかけることが可能

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ssm:StartSession",
            "Resource": [
                "arn:aws:ec2:*:*:instance/*"
            ],
            "Condition": {
                "BoolIfExists": {
                    "ssm:SessionDocumentAccessCheck": "true"
                },
                "StringLike": {
                    "ssm:resourceTag/Name": "FugaFuga"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/HogeHogeDocument"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession",
                "ssm:ResumeSession"
            ],
            "Resource": "arn:aws:ssm:*:*:session/${aws:username}-*"
        }
    ]
}

やっている内容について書いていく

まずはこのstatement

{
    "Effect": "Allow",
    "Action": "ssm:StartSession",
    "Resource": [
        "arn:aws:ec2:*:*:instance/*"
    ],
    "Condition": {
        "BoolIfExists": {
            "ssm:SessionDocumentAccessCheck": "true"
        },
        "StringLike": {
            "ssm:resourceTag/Name": "FugaFuga"
        }
    }
}

単純にActionとResourceはSSMのStartSessionをどのEC2インスタンスに対してでも実行できるようにしている
その上でConditionを使用して対象の絞り込みをかける
BoolIfExistsのssm:SessionDocumentAccessCheckは下の公式を読むとよくわかるが、
AWS CLI でセッションドキュメントのアクセス許可チェックを適用する
通常ssm:StartSessionを許可した場合にSSM-SessionManagerRunShellがデフォルトで許可される
これが許可されてしまうとインスタンスに接続してごにょごにょ何でも出来てしまうのでまず明示的に許可していないドキュメントへのアクセスを遮断する為に必要
次にStringLikeで ssm:resourceTag/Name を絞っているが、これは特定の名前のインスタンスにのみ実行を許可するために使っている(今回であればNameがFugaFugaのインスタンスだけとなる)
これもよくある、この種類のインスタンスに対しては良いけど他へは実行できて欲しくないといったときに重宝する

次にこのstatement

{
    "Effect": "Allow",
    "Action": "ssm:StartSession",
    "Resource": "arn:aws:ssm:*:*:document/HogeHogeDocument"
}

前のstatementで明示的に許可をしていないドキュメントについてはアクセス出来なくさせたので、
ドキュメントを指定することによって実行を許可している
なんで前のstatementと分けて書いているかというと、
前のstatementはConditionのStringLikeでTagの一致を条件として使用しているので、ドキュメントにも同様のTagがないと弾かれてしまうようになる(ドキュメントのName tagにFugaFugaを設定するつもりはないので、今回は分けている)

最後にこのstatement

{
    "Effect": "Allow",
    "Action": [
        "ssm:TerminateSession",
        "ssm:ResumeSession"
    ],
    "Resource": "arn:aws:ssm:*:*:session/${aws:username}-*"
}

自分自身がStartSessionで作成したsessionに対してResumeとTerminateを出来るように許可している

書いてみると意外と単純だが、Conditionを扱うのが久しぶりだと若干頭を悩ませる