Ubuntu VMで学ぶ「属性ベースアクセス制御:ABAC」
- 7 日前
- 読了時間: 7分
“ユーザーやロールだけで決めない”アクセス制御を、polkitで手を動かして理解する
アクセス制御の説明では、RBAC まで来ると話がだいぶ整理しやすくなります。「運用担当だからこの操作を許可する」「監査担当だから閲覧だけ許可する」といった形で、役割ごとに権限をまとめられるからです。
ただ、実務ではそれだけで収まらない場面が増えています。同じ管理者でも、社内ネットワークからの操作と私物端末からの操作では扱いを変えたい。同じ医師でも、自分の担当患者に対する閲覧と、他科の患者記録へのアクセスを同じにしたくない。こういう条件が入ってくると、ロールだけで押し切る設計はすぐに苦しくなります。
ここで出てくるのが ABAC です。ABAC は Attribute-Based Access Control、属性ベースアクセス制御です。RBAC が「役割」でアクセスを決めるモデルだとすれば、ABAC はもう一段細かく考えます。アクセスの可否を、利用者の属性、資源の属性、操作の種類、時間帯、場所、端末状態など、複数の条件で判断する考え方です。Ubuntu で標準の MAC として前面に出ているのは AppArmor ですが、認可判断を属性で細かく書き分ける入口としては polkit が分かりやすい位置にあります。polkit は、特権側プログラムが非特権側からの要求を受けたとき、その要求を認可すべきかどうかを判定する仕組みで、Authorization Rules によって管理者が条件を追加できます。
ABACの発想
RBAC では、「医師ロールだから閲覧可能」といった判断をします。ABAC では、それに加えて次のような条件を掛け合わせます。
利用者属性:医師、所属診療科、担当患者
資源属性:診療記録、機微情報フラグ
環境属性:院内ネットワーク、勤務時間内、多要素認証済み
操作属性:閲覧か、更新か、削除か
つまり、誰であるかだけではなく、どういう条件下で、何に対して、何をするかまで含めて制御します。
この見方は、今のシステムにはかなり相性がいいです。実際の業務要件は、「利用者の所属」だけで完結せず、接続元、セッション状態、認証強度、対象データの性質まで絡むことが多いからです。
polkit の認可モデルでも、アクションの識別子とサブジェクトの状態を見て判断する前提になっており、既定ポリシーにも allow_any、allow_inactive、allow_active といった区分が用意されています。つまり「何をしようとしているか」と「その要求元がどんな状態か」を組み合わせて扱う発想が、最初から組み込まれています。
RBACとの違い
RBAC なら、ロールを増やせばある程度は似たことができます。ですが、「循環器の医師で、院内ネットワークから、勤務中に、MFA 済みの場合のみ」までロールで表現し始めると、設計はすぐに破綻気味になります。
たとえば、こうなります。
循環器医師ロール
循環器医師_院内限定ロール
循環器医師_院内限定_MFA済みロール
循環器医師_院内限定_MFA済み_勤務中ロール
この方向に進むと、ロールは増え続けるのに、何を表しているのかは逆に見えにくくなります。RBAC の良さは「役割の整理」にありますが、条件分岐を全部ロールへ押し込むと、その良さが消えます。
ABAC はそこを属性で処理します。ロールを大量に増やす代わりに、ポリシーで条件を記述するわけです。polkit のルールでも、action と subject を受け取る addRule() を使い、そこで条件に合えば YES、合わなければ NO や追加認証を返す、という形で認可判断を書けます。
UbuntuでABACを考えるなら、polkitが分かりやすい
Ubuntu で ABAC を学ぶとき、sudoers を無理に拡張して説明するより、polkit を足場にした方が分かりやすいです。sudoers は「誰がどのコマンドをどのユーザーとして実行できるか」を定義するのに向いています。一方、polkit は、特権側のメカニズムが受けた個々の要求について、その都度認可判断を下すための仕組みです。
ルールファイルは /etc/polkit-1/rules.d や /usr/share/polkit-1/rules.d に置かれ、JavaScript でpolkit.addRule(function(action, subject) { ... }) のように書きます。
この設計は ABAC と相性がいいです。なぜなら、判断材料として最初から「アクション」と「サブジェクトの状態」が入ってくるからです。
たとえば、こういうルールがABACらしい
Ubuntu VM で考えやすい例として、こんな条件を想像すると分かりやすいです。
特定の操作だけを対象にする
ローカルセッションからの要求であること
今そのセッションがアクティブであること
さらに特定グループに所属していること
これはもう、単なる RBAC ではありません。グループ所属という主体属性だけでなく、ローカルかどうか、アクティブかどうかという環境属性まで見ています。
polkit のルールは、たとえば次のように書けます。
polkit.addRule(function(action, subject) { if (action.id == "com.example.demo.manage" && subject.local && subject.active && subject.isInGroup("appops")) { return polkit.Result.YES; } if (action.id == "com.example.demo.manage") { return polkit.Result.NO; }});このルールで見ている属性を分解すると、次のとおりです。
何をしようとしているかという操作属性
subject.local
ローカル由来の要求かという接続元属性
subject.active
アクティブなセッションかという環境属性
subject.isInGroup("appops")
所属グループという利用者属性
polkit の公式文書でも、addRule() は認可チェックのたびに action と subject を受け取り、YES、NO、AUTH_SELF、AUTH_ADMIN などを返せると説明されています。さらに、ファイルは名前順に評価され、最初に値を返したルールが使われます。
ABACの強み
ABAC の強みは、現実の業務条件に近い制御ができることです。クラウド、ゼロトラスト、API ゲートウェイ、ID 基盤で注目されるのは、この柔軟性が大きいからです。
とくに、「同じ人でも条件によって許可範囲が変わる」世界では非常に使いやすい。管理者が社内から使うのと、私物端末から使うのとでは扱いを変えたい。MFA 済みのときだけ高リスク操作を許可したい。勤務時間外の更新操作だけは拒否したい。この種の要件は、ABAC の方が素直に書けます。
Ubuntu の polkit でも、allow_active や allow_inactive といった区分があるように、そもそも「同じユーザーでもセッション状態によって扱いを変える」という発想が中心にあります。
ABACの難しさ
ただし、柔軟であることは複雑さでもあります。属性の定義が曖昧だと、ポリシーはすぐに読みにくくなります。たとえば「端末が準拠状態である」という属性を参照するなら、その判定元を本当に信頼できるのか、という問題が出ます。属性がきれいに見えても、元データが怪しければ制御の根拠ごと崩れます。
また、障害調査の観点でも、RBAC より追いづらい場合があります。なぜ拒否されたのかが、複数属性の組み合わせに依存するためです。polkit でも、ルールは順番に評価され、どのルールが先に値を返したかで結果が決まります。そのため、ルールが増えるほど「どの条件が効いたのか」を追う難しさは確実に増します。polkit はデバッグ用に polkit.log() を持っており、ルールの判定内容をログへ出せるのも、こうした複雑さが現実にあるからです。
実務での位置づけ
現代の認証・認可基盤では、RBAC だけでは足りない場面が増えています。そのため、ABAC の考え方はかなり実践的です。もちろん、全部を ABAC にすればよいわけではありません。実務では、まず RBAC で大枠を切り、その上で ABAC で条件を細かくする、という組み合わせが扱いやすいです。
たとえば「運用担当」という役割を前提にしつつ、「社内ネットワークから」「MFA 済みで」「本番変更申請が通っているときだけ」許可する、といった形です。この見方をすると、ABAC は RBAC の敵ではありません。RBAC だけでは表現しきれない現実条件を、属性で補うための実務的な手段です。
まとめ
ABAC の本質は、役割だけではなく、属性の組み合わせによって認可を決定する点にあります。利用者属性、資源属性、操作属性、環境属性を組み合わせることで、より現実に即したアクセス制御を設計できる一方、その柔軟性は設計と運用の難しさも引き上げます。
属性定義が曖昧であれば、ポリシーは容易に破綻します。許可条件と拒否条件が増えるほど、管理負荷や説明可能性の問題も大きくなります。ABAC は便利なモデルというより、複雑な要件を正しく扱うために必要になるモデルと捉えたほうが実態に近いでしょう。
Ubuntu VM では、polkit を通して「誰か」だけではなく「どの条件で、その操作を許すか」を試すことで、ABAC の発想を具体的に理解できます。現代的なシステムで求められるきめ細かな認可を考えるなら、ABAC は理論として知るだけでなく、実際に設計の難しさごと体験しておく価値のある考え方です。


