diff --git a/2.1-object-tree-schema.md b/2.1-object-tree-schema.md index 0c63182..55c7786 100644 --- a/2.1-object-tree-schema.md +++ b/2.1-object-tree-schema.md @@ -121,6 +121,21 @@ Parent / child関係はWorldspaceにおける**所有または内包**を表す Protocolでは`Object`自体にchildrenとpathを含めず、`fetch_tree`の`ObjectTreeNode`としてObjectとchildrenをまとめる。ValidatorはObjectに含まれる。各nodeのpathは、request pathを起点にObjectの`name`を辿って導出する。このwrapperはObjectとは別のdomain entityを導入するものではなく、Tree traversalのresponse shapeである。 +## Objectの可視性 + +Hostは、主体に認識させるObjectだけでClient-facing Worldspaceを構成する。ObjectをWorldspaceへ公開することは、そのpathとObjectの公開情報を主体が認識できることを意味する。 + +主体に認識させないObjectは、そのWorldspaceに存在しないものとして扱う。 + +- `fetch_tree`では、そのObjectと、そのObjectだけを経由して到達するsubtreeを省略する。 +- 省略されたObjectやchild数を示すredaction markerは返さない。 +- そのpathを指定した`fetch`には、Host内部での存在理由にかかわらず`NotFound`を返す。Object取得に対する`PermissionDenied`は使用しない。 +- `truncated`は、その主体へ公開されたindexable childrenについて判定する。非公開Objectを省略したことだけを理由に`true`にしない。 + +Objectを公開しながら、Objectが参照するInterfaceから一部のOperationを除外することや、公開されたOperationの実行を認可時に拒否することはできる。Operationの可視性と`PermissionDenied`の使い分けは[2.2. Interface / Operation](2.2-operation.md)で定義する。 + +Objectの`description`には、その主体へ公開できる説明だけを含める。安全な説明を公開できない場合はoptionalな`description`を省略できるが、Protocolはfield-level redaction markerを定義しない。Objectの本文やdomain dataの部分的な開示は、各Operationのresult schemaとdomain semanticsで表現する。 + ## `fetch` `fetch(path)`は、指定されたpathで現在公開されている一つのObjectを観測する。 @@ -146,8 +161,8 @@ fetch_tree(path, depth, limit) -> ObjectTree - `depth`は起点Objectを`0`とする最大深さ。 - `limit`はresponse全体に含めるObject数の上限。 - 起点Objectはlimitへ含める。 -- `depth`または`limit`によって存在するindexable childを省略した場合は、responseで`truncated = true`を返す。 -- 要求範囲内のindexable childをすべて含む場合は、`truncated = false`を返す。 +- `depth`または`limit`によって、その主体へ公開されたindexable childを省略した場合は、responseで`truncated = true`を返す。 +- 要求範囲内でその主体へ公開されたindexable childをすべて含む場合は、`truncated = false`を返す。 Tree responseは各nodeにObjectを含み、Clientはrequest pathとchildrenの`name`から各Objectのpathを導出する。各ObjectはHostが発行したvalidatorを持ち得るため、Clientは導出したpathとvalidatorから条件付きOperationのtargetを構築できる。 diff --git a/2.2-operation.md b/2.2-operation.md index b24db42..e5e9468 100644 --- a/2.2-operation.md +++ b/2.2-operation.md @@ -62,19 +62,27 @@ Operationの用途は短いdocumentationで説明する。長文documentationや fetch_interface(interface) -> Interface Descriptor ``` -ObjectはInterface参照だけを持ち、Descriptorを先行同梱しない。ClientはInterface cacheと参照を比較し、未知のDescriptorだけを取得する。 +ObjectはInterface参照だけを持ち、Descriptorを先行同梱しない。ClientはInterface cacheと参照を比較し、未知のDescriptorだけを取得する。Hostは主体へ公開したObjectが参照するDescriptorを、その主体から取得可能にしなければならない。 HostはClientのcache状態を推測して、要求されていないDescriptorをObject responseへ追加しない。複数のDescriptor取得はTransport Bindingでbatchできる。 ## Operationの可視性 -Hostは、主体の権限やrole / capabilityに基づいて、その主体へ公開するInterfaceを決定してよい。 +Hostは、主体の権限やrole / capabilityに基づいて、その主体へ公開するInterfaceを決定してよい。同じObjectでも、主体ごとに異なるInterface参照を返してよい。 + +Operationを主体に認識させない場合、HostはそのOperationを含まないInterfaceをObjectから参照する。そのOperation名を推測して`call_operation`しても、現在公開されているInterfaceに宣言されていないため`OperationNotFound`を返す。 + +Operationの存在を公開しつつ実行だけを認めない設計も可能である。この場合はOperationをInterfaceに宣言し、`call_operation`時のauthorizationで拒否して`PermissionDenied`を返す。 + +したがって、Hostは主体に対して次を独立に選択できる。 + +- Object自体を公開せず、Objectへの`fetch`とOperation callを`NotFound`にする。 +- Objectを公開するが、特定OperationをInterfaceから除外する。 +- ObjectとOperationを公開するが、そのOperationの実行を`PermissionDenied`にする。 Operationの可視性は、頻繁に変化する実行可否やdomain stateを表すものではなく、**その主体に対してどのInterfaceを公開するか**というprojectionとして扱う。 -同じObjectでも、主体ごとに異なるInterface参照を返してよい。 - -WIPはOperationの`available` / `disabled`のような揮発的状態をInterfaceへ同期することを前提としない。現在状態を判断する必要がある場合は、必要に応じてdomain固有のOperationで観測する。最終的なauthorizationと実行条件の判定は`call_operation`時にHostが行う。 +WIPはOperationの`available` / `disabled`のような揮発的状態をInterfaceへ同期することを前提としない。現在状態を判断する必要がある場合は、必要に応じてdomain固有のOperationで観測する。公開されたOperationについても、最終的なauthorizationと実行条件の判定は`call_operation`時にHostが行う。 ## `call_operation` @@ -99,6 +107,8 @@ HostはOperationを実行する前に、次を検証する。 4. Argumentsがparameter declarationに従っている。 5. ClientがOperationを実行できる。 +対象Objectが現在のClient-facing Worldspaceへ公開されていない場合は`not_found`、Operationが現在公開されているInterfaceに宣言されていない場合は`operation_not_found`、宣言されたOperationの実行が認められない場合は`permission_denied`を返す。 + Validatorの比較とOperation実行はatomicに行う。一致しない場合、HostはOperationを実行せず`validator_mismatch`を返す。Hostがvalidatorを要求するOperationに指定がない場合は`validator_required`を返す。 Argumentsに未知のfieldがある場合、必須parameterがない場合、またはvalueが宣言型に一致しない場合、HostはOperationを実行せず`invalid_arguments`を返す。 diff --git a/3-protocol.md b/3-protocol.md index a5abb25..eaa3523 100644 --- a/3-protocol.md +++ b/3-protocol.md @@ -397,6 +397,8 @@ type FetchResponse = Object; Requestの`path`はresponseに重複して含めない。Root path `/`ではObjectの`name`が空文字列でなければならず、非root pathでは最後のsegmentとObjectの`name`が一致しなければならない。Clientは一致しないresponseを`InvalidResult`として扱う。 +指定pathのObjectがその主体のClient-facing Worldspaceへ公開されていない場合、Host内部での存在理由にかかわらず`NotFound`を返す。`fetch`はObject取得の認可失敗として`PermissionDenied`を返さない。Objectを返すこと自体が、そのpathとObjectの公開情報を主体へ認識させるためである。 + 返されたObjectが`validator`を持つ場合、Clientはrequest pathとObjectを対応付けてcacheし、条件付きOperationの`target`を構築できる。Batch Transport Bindingも各itemのrequestとresponseを一意に対応付けなければならない。 ## `fetch_tree` @@ -424,11 +426,14 @@ struct FetchTreeResponse { - 起点Objectはdepth `0`とする。 - `limit`はrootを含むresponse全体のnode数に適用する。 - Root nodeのObjectはrequest pathが指すObjectであり、Root pathが`/`でない場合は最後のsegmentとObjectの`name`が一致する。 +- Request pathのObjectがその主体へ公開されていない場合は`NotFound`を返す。 - 各childのpathは、parent pathへchild Objectの`name`を追加して導出する。 - 同じparent nodeのchildrenは、互いに異なる`name`を持つ。 - `children`はWorldspace上の直接の子だけを含む。 -- `depth`または`limit`によって存在するindexable childを省略した場合、`truncated = true`とする。 -- 要求範囲内のindexable childをすべて含む場合、`truncated = false`とする。 +- `depth`または`limit`によって、その主体へ公開されたindexable childを省略した場合、`truncated = true`とする。 +- 要求範囲内でその主体へ公開されたindexable childをすべて含む場合、`truncated = false`とする。 +- その主体へ公開されていないObjectはresponseへ含めず、存在や省略を示すmarkerも返さない。 +- 非公開Objectを省略したことだけを理由に`truncated = true`としてはならない。 各nodeのObjectがvalidatorを持つため、Clientはrequest pathとObjectの`name`から各pathを導出し、Treeから発見したObjectを再度`fetch`せずに条件付きOperationのtargetを構築できる。 @@ -457,6 +462,8 @@ Clientは次を検証する。 Interface参照はHostが発行するopaque stringである。Clientは参照をcache keyとして使用し、同じ有効な参照から異なるDescriptorを受け取った場合はProtocol failureとして扱う。 +Hostは、主体へ公開したObjectの`interface`が参照するDescriptorを、その主体の`fetch_interface`で取得可能にしなければならない。現在公開されていないInterface参照には`InterfaceNotFound`を返し、Descriptor取得の認可失敗として`PermissionDenied`は使用しない。 + ## `call_operation` 指定pathにあるObjectへOperationを実行する。 @@ -483,6 +490,14 @@ struct CallOperationResponse { `arguments`はOperation parameterに対応する名前付きrecordである。引数がない場合は空のmapを送る。 +Hostは、現在その主体へ公開しているObjectとInterfaceに基づいてOperationを解決する。 + +- `target.path`のObjectが公開されていない場合は`NotFound`を返す。 +- 現在公開されているInterfaceに`operation`が宣言されていない場合は`OperationNotFound`を返す。 +- 宣言されたOperationの存在を公開しつつ、その主体による実行を認めない場合は`PermissionDenied`を返す。 + +したがって、HostはOperationをInterfaceから除外して存在を非公開にすることも、Interfaceへ含めたうえで実行時に拒否することもできる。 + `target.validator`が指定された場合、Hostは現在のvalidatorとの比較とOperation実行をatomicに行う。一致しない場合はOperationを実行せず`ValidatorMismatch`を返す。Hostがvalidatorを要求するOperationに指定がない場合は`ValidatorRequired`を返す。 Hostはvalidatorの生成方法と無効化する状態変化を決定する。Content hash、generation、database revision等を使用できる。比較はopaque bytesの完全一致で行う。 @@ -523,7 +538,9 @@ enum ProtocolErrorCode { `message`は人間向けのboundedな診断であり、Clientが分岐に使用する安定した値ではない。Clientは`code`を使用する。 -Hostは情報漏洩を避けるため、存在するが閲覧できないObjectに`NotFound`を返してもよい。 +Objectを主体へ公開しない場合、HostはそのObjectをClient-facing Worldspaceに存在しないものとして扱い、`fetch`、`fetch_tree`、`call_operation`へ`NotFound`を返す。Objectの存在を秘匿する目的で`PermissionDenied`を返してはならない。 + +`PermissionDenied`は、現在公開されているInterfaceに宣言されたOperationについて、その存在を公開しつつ実行を認めない場合に使用する。Operation自体をInterfaceから除外している場合は`OperationNotFound`を返す。 Protocol failureとdomain failureを混在させない。現在のProtocolでは、Domain failureをApplicationのOperation resultに含まれるUnion caseとして明示する。専用のfailure envelopeは定義しない。 diff --git a/draft/unresolved-issues.md b/draft/unresolved-issues.md index f380911..7cc385f 100644 --- a/draft/unresolved-issues.md +++ b/draft/unresolved-issues.md @@ -2,12 +2,6 @@ 主要な未解決事項を、canonicalなCore文書とTransport Bindingへのindexとしてまとめる。 -## 2.1. Object tree / Schema - -対象: [2.1. Object tree / Schema](../2.1-object-tree-schema.md) - -- Partial visibility、redaction、authorization failureの表現。 - ## 2.2. Interface / Operation 対象: [2.2. Interface / Operation](../2.2-operation.md) diff --git a/draft/wip-over-https.md b/draft/wip-over-https.md index 5880e08..326ba52 100644 --- a/draft/wip-over-https.md +++ b/draft/wip-over-https.md @@ -254,7 +254,7 @@ Protocol failureをJSON response bodyへ含める場合、概念的に次の形 `code`はProtocolが定義する安定した識別子、`message`は人間向けのboundedな診断である。Clientは`message`の内容で分岐しない。 -Protocol error codeとHTTP statusのmapping、認証情報を漏らさないための`not_found`と`permission_denied`の使い分け、validation errorのstructured detailは未確定である。 +Protocol error codeとHTTP statusのmapping、およびvalidation errorのstructured detailは未確定である。`not_found`、`operation_not_found`、`permission_denied`の使い分けはProtocolのObject / Operation visibility semanticsに従い、HTTP statusへのmappingによって変更しない。 Domain failureをProtocol errorへ変換しない。Domain failureはOperation resultのApplication dataとしてencodeする。