From c8c93ad4ad82707ce0fcb5ced1b621d7be15d96a Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Thu, 29 Jan 2026 23:29:28 +0900 Subject: [PATCH 1/7] =?UTF-8?q?docs:=20policy=E3=81=AB=E3=81=A4=E3=81=84?= =?UTF-8?q?=E3=81=A6=E8=A8=98=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/authorization.md | 137 +++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 89 deletions(-) diff --git a/src/authorization.md b/src/authorization.md index 51a04a3..d58034f 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -1,90 +1,49 @@ -# アクセス制御 +# 認可制御 + +このドキュメントでは,Pulsate API(v0) における認可制御について記述する. + +## 用語 + +- `Actor`: アクションを実行する主体.ほとんどの場合で`Account`が該当する. +- `Action`: リソースに対して行う何らかの操作のこと. +- `Resource`: `Action`の対象となるもの. +- `Policy`: `Actor`が`Action`を実行するための条件. + +## 全体像 +- Pulsate API での認可制御は Policy クラスによって定義される. +- Policy クラス は `isAllowed` static メソッドを持ち,actor, action, resource の3値を要求する. + - `isAllowed` メソッドは `Option.Option` を返す. + - 要求が拒否された場合は `Option.Some` を返し,要求が承認された場合は `Option.None()` を返す. + +```ts +interface PolicyArgs { + actor: Actor, + action: Action, + resource: Resource +} + +type NotePolicyArgs = PolicyArgs + +class NotePolicy { + static isAllowed(args: NotePolicyArgs): Option.Option { + // 略 + } +} +``` + +### PolicyScope +Action は識別子 PolicyScope を用いて識別する. + +- PolicyScope は3つの要素からなる文字列である. +- 要素は以下の通り. + - 1: ポリシー名 + - 2: モデル名 (例: `account`, `note`) + - モデルではないものも含む (例: `follow` ). + - タイムラインの場合はタイムライン種別名とする (例: `home`, `conversation`) + - 3: アクション名 (例: `fetch`, `update`) +- これらは以下で示す型で表現できる形式に従って結合される. +```ts +type PolicyScope = `${PolicyName}.${ModelName}:${ActionName}` +``` +- `isAllowed` メソッドは,PolicyScope のポリシー名が自分が管理するものでない場合,エラーを返す. -## アカウントのロール - -ロールは自分以外のアカウントに対して操作を実行可能であるかを制御する. - -表1: 可能な操作一覧 - -| 操作名 | 備考 | `Admin` | `Moderator` | -| :--------------: | :------------------------------------------: | :-----: | :---------: | -| 他アカウント | 凍結、サイレンスの実行、アカウント情報の閲覧 | Y | Y | -| ノート/メディア | ノート/メディアの削除 | Y | Y | -| 通報に関する操作 | 通報の確認/解決、警告の送信 | Y | Y | -| 不要メディア削除 | どこからも参照されないメディアの削除 | Y | N | -| 統計情報 | 稼働統計情報の閲覧 | Y | Y | -| システム設定 | 設定値の閲覧/変更 | Y | N | -| お知らせ | お知らせの送信、編集 | Y | N | -| カスタム絵文字 | 登録、無効化、削除 | Y | Y | -| 他インスタンス | インスタンスのサイレンス/ブロック | Y | N | - -※ Y: 操作、閲覧が可能 / N: 操作、閲覧が不可能 - -### Admin (管理者) - -管理者.\ -全ての操作が実行可能. - -### Moderator (モデレーター) - -モデレーター.\ -(自他問わず)インスタンス、お知らせ以外の操作を実行可能 - -> [!IMPORTANT] -> -> モデレーターは一般ロールのアカウントに対する操作のみ実行可能. - -### Normal (一般) - -通常のユーザー.\ -自分のリソースに対する操作のみを行うことが可能. - -## メールアドレス検証状態 - -メールアドレスの検証が行われたかを示すもの. - -### notActivated (メールアドレス未検証) - -メールアドレスの検証が行われていない状態.\ -検証が行われていないアカウントは一定期間(設定可能)経過後に自動で削除される(設定で行わないことも可能) - -メールアドレス検証トークンの再送信のリクエスト と アカウント削除 のみ実行可能. - -### Active (メールアドレス検証済み) - -メールアドレスの検証が行われたことを示す状態. - -設定されているロールの権限に基づく全ての操作が実行可能になる. - -## アカウント状態 - -アカウントの現在の状態を示すもの. - -### Notmal(通常) - -通常の状態.\ -設定されているロール権限に基づく全ての操作が実行可能. - -> [!IMPORTANT] -> -> ただし、メールアドレス検証状態が`notActivated`である場合はそちらが優先される - -### Frozen(凍結済み) - -凍結済み状態.\ -ログインを含む全ての操作が**実行不可能**.\ -そのアカウントの投稿, -メディアは`Admin`/`Moderator`ロール以外のアカウントから閲覧できなくなる. - -> [!IMPORTANT] -> -> 凍結状態が解除(解凍)された場合は、投稿やメディアは他のアカウントから閲覧可能になる. - -### Silenced(サイレンス済み) - -サイレンス済み状態.\ -そのアカウントは新規投稿の公開範囲で`PUBLIC`を選択できなくなる - -> [!IMPORTANT] -> -> サイレンス状態が解除されても、サイレンス中に行われた投稿の公開範囲は変更されない. From 56c6b629b5073e668e812a5a2d5ab5e771ea4121 Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Fri, 30 Jan 2026 21:52:35 +0900 Subject: [PATCH 2/7] =?UTF-8?q?docs:=20Args=E3=81=AE=E5=9E=8B=E5=90=8D?= =?UTF-8?q?=E3=82=92=E6=9B=B8=E3=81=8D=E7=9B=B4=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/authorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/authorization.md b/src/authorization.md index d58034f..2f11a31 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -22,7 +22,7 @@ interface PolicyArgs { resource: Resource } -type NotePolicyArgs = PolicyArgs +type NotePolicyArgs = PolicyArgs class NotePolicy { static isAllowed(args: NotePolicyArgs): Option.Option { From e71755e294fec7c01757639f5da84edded347a47 Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Fri, 30 Jan 2026 21:53:32 +0900 Subject: [PATCH 3/7] chore: fmt --- src/authorization.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/authorization.md b/src/authorization.md index 2f11a31..453036f 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -10,19 +10,22 @@ - `Policy`: `Actor`が`Action`を実行するための条件. ## 全体像 + - Pulsate API での認可制御は Policy クラスによって定義される. -- Policy クラス は `isAllowed` static メソッドを持ち,actor, action, resource の3値を要求する. +- Policy クラス は `isAllowed` static メソッドを持ち,actor, action, resource + の3値を要求する. - `isAllowed` メソッドは `Option.Option` を返す. - - 要求が拒否された場合は `Option.Some` を返し,要求が承認された場合は `Option.None()` を返す. + - 要求が拒否された場合は `Option.Some` を返し,要求が承認された場合は + `Option.None()` を返す. ```ts interface PolicyArgs { - actor: Actor, - action: Action, - resource: Resource + actor: Actor; + action: Action; + resource: Resource; } -type NotePolicyArgs = PolicyArgs +type NotePolicyArgs = PolicyArgs; class NotePolicy { static isAllowed(args: NotePolicyArgs): Option.Option { @@ -32,6 +35,7 @@ class NotePolicy { ``` ### PolicyScope + Action は識別子 PolicyScope を用いて識別する. - PolicyScope は3つの要素からなる文字列である. @@ -42,8 +46,10 @@ Action は識別子 PolicyScope を用いて識別する. - タイムラインの場合はタイムライン種別名とする (例: `home`, `conversation`) - 3: アクション名 (例: `fetch`, `update`) - これらは以下で示す型で表現できる形式に従って結合される. + ```ts -type PolicyScope = `${PolicyName}.${ModelName}:${ActionName}` +type PolicyScope = `${PolicyName}.${ModelName}:${ActionName}`; ``` -- `isAllowed` メソッドは,PolicyScope のポリシー名が自分が管理するものでない場合,エラーを返す. +- `isAllowed` メソッドは,PolicyScope + のポリシー名が自分が管理するものでない場合,エラーを返す. From 660726a0bbfcc5ea6fb5fb912650732a4685440a Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Sat, 31 Jan 2026 00:23:28 +0900 Subject: [PATCH 4/7] =?UTF-8?q?chore:=20action=E5=90=8D=E3=82=92=E6=98=8E?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/authorization.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/authorization.md b/src/authorization.md index 453036f..b942950 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -4,8 +4,10 @@ ## 用語 -- `Actor`: アクションを実行する主体.ほとんどの場合で`Account`が該当する. +- `Actor`: アクションを実行する主体.`Account`が該当する. - `Action`: リソースに対して行う何らかの操作のこと. + - `read`: 読み取り + - `write`: 書き込み,更新(リソースが更新可能な場合),リソースの削除 - `Resource`: `Action`の対象となるもの. - `Policy`: `Actor`が`Action`を実行するための条件. From 4ca21c64574ec8e4860bd5e767cc0ffe4b6abe17 Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Mon, 2 Feb 2026 00:40:53 +0900 Subject: [PATCH 5/7] =?UTF-8?q?chore:=20=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E5=90=8D=E3=82=92check=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/authorization.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/authorization.md b/src/authorization.md index b942950..7378975 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -14,9 +14,9 @@ ## 全体像 - Pulsate API での認可制御は Policy クラスによって定義される. -- Policy クラス は `isAllowed` static メソッドを持ち,actor, action, resource +- Policy クラス は `check` static メソッドを持ち,actor, action, resource の3値を要求する. - - `isAllowed` メソッドは `Option.Option` を返す. + - `check` メソッドは `Option.Option` を返す. - 要求が拒否された場合は `Option.Some` を返し,要求が承認された場合は `Option.None()` を返す. @@ -30,7 +30,7 @@ interface PolicyArgs { type NotePolicyArgs = PolicyArgs; class NotePolicy { - static isAllowed(args: NotePolicyArgs): Option.Option { + static check(args: NotePolicyArgs): Option.Option { // 略 } } @@ -46,12 +46,12 @@ Action は識別子 PolicyScope を用いて識別する. - 2: モデル名 (例: `account`, `note`) - モデルではないものも含む (例: `follow` ). - タイムラインの場合はタイムライン種別名とする (例: `home`, `conversation`) - - 3: アクション名 (例: `fetch`, `update`) + - 3: アクション名 - これらは以下で示す型で表現できる形式に従って結合される. ```ts type PolicyScope = `${PolicyName}.${ModelName}:${ActionName}`; ``` -- `isAllowed` メソッドは,PolicyScope +- `check` メソッドは,PolicyScope のポリシー名が自分が管理するものでない場合,エラーを返す. From 18de4b3ad834a19f59807c17264a831dfad73b93 Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Tue, 3 Feb 2026 01:56:46 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20=E5=88=A4=E5=AE=9A=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=81=8C=E9=96=A2=E6=95=B0=E3=82=92?= =?UTF-8?q?=E5=8F=97=E3=81=91=E5=8F=96=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=97=EF=BC=8C=E3=82=AB=E3=83=AA=E3=83=BC=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/authorization.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/authorization.md b/src/authorization.md index 7378975..bf25bb8 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -9,16 +9,14 @@ - `read`: 読み取り - `write`: 書き込み,更新(リソースが更新可能な場合),リソースの削除 - `Resource`: `Action`の対象となるもの. +- `Target`: 操作が許可されたときに使用する,操作を行うまたは操作後のリソースを保存するもの. - `Policy`: `Actor`が`Action`を実行するための条件. ## 全体像 - Pulsate API での認可制御は Policy クラスによって定義される. -- Policy クラス は `check` static メソッドを持ち,actor, action, resource - の3値を要求する. - - `check` メソッドは `Option.Option` を返す. - - 要求が拒否された場合は `Option.Some` を返し,要求が承認された場合は - `Option.None()` を返す. +- Policy クラスは `withCheck` static メソッドを持ち,actor, action, resource, targetの3値,および関数 `fn` を要求する. + - `withCheck` メソッドはジェネリクス `` を受け取る.`Target` は target の型,`Res` は `fn` の返値である. ```ts interface PolicyArgs { @@ -30,8 +28,15 @@ interface PolicyArgs { type NotePolicyArgs = PolicyArgs; class NotePolicy { - static check(args: NotePolicyArgs): Option.Option { - // 略 + static withCheck(target: Target): (args: NotePolicyArgs, fn: (target: Target) => Promise>) => Promise> { + return async ( + args: AccountPolicyArgs, + fn: (target: Target) => Promise> + ): Promise> => { + if (!args.actor) return Result.err(Error("ログインしないと使えません")); + // 条件を満たしたときだけ実行する + return await fn(target); + }; } } ``` @@ -53,5 +58,5 @@ Action は識別子 PolicyScope を用いて識別する. type PolicyScope = `${PolicyName}.${ModelName}:${ActionName}`; ``` -- `check` メソッドは,PolicyScope +- `withCheck` メソッドは,PolicyScope のポリシー名が自分が管理するものでない場合,エラーを返す. From 602e45f3ff9146a195b8dd03a11eba1a7756b01f Mon Sep 17 00:00:00 2001 From: Tatsuto YAMAMOTO Date: Tue, 3 Feb 2026 01:57:21 +0900 Subject: [PATCH 7/7] chore: format --- src/authorization.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/authorization.md b/src/authorization.md index bf25bb8..c645648 100644 --- a/src/authorization.md +++ b/src/authorization.md @@ -9,14 +9,17 @@ - `read`: 読み取り - `write`: 書き込み,更新(リソースが更新可能な場合),リソースの削除 - `Resource`: `Action`の対象となるもの. -- `Target`: 操作が許可されたときに使用する,操作を行うまたは操作後のリソースを保存するもの. +- `Target`: + 操作が許可されたときに使用する,操作を行うまたは操作後のリソースを保存するもの. - `Policy`: `Actor`が`Action`を実行するための条件. ## 全体像 - Pulsate API での認可制御は Policy クラスによって定義される. -- Policy クラスは `withCheck` static メソッドを持ち,actor, action, resource, targetの3値,および関数 `fn` を要求する. - - `withCheck` メソッドはジェネリクス `` を受け取る.`Target` は target の型,`Res` は `fn` の返値である. +- Policy クラスは `withCheck` static メソッドを持ち,actor, action, resource, + targetの3値,および関数 `fn` を要求する. + - `withCheck` メソッドはジェネリクス `` を受け取る.`Target` は + target の型,`Res` は `fn` の返値である. ```ts interface PolicyArgs { @@ -28,10 +31,15 @@ interface PolicyArgs { type NotePolicyArgs = PolicyArgs; class NotePolicy { - static withCheck(target: Target): (args: NotePolicyArgs, fn: (target: Target) => Promise>) => Promise> { + static withCheck( + target: Target, + ): ( + args: NotePolicyArgs, + fn: (target: Target) => Promise>, + ) => Promise> { return async ( - args: AccountPolicyArgs, - fn: (target: Target) => Promise> + args: AccountPolicyArgs, + fn: (target: Target) => Promise>, ): Promise> => { if (!args.actor) return Result.err(Error("ログインしないと使えません")); // 条件を満たしたときだけ実行する