「静的な権限管理」は死んだ:ABACで実現するゼロトラストなアクセス制御
現場でインシデント対応をしていると、「権限管理はロール(RBAC)で十分」と信じ切っているチームに何度も出会う。だが、現実はどうか。退職したエンジニアの権限が残っていた、あるいはVPNを突破された瞬間に社内LANが全開放される状況……これらはすべて「静的なルール」に依存した設計の敗北だ。
今日は、攻撃者が最も嫌う「動的な防御」、すなわち ABAC (Attribute-Based Access Control) の実装について、現場の泥臭い知見を交えて解説する。
—
なぜRBACだけでは突破されるのか?
RBAC(ロールベースアクセス制御)は、ユーザーに「管理者」や「編集者」といったラベルを貼る。しかし、攻撃者はその「ラベル」を奪い取る(セッションハイジャックやクレデンシャルスタッフィング)。
ここでABACの出番だ。ABACは「誰か」だけでなく、以下の属性(Attributes)を掛け合わせてアクセス可否を動的に判定する。
- Subject(主体の属性): デバイスの健全性(EDR導入済みか)、所属部署、MFAの実施状況
- Action(操作の属性): 読み込みか、書き込みか、削除か
- Resource(リソースの属性): データの重要度、機密フラグ
- Environment(環境の属性): IPアドレス(社内か)、時刻(業務時間内か)、接続元リージョン
攻撃者が正しいID/PWを持っていても、深夜の海外IPからのアクセスであれば、ABACエンジンが「否認」を叩き出す。これが現代の要塞化の基本だ。
—
【実装編】PythonによるABACポリシー評価エンジン
複雑なフレームワークを入れる前に、ABACの本質を理解しよう。これは「属性の組み合わせを条件判定するロジック」に過ぎない。
以下は、アクセスリクエストを評価するシンプルなPythonコードだ。実務ではこれをミドルウェアやAPIゲートウェイ層に組み込む。
def evaluate_access(user, resource, environment):
"""
ABACポリシーエンジン
戻り値: True (許可) / False (拒否)
"""
# 1. 時間外アクセスのブロック(環境属性)
if environment['hour'] < 9 or environment['hour'] > 18:
print("警告: 業務時間外のアクセスを検知")
return False
# 2. デバイス健全性のチェック(主体属性)
if not user['is_device_compliant']:
print("警告: デバイスが検知対象外(EDR未稼働など)")
return False
# 3. IP制限と権限の組み合わせ(環境と主体の属性)
if resource['is_sensitive'] and environment['ip_type'] != 'office':
print("拒否: 機密リソースへの社外からのアクセス")
return False
return True
# 判定シミュレーション
user_context = {'id': 'dev_01', 'is_device_compliant': True}
resource_info = {'id': 'db_prod_01', 'is_sensitive': True}
env_info = {'ip_type': 'home', 'hour': 14}
if evaluate_access(user_context, resource_info, env_info):
print("アクセス許可")
else:
print("アクセス拒否")
—
インフラ層でのABAC的アプローチ(Nginx + Lua)
アプリケーションコードまでリクエストを到達させないことが、最大の防御だ。Nginxの auth_request モジュールを使えば、リクエストの属性(ヘッダー、IP、証明書)を前段で検証できる。
# Nginx設定例: 特定の属性を持つリクエストのみ通す
location /api/private/ {
# 認証サブクエリを呼び出す
auth_request /auth_check;
# ... そのままバックエンドへ転送
proxy_pass http://backend_cluster;
}
location = /auth_check {
internal;
# ここでLua等を使って、ヘッダーのX-Device-Stateや
# 送信元IPを判定して200か403を返す
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# 判定ロジックへリダイレクト
}
—
現場のエンジニアへ:明日からのアクションプラン
1. 「とりあえず許可」をやめる: デフォルト拒否(Default Deny)を徹底せよ。
2. 属性の可視化: 現在のシステムで「IP」「時刻」「デバイス情報」がログとして取得できているか確認せよ。これらがなければABACは実装できない。
3. まずは「時刻」と「IP」から: 難解なポリシー言語を覚える前に、まずは「深夜の管理画面アクセスを遮断する」といった単純なABACから着手しよう。
セキュリティ・チーフからの教訓
セキュリティは「一度設定して終わり」の静的な壁ではない。攻撃者が環境を変化させる以上、我々の制御もまた、常に「文脈(コンテキスト)」に応じて変化し続けなければならない。
ツールに依存せず、この「コンテキストを判定するロジック」を自身のアーキテクチャに組み込む勇気を持ってほしい。それが、君たちのプロダクトを真の意味で守る唯一の道だ。
何か実装で詰まったら、いつでも聞きに来い。現場のコードは嘘をつかない。
コメント