本記事は、BIPROGY / ユニアデックス社内AWSコミュニティ「BIPROGY AWS SPARK」の定期投稿企画第9回目の記事です。他の定期投稿企画の記事は、AWS Sparkブログリレーを始めます! #AWS - Qiitaをご覧ください。
1. はじめに
お客様からこんな要望がきました。
Inspectorエージェントベーススキャンは動かしたいが、
Session Manager/Fleet Manager経由のEC2接続はなくしたい
単純思考な私は、頭がこんがらがりました。
- エージェントベーススキャンのためには
AmazonSSMManagedInstanceCoreが必要 - Session Manager接続を遮断したいなら、SSM関連の権限は付けたくない
一見、矛盾する2つの要求です。
そんな中、「AmazonSSMManagedInstanceCore + ssm:StartSession等を拒否するDenyポリシーを、同じロールに付ければ両立できるのでは?」という仮説をもらいました。
AWSはDenyが優先されるので、カスタムでSSM接続を拒否するポリシーを同じロールにアタッチすれば、AmazonSSMManagedInstanceCoreの許可とぶつかってDenyが勝ち、結果的に両立できるはず、という理屈です。
カスタムポリシーでAWS管理ポリシー内容を調整する発想は頭になかったので驚きでした。
加えて、本当に両立できるのか確かめたくなり、実際にAWS環境で検証してみました。
(補足)IAMの基本用語
本題に入る前に、登場する用語を簡単にまとめます。
- ユーザー(User):AWSにサインインするための、個人に紐づくID
- グループ(Group):複数のユーザーをまとめて管理する入れ物。グループ自体でサインインすることはできない
- ロール(Role):一時的に借りる権限のセット。人間がスイッチロールで使うこともあれば、EC2のようなAWSのサービス自身が「代わりに」引き受けて使うこともある
-
ポリシー(Policy):ユーザー/グループ/ロールに対して「何を許可・拒否するか」を定義したもの
※複数のポリシーを1つにまとめたものがロール。ロールを作成するには1つ以上のポリシーが必要になる。
今回のポイントは、「ロール」は人間もEC2も同じように使える仕組みという点です。EC2インスタンスに付けるロールも、人間がスイッチロールなどで使うロールも、同じ「ロール」ですが、「誰(何)がそのロールを使ってAPIを呼び出しているか」によって、そこに付けたポリシーの効き目が変わります。この違いが、後の検証結果を理解するカギになります。
2. 検証したい仮説
以下の2点を確かめることを目的に検証を行いました。
- 「EC2インスタンス側のロールにカスタムのDenyポリシーを付ければ、
AmazonSSMManagedInstanceCoreが入っていてもSession Manager接続をブロックできる」は本当か? - Denyを付けたことで、AWS Systems Manager(SSM)の管理対象インスタンス(Managed Instance)としての登録に影響が出ないか?
2番目を確認する理由は、そもそもInspectorエージェントベーススキャンが機能するには、対象EC2がSSMのManaged Instanceとして正常に登録されている必要があるためです。1番目のDenyの付け方次第でここに悪影響が出てしまうと、Session Managerは塞げてもInspector自体が動かなくなる、という本末転倒な結果になりかねません。
3. 検証環境の準備
① 2つのIAMロールを用意する
| ロール名 | アタッチする内容 |
|---|---|
inspector-only-role |
AmazonSSMManagedInstanceCore(AWS管理ポリシー)のみ |
inspector-deny-role |
AmazonSSMManagedInstanceCore + Session Manager拒否のDenyインラインポリシー(deny-session-manager-access) |
deny-session-manager-accessの中身は以下の通りです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenySessionManagerAccess",
"Effect": "Deny",
"Action": [
"ssm:StartSession",
"ssm:ResumeSession",
"ssm:TerminateSession",
"ssm-guiconnect:*"
],
"Resource": "*"
}
]
}
② それぞれのロールでEC2インスタンスを起動する
| インスタンス名 | 使用するIAMロール |
|---|---|
ec2-allow |
inspector-only-role |
ec2-deny |
inspector-deny-role |
SSM接続ができる環境で立てます。アタッチするSGは、インバウンド無し・アウトバウンドHTTPS(443)のみ許可のものです。

③ Managed Instanceとして登録されたことを確認する
起動後、Systems Managerのフリートマネージャーで両インスタンスの「Ping状態」がオンラインになっていることを確認します。これが、Inspectorエージェントベーススキャンが機能する前提条件(=Managed Instanceとしての登録)です。

4. 検証①:インスタンス側ロールにDenyを付けてみる
ec2-allow・ec2-denyそれぞれに対して、フリートマネージャーからSession Manager接続を試みます。

検証の予測としては、2章で書いた通り、ec2-allowは成功、ec2-denyは接続不可となることが予想されます。
(2章より再掲)
「EC2インスタンス側のロールにカスタムのDenyポリシーを付ければ、
AmazonSSMManagedInstanceCoreが入っていてもSession Manager接続をブロックできる」は本当か?
inspector-deny-roleにはssm:StartSession等を拒否するDenyポリシーを付けているにもかかわらず、ec2-denyへの接続はブロックされませんでした。
なぜ拒否ポリシーが効かないのか
調べてみると、IAMの認可モデルに理由があることが分かりました。
ssm:StartSessionのようなセッション開始アクションは、「接続を試みる側(人間のIAMユーザー/ロール)」に対して認可判定が行われ、「接続される側(EC2インスタンスのロール)」は一切評価対象になりません。
つまり、inspector-deny-roleにどれだけDenyを積んでも、それは「このEC2インスタンスが持つ権限」を制限しているだけであり、「誰がこのEC2に接続できるか」は別の話、ということです。
ということで早速ssm:StartSession等を拒否するDenyポリシーをIAMユーザーにつけてみました。
5. 検証②:接続する側(人間側)にDenyを付けてみる
「実際にAPIを呼び出しているプリンシパル(スイッチ先ロールで実行しているならスイッチ先ロール)」にSession Manager拒否のDenyインラインポリシー(deny-session-manager-access)を付与して、Session Manager接続を試みます。
結果:「explicit deny in an identity-based policy」で接続拒否を確認!

ec2-denyだけではなく、ec2-allowも同じように拒否を確認できました。このことからもSession Manager関連の許可はサービス側(EC2)ではなく人間側(IAMロール)にあることが分かります。
Denyを外せば接続が復活することも確認できました。
6. Inspectorへの影響は?
Denyの有無にかかわらず、Managed Instance登録状態(Ping状態オンライン)は変化なしでした。
つまり、Session Manager接続を拒否するポリシー(deny-session-manager-access)と、Managed Instance登録に必要なAmazonSSMManagedInstanceCoreの権限は重複しておらず、両立に矛盾がないことが分かりました。
7. 結論:正しい構成パターン
ここまでの検証①・②について、「想定していた流れ」と「実際の結果」の違いを図にまとめました。

今回の検証結果をまとめると、以下のようになります。
| Denyを付ける場所 | Session Manager接続 | Inspectorへの影響 |
|---|---|---|
| EC2インスタンス側のロール | ❌ ブロックされない | 影響なし |
| 接続する人間側(IAMロール/ユーザー) | ✅ 確実にブロックされる | 影響なし |
今回設定したポリシーのDenyが対象としているアクション(ssm:StartSession等)は人間が対話的にセッションを開始するための操作です。一方、Deep Inspection(Java検知含む)にはssm:PutInventoryとssm:GetParameterの権限が必要とAWS公式ドキュメントに明記されており、両者の対象アクションに重なりはありません。そのため、Denyを「EC2インスタンス側」ではなく「接続する人間側」に付けることで、Inspectorエージェントベーススキャンとの権限的な矛盾なく、Session Manager接続だけを塞ぐことができます。
運用としても、通常時は接続する側にDenyを付与してブロックし、保守などの例外時は一時的にデタッチして接続を復旧する、という形が成立することを実機で確認できました。
「Inspectorは動かしたい、でもSession Manager接続は止めたい」という一見矛盾する要望は、Denyを付ける場所さえ間違えなければ、問題なく両立できます。
8. おわりに
こんがらがっていた頭も、実機で1つずつ確かめていくことですっきり整理できました。「誰に効くDenyなのか」さえ意識できれば、一見矛盾する要望も問題なく両立できます。
似たようなお客様からのオーダーがあった方、同じ壁にぶつかった方の参考になれば幸いです。
BIPROGYグループの技術への取り組み
We Are Hiring!


