🔐

IAM Identity CenterでSecrets ManagerにABACを導入しつつABACに想いを馳せる

2024/09/15に公開

(この手の話は何番煎じかわかりませんが…)

RBACABACは、アクセスコントロール(権限管理)の主要な方法論です。これらの実装は、アクセスコントロールの仕組みを提供する側に大きく依存します。一般的には、シンプルなRBACで権限管理を行うケースが多いでしょう。

私の認識では、ABACはRBACの運用に疲れた人々に、ちょっとだけ柔軟な選択肢を提供する希望の光のようなものです。(ただし、これは「どちらか」を選ぶものではなく、両者を組み合わせて使うものです)

今回は、ABACが身近にある具体例として、AWSを題材に取り上げます。IAM Identity Centerに登録されている属性情報を利用して、Secrets Managerの重要な認証情報へのアクセス権限を制御する実装を試みます。

そもそもABACとRBACの違いとは?

この辺りはOktaの記事を参考にかみ砕いてみます。(細部は異なる可能性がありますが、大まかなニュアンスを掴んでいただければと思います。重要なのは実際の使用時に適切に扱えるかどうかなので、概念は大筋を押さえれば十分でしょう。)
https://www.okta.com/jp/identity-101/role-based-access-control-vs-attribute-based-access-control/

RBACとその課題

RBACはRole-Based Access Controlの略で、ロール(人々のグループ)を中心に権限管理を行う仕組みです。

AWSで言えば、IAMロールやIAMグループを使用する場合、RBACで設計されていると言えるでしょう。誰がどのロールに切り替えられるかを制御し、そのロールに適切な権限を付与する形で運用します。(多くのデータベースの権限管理の仕組みもRBACです)

RBACの仕組み上、きめ細かく権限を制御しようとするとロールの爆発(数が莫大に増える)が起こります。

例えば、次のような要件が来たら大変です。

「認証情報AにアクセスできるのはA部署の人だけ。でも、認証情報BにアクセスできるのはA部署のAさんとBさんだけ。それと…」

このような要望を一つ一つ受け止めてロールを作っていったとして、それを維持管理できるでしょうか?(地獄のような未来が見えてきますね)

さらに、設計によっては複数の部署(役割)を持つ人が複数のロールを使い分けなければならなくなるかもしれません。これは面倒です(個人的には、管理者の負担が増えることよりも利用者側の負担が増える点の方がが大きな問題だと考えています)。

ABACとその課題

ABACはAttribute-Based Access Controlの略で、属性を中心に権限管理を行う仕組みです。

「属性と言っても、部署・役割に合わせてロールを設計していたらRBACと同じではないか?」と思うかもしれません。その気持ちはよくわかります。冒頭でも少し触れましたが、ABACはRBACと対立する方法論ではなく、RBACの機能を補完するものだと考えてください。RBACとの最大の違いは、Oktaの図が明確に示しているように、アクセスする対象の属性も含めて考慮できる点です。

「…ん?結局どういうこと?」と思われるかもしれません。RBACで困難を感じた要件を思い出してみましょう。

「認証情報AにアクセスできるのはA部署の人だけ。でも、認証情報BにアクセスできるのはA部署のAさんとBさんだけ。それと…」

このような要望を満たすために、実際にはロール側を増やす必要はないのかもしれません。ABACの場合、RBACで付与された大まかな権限に加えて、操作先・操作元の属性値を使って追加の許可・拒否条件を導入できるのです。

つまり、ロールのポリシーを変更することなく、リソース側で「この属性を持つ人はアクセスできる」といった設定が可能になります。(もちろん、属性がしっかりと設計され、ユーザーに適切に適用されていることが前提ですが…)

最も細かな制御の例として、特定の人だけにアクセスを絞りたい場合、ユーザー名という属性でアクセスできる人を限定することができます。

一方で、設定が分散するため、意図せずアクセスできなくなり、「なぜだろう?」という事態が発生する可能性もあります。何でもかんでもABACを利用すると、逆にカオスになる可能性もあるのです。これが一つの課題と言えるでしょう。


さらに深く掘り下げたい方には、こちらの記事がわかりやすくておすすめです。

https://dev.classmethod.jp/articles/akibaaws-06-iam-abac/

(これを読んで完全に理解できたなら、以降は読まなくても大丈夫かもしれません)

それでは具体的な形でABACを利用してみる

IAM Identity Centerの属性値とSecrets Managerのリソースポリシーを利用してABACを実装してみます。

今回のABACで利用する属性はIAM Identity CenterをIDPとして利用する場合に使えるcostCenterという属性です。(他のIDP利用するともう少し企業の所属とかも利用できるみたいです)

想定するユースケース

とある認証情報を特定の管理者のみに絞るというケースを想定してみます。
前提として、IAM Role側では細やかに権限管理せずにResourcesに "*" が設定されているとします。

Identity Centerでアクセスコントロールの属性を設定する

IAM Identity Centerでアクセスコントロールの属性を有効にします。
手順はこちら↓
https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/configure-abac.html

有効化をしたら属性のマッピングをします。(キーは任意の名前です)

キー
CostCenter ${path:enterprise.costCenter}

アクセスコントロールの属性

設定が完了したら、実際のユーザの属性にコストセンターがあるのでそこに Administrator と入力しましょう。

(セッションに設定されているっぽい感じなので、ログアウトしたりしてからログインすると反映されるような感じでした。)

Secrets ManagerでリソースポリシーにABACを設定する

Secrets Managerを設定していきます。
今回はTerraformのコードで設定したので、それをサンプルコードに書き直した状態で貼っておきます。(他にもシステムが利用するようにIAMロールのプリンシパルでも設定してあります。)

resource "aws_secretsmanager_secret" "sample" {
  name                    = "sample_secret"
  recovery_window_in_days = 0
  policy                  = data.aws_iam_policy_document.sample.json
}

data "aws_iam_policy_document" "sample" {
  statement {
    sid    = "AllowOnlyAdminAndSystem"
    effect = "Deny"
    principals {
      type = "AWS"
      identifiers = ["*"]
    }
    actions = [
      "secretsmanager:GetSecretValue",
    ]
    resources = ["*"]
    # ここがABACの部分!
    condition {
      test     = "StringNotEquals"
      variable = "aws:PrincipalTag/${var.admin_tag_key}"
      values   = ["${var.admin_tag_value}"]
    }
    condition {
      test     = "StringNotEquals"
      variable = "aws:PrincipalArn"
      values = [
        "${aws_iam_role.sample.arn}"
      ]
    }
  }
}

variable "admin_tag_key" {
  default     = "CostCenter"
  description = "IAM Identity CenterのCostCenter属性を参照しているアクセスコントロールの属性のキー名"
}

variable "admin_tag_value" {
  default     = "Administrator"
  description = "管理者に設定しているIAM Identity CenterのCostCenter属性の値"
}

# iam_roleは割愛

Denyで特定の文字列以外を拒否する形で制限を入れています。つまり許可する属性を指定しているわけです。

動作確認

実際にアクセスしてみます

属性のコストセンターにAdministratorが設定されている状態

設定を確認できる

属性のコストセンターにAdministratorが設定されていない状態

権限不足と表示される


以上で、動作確認が完了しました。

ここまでの手順でIAMロールのポリシー側には一切触っていまないことがわかると思います。

まとめ

IAMではCondition句を使用して細かな制御が可能ですが、ABACの要素を取り入れることで、より柔軟な権限管理が実装しやすくなります。特定のユースケースでは、ABACの導入により大きな恩恵を得られる可能性があります。

また、今回とは異なるアプローチとして、IAM Policyを利用したパターンも参考になります。以下の記事では、リソースのタグを使ってアクセス範囲を設定する方法が紹介されています。この方法はリソースポリシーがないリソースにも適用できるため、より実用的です。ただし、各ロールにポリシーを設定する必要があるので注意が必要です。初期段階で導入できれば問題ありませんが、既に複雑化した環境では大規模な変更が必要になる可能性があります。
https://dev.classmethod.jp/articles/aws-iam-identity-center-abac/

「RBACで苦労しそうだが、セキュリティ要件は妥協できない…」と諦める前に、ABACの要素を取り入れられないか検討してみましょう。少し立ち止まって考えることで、より効率的な解決策が見つかるかもしれません。

Discussion