ジャストインタイムノードアクセス機能の自動承認ポリシーを試してみた
お疲れさまです。とーちです。
AWS Systems Manager でジャストインタイムノードアクセス機能が新たに登場しました。なかなかおもしろい機能ですよね。機能の詳細は以下の記事をご確認頂ければと思いますが、ざっくりいうとEC2インスタンスに接続する際に承認フローを挟むことができる機能になっています。
この承認ですが、手動承認と自動承認の2種類が存在します。この記事では自動承認を試してみようと思います。
自動承認ポリシーの基本
自動承認をどのように設定するかですが、ポリシーを記述することにより設定します。
こちらの記事に分かりやすく書いてあるのですが、ジャストインタイムノードアクセス機能では3種類のポリシーが用意されており優先順位(アクセス拒否⇒自動承認⇒マニュアル)に従い適用されるポリシーが決まります。自動承認はマニュアルよりも優先度が高いので自動承認の条件にマッチした場合は承認フローを挟まずにアクセスできます。
Cedarポリシー言語について
自動承認ポリシーですが、CedarというAWSが開発したポリシー言語を使用して記載します。
Cedarの基本的なフォーマットは以下の通りです。
permit (
principal,
action,
resource
)
when {
条件
};
各要素の意味:
- permit/forbid: 許可するか禁止するか
- principal: 誰が
- action: 何をするか
- resource: 何に対して
- when: どのような条件の時に(オプション)
actionはジャストインタイムノードアクセス機能では、AWS::SSM::Action::"getTokenForInstanceAccess"
で固定となります。
principalには公式ドキュメントの例を見ると AWS::IdentityStore::Group::"e8c17310-e011-7089-d989-10da1EXAMPLE"
といった形でIAM Identity Centerのグループを指定できるようです。
IAMロールでの指定も出来ないかと思い、principal == AWS::IAM::Role::"ロール名"
principal == AWS::IAM::Role::"ロールARN"
等を試してみたのですが、以下のようにポリシー構文エラーとなり、設定出来ませんでした。principalにIAMロールを直接指定する方法をご存知の方がいましたら、@tttkkk215までご指摘頂けると幸いです。
policy0: for policy
policy0, unable to find an applicable action given the policy scope constraints
それではCedarを使って色々なパターンで自動承認を試してみましょう。なお、ジャストインタイムノードアクセス機能の初期セットアップ方法についてはこちらの記事をご参照ください。
特定のタグがついているEC2インスタンスを自動承認
特定のタグがついているEC2へのアクセスを自動承認してみます。
なお、以下のように手動承認ポリシーを設定しているので自動承認ポリシーが適用されなかった場合は承認されるのを待つことになる想定です。
自動承認ポリシーは以下の画面から設定します。
特定タグがついたEC2へのアクセスを許可するために以下のポリシーを設定しました。
permit (
principal,
action == AWS::SSM::Action::"getTokenForInstanceAccess",
resource)
when {
resource.hasTag("auto_approved") &&
resource.getTag("auto_approved") == "true"
};
なおポリシー編集画面は以下のような形になっています。画面左のサンプルステートメントからいくつかユースケースに沿ったポリシー例を確認、挿入できます。「自動承認ポリシーを公開」ボタンを押してポリシーを設定します。
自動承認を試してみる
ではこの状態でEC2にアクセスしてみましょう。予めEC2インスタンスにタグをつけておきます。
一般ユーザーを想定したIAMロールでAWSアカウントに入り直して、タグを付与したインスタンスに接続してみます。
「ターミナルセッションを開始する」を選択すると以下のように承認依頼画面が出るところまでは手動承認と一緒です。
「Create access request」を選択すると以下のように即座にSession Managerによる接続が開始されます。
タグを変更した場合の挙動
タグをfalseに変えてもう一度試してみます。
この状態だと接続するために再度承認依頼画面が出ると思ったのですが、予想に反して接続できてしまいました。
これは自動承認で許可されたアクセス期間が残っていたからだと思われます。
このあたり想像とは異なる挙動だと思います。アクセス期間が残っている場合はタグ等の属性を変えても対象EC2インスタンスに対するアクセスは引き続き有効である点には注意したほうが良さそうです。
なお、自動承認した場合のアクセス期間は1時間固定で変更することはできません。
The access duration for an access request that is automatically approved is 1 hour. This value can't be changed.
気を取り直して、改めて新しくEC2インスタンスを作成しそれに対して、auto_approved: false
のタグをつけて再度アクセスを試してみます。
承認依頼画面で「Create access request」ボタンを押すと、今度は即座に接続されずに以下のようにアクセスリクエストが作成されました。ちゃんと自動承認ポリシーは機能しているようです。
特定のタグがついたIAMロールは自動承認
今度はポリシーを追加して、以下のポリシーにしてみます。
permit (
principal,
action == AWS::SSM::Action::"getTokenForInstanceAccess",
resource)
when {
resource.hasTag("auto_approved") &&
resource.getTag("auto_approved") == "true"
};
// 以下を追加
permit (
principal,
action == AWS::SSM::Action::"getTokenForInstanceAccess",
resource
)
when
{
context.iam.principalTags.hasTag("Admin") &&
context.iam.principalTags.getTag("Admin") == "true"
};
IAMロールに特定のタグ(Admin: true
)がついている場合に許可するポリシーを追加してみました。
なお、自動承認ポリシーには、複数のpermit(許可)を含めることができます。私が確認した限りではどれか一つのpermit条件に当てはまれば合格となるようです。
それでは追加したポリシーを試してみます。
IAMロールに以下のようにタグをつけました。
EC2を再作成(auto_approvedタグは付けていない状態)した後、承認依頼画面で「Create access request」ボタンを押すと自動で承認されSession Managerによる接続が開始されました。
こちらのユースケースとしては、IAMロールにグループのタグをつけて対象のグループに対して一律でポリシーを割り当てるといった用途が考えられますね。
まとめ
以上、ジャストインタイムノードアクセス機能の自動承認ポリシーを試してみました。CedarはIAMポリシーとは異なるのでIAMプリンシパルの指定方法等で差異があり、私は書き方に悩んだりもしましたが、有効に活用することで余計な承認の手間を減らすことができると思うのでぜひ試してみて頂ければと思います。