概要
役割管理(Role Management)は、ユーザーに直接「権限」を付与するのではなく、 「ロール(役割)」に権限を束ね、ユーザーへロールを割り当てる設計です。 代表的なモデルは RBAC(Role-Based Access Control)、 条件ベースで柔軟に判定する ABAC(Attribute-Based Access Control) です。
RBAC の利点
- 権限の集約管理(監査しやすい)
- 配属/異動の運用に強い(ロール付替えで権限更新)
- UI/コードがシンプルになりやすい
ABAC の利点
- 属性(ユーザー/リソース/環境)で柔軟に制御
- 動的ポリシー(勤務時間・IPレンジ等)に対応
- 細粒度アクセスが必要な大規模基盤で有効
基礎
用語:User / Role / Permission / Policy / Resource / Scope
| 要素 | 説明 | 例 |
|---|---|---|
| Role | 権限の集合 | admin / editor / viewer |
| Permission | 具体的な操作の許可 | user.write, content.publish |
| Policy | 判定ルール(RBAC/ABAC) | 勤務時間内のみ許可、部署=営業 |
| Scope | 対象範囲 | プロジェクト単位、組織単位 |
基本
PHP: ロール/権限チェック
function has_role(string $role): bool {
return current_role() === $role;
}
function can(string $permission) : bool {
global $ROLE_PERMISSIONS;
$role = current_role();
if (!$role) return false;
return in_array($permission, $ROLE_PERMISSIONS[$role] ?? [], true);
}
// 使い方
if (has_role('admin')) {
// 管理メニュー表示
}
if (can('content.publish')) {
// 公開ボタンを有効化
}
フロントエンドでのUI制御
DOM要素に data-requires="admin" のように付けるだけで、JSが自動で表示/非表示を切り替えます。
🔧 管理コンソール
role=admin で見える
role=admin で見える
✍️ コンテンツ編集
role=editor 以上で見える
role=editor 以上で見える
👁️ 閲覧ダッシュボード
role=viewer 以上で見える
role=viewer 以上で見える
導入
- ロール/権限 の命名規則を定義(例:
resource.action) - システム境界(フロント/バック/API/DB)の責務とチェック箇所を決める
- 監査ログ(誰が・いつ・何を)を最低限入れる
- 最小権限の原則(不要な権限を付けない)
- ロール設計の棚卸しサイクルを決める(四半期など)
開発現場
APIミドルウェア(疑似コード)
function requirePermission(string $perm, callable $handler) {
if (!can($perm)) {
http_response_code(403);
echo json_encode(['error'=>'forbidden','need'=>$perm]);
return;
}
$handler();
}
requirePermission('user.write', function() {
// ユーザー作成処理…
});
SQL: シンプルなRBACスキーマ例
CREATE TABLE users(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(64) UNIQUE,
display_name VARCHAR(128)
);
CREATE TABLE roles(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(64) UNIQUE
);
CREATE TABLE permissions(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(128) UNIQUE
);
CREATE TABLE user_roles(
user_id BIGINT, role_id BIGINT,
PRIMARY KEY(user_id, role_id)
);
CREATE TABLE role_permissions(
role_id BIGINT, permission_id BIGINT,
PRIMARY KEY(role_id, permission_id)
);
最新情報
実運用では、IdP(例:Keycloak / Auth0)やゲートウェイ、ポリシーエンジン(例:Casbin / OPA)との連携情報をここに集約しましょう。
- 監査ログのダッシュボード(失敗した認可を含む)
- ロール棚卸しレポート(過剰権限の検知)
- 特権操作のワークフロー(申請・承認)
応用
ABACの導入
ユーザー属性(部署/雇用形態)、リソース属性(機密度/オーナー組織)、環境属性(アクセス元IP/曜日/時間帯)を加味したルールにします。
// 疑似: ABACポリシー
$ctx = [
'user' => ['dept'=>'sales', 'employment'=>'fulltime'],
'resource' => ['owner_dept'=>'sales', 'classification'=>'internal'],
'env' => ['ip'=>'203.0.113.10', 'time'=>'09:10']
];
function abac_allow(array $ctx): bool {
// 例: 部署一致 & 勤務時間(9-18) 内のみ許可
$hour = intval(substr($ctx['env']['time'],0,2));
return $ctx['user']['dept'] === $ctx['resource']['owner_dept']
&& $hour >= 9 && $hour < 18;
}
発展
- マルチテナントでのロール分離(tenant_id 付与)
- 権限の階層化(role の継承 / permission の名前空間)
- 監査やSoD(職務分離)のルール強化
- OPA/RegoやCasbinモデルでの宣言的ポリシー
例
PHP: ビューでの出し分け
<?php if (can('content.publish')): ?>
<button class="btn">公開する</button>
<?php else: ?>
<button class="btn warn" disabled>公開権限がありません</button>
<?php endif; ?>
アクセス行列(例)
| 操作 | viewer | editor | admin |
|---|---|---|---|
| 記事閲覧(content.read) | ✅ | ✅ | ✅ |
| 記事編集(content.write) | ❌ | ✅ | ✅ |
| 公開(content.publish) | ❌ | ✅ | ✅ |
| ユーザー作成(user.write) | ❌ | ❌ | ✅ |
| ロール管理(role.write) | ❌ | ❌ | ✅ |