Strapi v5 でチーム運用するためのロール設計ガイド
Strapi v5のAdmin権限システムを活用して、ブログ担当・ニュース担当・管理者でアクセス権を分離する方法を解説します。DBへの直接操作を含む実践的な設定手順を紹介します。
なぜロール設計が重要なのか
Headless CMSを複数人で運用するとき、全員がAdmin権限を持つのは危険です。誰かが誤ってAboutページやサイト設定を書き換えてしまうリスクがあります。Strapi v5ではロールベースのアクセス制御(RBAC)を使って、ユーザーごとに操作可能なコンテンツタイプを絞り込めます。
今回の構成
このブログでは以下の3ロール体制を構築しました。
- Super Admin:全コンテンツタイプの作成・編集・削除・公開。AboutページやTopページの設定変更も可能。
- Blog Editor:Articleコンテンツタイプの作成・編集・公開と画像アップロードのみ。AboutやTopページには触れない。
- News Editor:Blog Editorと同じ権限範囲。ニュース記事の投稿・管理に特化。
ロールの作成方法
Strapi管理画面(Settings → Administration Panel → Roles)からロールを作成するのが通常の手順です。しかし、コンテンツタイプが増えた後に細かな権限設定を行う場合、DBに直接INSERTする方が確実です。
1. admin_roles テーブルにロールを登録
INSERT INTO admin_roles (name, description, created_at, updated_at)
VALUES
('Blog Editor', 'ブログ記事の作成・編集・公開が可能', NOW(), NOW()),
('News Editor', 'ニュース記事の作成・編集・公開が可能', NOW(), NOW())
RETURNING id;
2. 既存ロールのパーミッションをコピー
Editorロール(role_id=2)が持つ Article と Upload のパーミッションを、Blog Editor(role_id=4)と News Editor(role_id=5)にコピーします。AboutやTop Pageのパーミッションは含めないことがポイントです。
WITH src AS (
SELECT p.action, p.subject, p.properties,
p.conditions, p.action_parameters
FROM admin_permissions p
JOIN admin_permissions_role_lnk l ON l.permission_id = p.id
WHERE l.role_id = 2
AND (p.subject = 'api::article.article'
OR p.subject IS NULL) -- uploadはsubject=NULL
),
ins4 AS (
INSERT INTO admin_permissions
(document_id, action, action_parameters,
subject, properties, conditions,
created_at, updated_at)
SELECT
substr(md5(random()::text || action || '4'), 1, 24),
action, action_parameters, subject,
properties, conditions, NOW(), NOW()
FROM src
RETURNING id
)
INSERT INTO admin_permissions_role_lnk
(permission_id, role_id, permission_ord)
SELECT id, 4, row_number() OVER () FROM ins4;
3. ユーザーを作成してロールを割り当て
パスワードはbcryptjsでハッシュ化します。Strapiコンテナ内のNodeで生成できます。
// Strapiコンテナ内で実行
// docker exec strapi node -e "..."
const bcrypt = require('bcryptjs');
const hash = bcrypt.hashSync('YourPassword2026!', 10);
console.log(hash);
WITH new_user AS (
INSERT INTO admin_users
(document_id, firstname, lastname, email,
password, is_active, blocked,
prefered_language, locale,
created_at, updated_at)
VALUES (
substr(md5(random()::text), 1, 24),
'Blog', 'Editor',
'[email protected]',
'$2a$10$...bcrypt_hash...',
true, false, 'ja-JP', 'en',
NOW(), NOW()
)
RETURNING id
)
INSERT INTO admin_users_roles_lnk
(user_id, role_id, role_ord, user_ord)
SELECT id, 4, 1, 1 FROM new_user;
管理画面でのロール確認
設定完了後、Blog EditorアカウントでStrapi管理画面にログインすると、サイドメニューに Content Manager → Article だけが表示されます。AboutやTop Pageのメニューは見えません。これにより、担当外のコンテンツを誤って変更するリスクをゼロにできます。
注意点:typeフィールドによる記事種別の分離
現在の構成では Blog Editor と News Editor は同一の Article コンテンツタイプにアクセスします。記事の type フィールド(blog / news )で区別はしていますが、フィールドレベルの書き込み制限はStrapiの標準機能では設定できません。運用ルールで「Blog EditorはtypeをblogにSet」を徹底するか、将来的にコンテンツタイプを分離することを検討してください。
まとめ
- Strapi v5のRBACはDB直接操作で柔軟に設定できる
- パーミッションはコンテンツタイプ単位で付与・拒否が可能
- ロールをコピーして作成すると、設定漏れが起きにくい
- AboutやTop Pageなど変更頻度の低いコンテンツは管理者専用に絞ることでリスクを軽減できる