権限
トークンがどの組織に紐づくか、そしてすべてのリクエストが通る 4 つの検査。接続スコープ、アクションスコープ、役割、そしてモジュールです。
リクエストは 4 つの検査を通ります。拒否はどの検査で失敗したかを示し、それぞれ失敗の理由が異なるため、4 つすべてを知っておく価値があります。
どの検査よりも前に、ひとつだけ既に決まっていることがあります。
組織はパラメータではない
グラントは人が同意した時点で 1 つの組織に紐づき、すべてのリクエストは組織をトークンから解決します。クライアントが送る値でそれを変えることはできません。 この API 全体で 27 個のリクエスト本文があり、organizationId を受け付けるものは 1 つもありません。 そのうち 26 個は未知のプロパティもそのまま拒否するので、送ることはヒントではなくエラーです。
13 個のレスポンスは organizationId を返します(承認、商品、価格表、見積、ドキュメントテンプレート、保存済みリポート、ダッシュボード)。それは常に呼び出し元自身のものです。データにラベルを付けるために読むのはよいですが、誰のデータを読むかを選ぶために使ってはいけません。
GET /capabilities はそれを返しません。クライアントがどの組織のトークンを持っているかを知っているのは、同意の場に居合わせたからであり、API が教えてくれるからではありません。
1 トークン、1 組織。 2 つのワークスペースを扱うクライアントは 2 つのグラントと 2 つのトークンを持ち、自分でそれらを分けて管理します。
1. 接続スコープ
トークンは 1 つのリソースに対応し、各リソースにはスコープが 1 つあります。REST リソースには api.access、MCP には mcp.access が必要です。offline_access はリフレッシュトークンを得るためのものです。
*.access 形式のスコープはこの 3 つだけです。 cpq.access や reports.access を要求することはできません。テナントのモジュールはクライアントが要求するものではなく、ワークスペース側で設定され、サーバーが検査します。
2. アクションスコープ
エンドポイントのスコープはそのアクションそのものです。 GET /api/v1/objects/{objectId}/records には records.read が必要です。それがこのエンドポイントの行うアクションだからです。各エンドポイントのスコープはリファレンスに記載されています。
アクションは 21 個あります。
objects.bootstrap objects.read objects.manage
records.read records.write
prices.read prices.manage
quotes.read quotes.write
reports.read reports.manage
documents.read documents.generate documents.manage
approvals.read approvals.submit approvals.decide approvals.manage
marketing.read marketing.manage
settings.manage
使うアクションだけを要求してください。行使しないアクションを持つトークンは、必要以上に大きな権限です。
marketing.read と marketing.manage は付与できますが、対応する外部エンドポイントがありません。呼び出し元はセッション専用のものだけです。予約済みとして扱ってください。
3. メンバーの役割
スコープがトークンに含まれていることと、メンバーの役割がそのアクションを許可していることの両方が必要です。viewer が付与した records.write を持つトークンでも、書き込みはできません。
この API が到達するアクションのみを挙げています。marketing.read と marketing.manage も役割の集合には含まれますが、ここに対応するエンドポイントはありません。
| 役割 | できること |
|---|---|
owner、admin |
すべてのアクション |
member |
viewer が読めるものすべてに加えて records.write、quotes.write、documents.generate、approvals.submit、approvals.decide |
viewer |
objects.read、records.read、prices.read、quotes.read、reports.read、documents.read、approvals.read |
4. ワークスペースのモジュール
多くのアクションはオプションモジュールに属し、ワークスペースがそれを有効にしているかどうかで決まります。モジュールが無効なら、トークンの内容にかかわらずアクションは失敗します。
| モジュール | 所有するアクション |
|---|---|
custom_objects |
objects.manage |
cpq |
prices.read、prices.manage、quotes.read、quotes.write、settings.manage |
reports |
reports.read、reports.manage |
documents |
documents.read、documents.generate、documents.manage |
approvals |
approvals.read、approvals.submit、approvals.decide、approvals.manage |
| コア | objects.read、objects.bootstrap、records.read、records.write |
api モジュールは REST リソース自体を、mcp は MCP を制御します。両者は独立しており、ワークスペースは一方だけを持つこともできます。
GET /api/v1/capabilities を読むと、呼び出し元ができることと有効なモジュールが、両者を読み取った時点の設定リビジョンとともに返ります。拒否から権限を推測するのではなく、これをポーリングしてください。
モジュールが無効化されたとき
モジュールを無効にすると、既存のトークンは有効期限前に拒否されます。この検査は実作業を行うトランザクションの内側でも再実行されるため、わずかに前に受け付けられたリクエストは完了しつつ、後続は拒否されることがあります。
知っておく価値のある 4 つの組み合わせ
エンドポイントに必要なスコープは、名前から想像されるものと必ずしも一致しません。
GET /api/v1/capabilitiesは有効なモジュールを報告しますが、objects.readが必要です。自分の権限を知るにもこれが要ります。PUT /api/v1/settings/commercialはsettings.manageとcpqモジュールの両方が必要です。GET /api/v1/documents/{id}、/retry、/downloadはdocuments.readではなくdocuments.generateが必要です。読み取り専用のクライアントは、自分が要求していない生成状況をポーリングできません。POST /api/v1/bootstrapとレコードの読み書きはコアです。モジュールは不要で、スコープと役割だけで決まります。
クライアントの権限を変更する
クライアントの登録スコープを更新し、同意を取り直してください。同意はそれが対象とするリソースを記録し、トークンはそのうち 1 つを指名するため、リソースを対象としなくなった同意はそのリソースのトークンを発行しなくなります。スコープ変更前に発行されたトークンが新しいスコープを得ることはありません。