ストーリー
高橋アーキテクトが要件書を渡しました。
課題概要
| 項目 | 内容 |
|---|---|
| 対象システム | マルチテナント SaaS プロジェクト管理ツール |
| 課題数 | 4つ |
| 合計時間 | 60分 |
| 評価基準 | 各課題の設計ドキュメントを作成すること |
システム要件
- テナント(組織)ごとにプロジェクトとタスクを管理
- ロール: オーナー、管理者、メンバー、ゲスト
- 外部IdP(Google、GitHub)でのSSO対応
- APIはモバイルアプリとWebアプリから利用
課題1: 認証方式を選択しよう(15分)
要件に基づいて最適な認証方式を選択し、理由を説明してください。
検討ポイント
- Web/モバイルの両対応
- SSO(Google、GitHub)対応
- セッション管理方式
- MFAの組み込み方
解答例(自分で設計してから確認しよう)
選択: OIDC + JWT
理由:
- OIDC: Google/GitHubとのSSO連携に標準対応
- JWT: Web/モバイル両方でステートレスに認証可能
- アクセストークン: 短命(15分)のJWT
- リフレッシュトークン: 長命(7日)、DBに保存して無効化可能
// 認証フロー設計
const authFlow = {
// 1. SSO認証
ssoLogin: "OIDC Authorization Code Flow + PKCE",
// 2. トークン設計
tokens: {
accessToken: {
type: "JWT",
expiry: "15min",
claims: ["sub", "tenantId", "role", "permissions"],
},
refreshToken: {
type: "opaque",
expiry: "7days",
storage: "database(無効化可能)",
},
},
// 3. MFA
mfa: {
method: "TOTP(Google Authenticator互換)",
required: "管理者以上は必須、メンバーは任意",
enforcement: "ログイン時 + 機密操作時",
},
};
課題2: ロールと権限を設計しよう(15分)
4つのロール(オーナー、管理者、メンバー、ゲスト)の権限マトリクスを作成してください。
解答例(自分で設計してから確認しよう)
type Role = "owner" | "admin" | "member" | "guest";
const permissionMatrix: Record<Role, string[]> = {
owner: [
"tenant:manage", // テナント設定の変更
"tenant:billing", // 課金管理
"members:invite", // メンバー招待
"members:remove", // メンバー削除
"members:role:change", // ロール変更
"projects:create",
"projects:read",
"projects:update",
"projects:delete",
"tasks:create",
"tasks:read",
"tasks:update",
"tasks:delete",
"tasks:assign",
],
admin: [
"members:invite",
"members:remove",
"projects:create",
"projects:read",
"projects:update",
"projects:delete",
"tasks:create",
"tasks:read",
"tasks:update",
"tasks:delete",
"tasks:assign",
],
member: [
"projects:read",
"tasks:create",
"tasks:read",
"tasks:update", // 自分が担当のタスクのみ
"tasks:assign", // 自分へのアサインのみ
],
guest: [
"projects:read", // 招待されたプロジェクトのみ
"tasks:read", // 招待されたプロジェクトのタスクのみ
],
};
権限マトリクス表:
| 操作 | オーナー | 管理者 | メンバー | ゲスト |
|---|---|---|---|---|
| テナント設定変更 | o | x | x | x |
| メンバー招待 | o | o | x | x |
| プロジェクト作成 | o | o | x | x |
| プロジェクト閲覧 | o | o | o | o(制限付) |
| タスク作成 | o | o | o | x |
| タスク編集 | o | o | o(自分のみ) | x |
| タスク削除 | o | o | x | x |
課題3: テナント分離を設計しよう(15分)
テナント分離のモデルを選択し、実装方針を記述してください。
解答例(自分で設計してから確認しよう)
選択: 行レベル分離(RLS) + テナントコンテキスト自動付与
理由:
- SaaS のスケーラビリティを考慮(テナント数が多くなる想定)
- PostgreSQL のRLSで DB レベルでの強制分離
- コスト効率が良い
// 1. テナントIDの伝播
const tenantMiddleware = async (req: Request, res: Response, next: NextFunction) => {
const tenantId = req.user.tenantId;
// DBセッションにテナントIDを設定
await db.query("SET app.current_tenant = $1", [tenantId]);
req.tenantId = tenantId;
next();
};
// 2. Prismaでの自動フィルタリング
const tenantPrisma = (tenantId: string) => {
return prisma.$extends({
query: {
project: {
async findMany({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
},
task: {
async findMany({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
},
},
});
};
// 3. キャッシュキーにテナントIDを含める
const cacheKey = (tenantId: string, resource: string, id: string) => {
return `tenant:${tenantId}:${resource}:${id}`;
};
課題4: ゼロトラストポリシーを定義しよう(15分)
コンテキストベースのアクセス制御ポリシーを3つ以上定義してください。
解答例(自分で設計してから確認しよう)
const zeroTrustPolicies: Policy[] = [
{
name: "テナント設定変更はMFA必須",
condition: (ctx) =>
ctx.action.startsWith("tenant:") &&
!ctx.subject.mfaVerified,
effect: "deny",
action: "require_mfa",
},
{
name: "不審なIPからのアクセスは追加認証",
condition: (ctx) =>
ctx.environment.riskScore > 60 ||
ctx.environment.geoLocation !== ctx.subject.usualLocation,
effect: "deny",
action: "step_up_auth",
},
{
name: "非管理端末からのデータエクスポート禁止",
condition: (ctx) =>
ctx.action === "data:export" &&
ctx.environment.deviceTrust !== "managed",
effect: "deny",
action: "block",
},
{
name: "深夜の管理操作は制限",
condition: (ctx) => {
const hour = ctx.environment.time.getHours();
return (
ctx.subject.role === "admin" &&
ctx.action.includes("delete") &&
(hour < 6 || hour > 22)
);
},
effect: "deny",
action: "block_with_notification",
},
];
達成度チェック
| 課題 | テーマ | 完了 |
|---|---|---|
| 課題1 | 認証方式の選択 | [ ] |
| 課題2 | ロールと権限の設計 | [ ] |
| 課題3 | テナント分離の設計 | [ ] |
| 課題4 | ゼロトラストポリシーの定義 | [ ] |
まとめ
| ポイント | 内容 |
|---|---|
| 認証方式 | 要件に基づいてOIDC + JWTなど最適な方式を選択 |
| 権限設計 | ロールと権限のマトリクスを明確に定義 |
| テナント分離 | スケーラビリティとセキュリティのバランス |
| ゼロトラスト | コンテキストベースのポリシーで動的制御 |
チェックリスト
- 認証方式を要件に基づいて選択・設計できた
- ロールと権限のマトリクスを作成できた
- テナント分離のモデルを選択し実装方針を定められた
- ゼロトラストポリシーを具体的に定義できた
次のステップへ
お疲れさまでした。認証・認可の設計演習が完了しました。 次はStep 3のチェックポイントです。
推定所要時間: 60分