Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Linked Web Storage Protocol仕様は、アプリケーションに対し、外部に保存されたデータへの安全で許可に基づく アクセスを相互運用可能な方法で提供することを目的とする。
この節は、この 文書の公開時点における位置付けを説明する。現在のW3C 公開物の一覧およびこの技術報告書の最新版は、 W3C標準および草案 インデックスで確認できる。
これは非公式な提案である。
この文書は、Linked Web Storageワーキング グループにより、 勧告 トラックを用いる作業草案として公開された。
作業草案としての公開は、 W3Cおよびそのメンバーによる承認を 意味しない。
これは草案文書であり、いつでも他の文書により更新、置換、または廃止される可能性がある。 この文書を進行中の作業以外のものとして引用することは不適切である。
この文書は、 W3C 特許 ポリシー の下で運営されるグループにより作成された。 W3Cは、このグループの成果物に関連して行われた 特許開示の公開一覧 を管理している。そのページには、 特許を開示するための手順も含まれる。個人が、 必須クレーム を含むとその個人が信じる特許について実際の知識を有する場合、 W3C特許ポリシー第6節 に従ってその情報を開示しなければならない。
この文書は、 2025年8月18日のW3Cプロセス文書 によって管理される。
この節は非規範的である。
LWSプロトコルは、ある主体が何らかのリソースを何らかのエージェントに利用可能にできる標準的なやり取りを定義する。
リソース管理者は、提供リソースを 非公開に保つことも、誰にでも公開することも、その可視性を制約された一群の 要求エージェントに限定することもできる。
非規範的と明示された節に加え、この仕様におけるすべての作成ガイドライン、図、例、および注記は 非規範的である。この仕様のそれ以外のすべては規範的である。
この文書におけるキーワードMAY、MUST、MUST NOT、OPTIONAL、RECOMMENDED、REQUIRED、SHOULD、およびSHOULD NOTは、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されるとおりに解釈される。
LWSサーバーは、この仕様における関連するすべての「MUST」 文に適合するHTTPサーバー[rfc9112]である。具体的には、 この文書の9. 操作における関連する規範的な「MUST」文を尊重MUSTする。
LWS クライアントは、この仕様における関連するすべての「MUST」文に適合するHTTPクライアント[rfc9112]である。具体的には、この文書の9. 操作における関連する規範的な 「MUST」文をMUST尊重する。
「authorization server」および「client」という用語は、OAuth 2.0 Authorization Framework [RFC6749]によって定義される。
「end-user」および「issuer」という用語は、OpenID Connect Core 1.0 [OPENID-CONNECT-CORE]によって定義される。
この仕様は、次の用語を定義する:
この節は、Linked Web Storageサーバーとやり取りするエージェントおよびエンドユーザーを識別するためのメカニズムを定義する。 この仕様は、認証資格情報の特定の形式を義務付けないが、既存の身元システムを Linked Web Storage認可フレームワークと組み合わせて使用する方法を記述する。
この節で記述されるデータモデルは、認証資格情報の任意の 具体的なシリアル化に対する要件を概説する。
認証資格情報は、主体に関する改ざん明示的なクレームを含まなければMUSTならず、これには次が含まれる:
認証資格情報の検証には、検証者と資格情報の発行者との間の信頼 関係が必要である。この信頼関係は、アウトオブバンドのメカニズムを通じて確立されてもMAYよい。 検証者と発行者との間の信頼を確立するための追加メカニズムは、特定の認証スイートで概説される。
認証資格情報は署名されなければMUSTならない。署名には非対称暗号を用いることがRECOMMENDEDされる。
各認証スイートは、トークン型URIに関連付けられなければMUSTならない。 認証スイートは、IANA「OAuth URI」レジストリで定義されたURIを使用すべきSHOULDである。
ストレージ記述リソースは、クライアントが ストレージとやり取りする際に使用できる情報を提供し、 機能およびサービスエンドポイントの記述を含む。
id - idプロパティはREQUIREDである。その値は、ストレージを識別するURIでなければMUSTならない。
type - typeプロパティはREQUIREDである。その値は、
Storageに等しい文字列、またはStorageに等しい項目を含む文字列の集合
(大文字小文字を区別する)でなければMUSTならない。
capability - capabilityプロパティはOPTIONALである。その値は、機能の集合でなければMUSTならず、
各機能は次のプロパティを含むマップによって記述される。
追加のプロパティが存在してもMAYよい。
id - idプロパティはOPTIONALである。存在する場合、その値はURIでなければMUST
ならない。type - typeプロパティはREQUIREDである。その値は文字列
または文字列の集合でなければMUSTならない。service - serviceプロパティはREQUIREDである。その値はサービスの集合でなければMUSTならず、
各サービスは次のプロパティを含むマップによって記述される。追加の
プロパティが存在してもMAYよい。
id - idプロパティはOPTIONALである。存在する場合、その値はURIでなければMUST
ならない。type - typeプロパティはREQUIREDである。その値は文字列
または文字列の集合でなければMUSTならない。serviceEndpoint - serviceEndpoint
プロパティはREQUIREDである。その値はURIでなければMUST
ならない。{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "https://storage.example/",
"type": "Storage",
"service": [{
"type": "StorageDescription",
"serviceEndpoint": "https://storage.example/description"
}]
}
ストレージリソースを対象とする
GETおよびHEAD要求に対するすべての応答は、
ストレージ
記述リソースのURIをターゲットとし、
値が
https://www.w3.org/ns/lws#storageDescriptionに等しい関係
(rel)パラメーターを含むLinkヘッダーを
含まなければMUSTならない。
参照解決された場合、ストレージ記述は、
ストレージを識別するidプロパティを含まなければ
MUSTならない。さらに、serviceプロパティは、
型がStorageDescriptionに等しく、そのserviceEndpointが
ストレージ記述のURLに等しい
サービス記述を含まなければMUSTならない。
StorageDescriptionサービスに加えて、
ストレージ記述リソースは、
ストレージに接続された他のサービスへのリンクを含んでもよい。
これらのサービスのAPI定義は、この仕様の範囲外である。
ストレージ記述リソースは、
メディア型application/lws+jsonでシリアル化可能でなければMUSTならない。
他の表現は、コンテンツネゴシエーションを介して利用可能であってもMAYよい。
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "https://storage.example/",
"type": "Storage",
"capability": [{
"type": "https://feature.example/PatchSupport",
"mediaType": {
"text/turtle": ["application/sparql-update"],
"application/n-triples": ["application/sparql-update"],
"application/linkset+json": ["application/merge-patch+json", "application/json-patch+json"]
}
}, {
"type": "https://feature.example/ResumableUploads"
}, {
"type": "https://feature.example/ContentNegotiation",
"source": "application/ld+json",
"target": ["text/turtle", "application/n-triples"]
}, {
"type": "https://feature.example/ContentNegotiation",
"source": "image/jpeg",
"target": ["image/png"]
}],
"service": [{
"type": "NotificationService",
"serviceEndpoint": "https://storage.example/notification/api",
"subscriptionType": ["WebhookSubscription"]
}, {
"type": "TypeIndexService",
"serviceEndpoint": "https://storage.example/types/index"
}, {
"type": "TypeSearchService",
"serviceEndpoint": "https://storage.example/types/search"
}, {
"type": "DataSharingService",
"serviceEndpoint": "https://storage.example/sharing/api"
}, {
"type": "StorageDescription",
"serviceEndpoint": "https://storage.example/description"
}]
}
Linked Web Storageは、リソースをコンテナに編成する。コンテナは、 メンバーと呼ばれる他のリソースへの参照を保持する特殊化されたリソースである。コンテナは、 ディレクトリまたはコレクションに類似した編成単位として機能し、クライアントがリソースをグループ化、発見、 およびナビゲートできるようにする。コンテナは、そのメンバーリソースへの参照を保持し、 それらは非コンテナリソースと追加のコンテナリソースの両方から構成されてもよく、それにより 階層的な構成が可能になる。通常、コンテナは、メンバーのメタデータまたは列挙を超える 最小限の固有コンテンツを保持し、その主な役割は下位リソースを集約し構造化することである。 ストレージシステムのルートはコンテナとして指定され、 上位の親を持たない最上位の編成単位として機能する。コンテナは、'ContainerPage'型を使用して メンバーシップ一覧のページネーションをサポートしなければMUSTならず、'first'、 'next'、'prev'、および'last'などのプロパティを用いる。表現は、特定のフレームおよび規範的コンテキストを伴う JSON-LDを使用しなければMUSTならず、任意で'Vary: Accept'ヘッダーを介して コンテンツネゴシエーションを広告してもよい。 ストレージは、ルートコンテナとして機能し、直接書き込みを可能にしてもMAYよい。
すべてのLWSストレージには、最上位の編成単位として機能するストレージ ルートがある。ストレージルートは親を持たず、 ストレージ 階層へのエントリーポイントとして機能する。
LWS内のリソースは、次のいずれかに分類される:
リソースとその親コンテナとの間の包含関係は、rel="up"リンク
関係によって表現される。サーバーは、任意の
非ルートリソースに対するGETおよびHEAD要求への応答において、親コンテナを指す
rel="up"を持つLinkヘッダーを含めなければMUSTならない。
Link: </alice/notes/>; rel="up"
コンテナのメンバーは、その表現内で
itemsプロパティを用いて一覧化される。サーバーがこの一覧を管理するため、クライアントは直接変更できない。
メンバーシップの変更は、リソースの作成および削除の副作用として発生する。
サーバーは、常に包含の完全性を維持しなければMUSTならない:
リソースはURIによって識別される。リソースのURIは、包含階層における位置とは独立している。サーバーは、リソース作成時にURIを割り当て、
クライアントヒント(例: Slugヘッダー)を組み込んでもMAYよいが、
クライアントはURI構造が包含を反映していると仮定すべきではSHOULD NOTない。
包含関係は、URIパス構造ではなく、メタデータ
(rel="up"リンクおよびコンテナ
表現内のitemsプロパティ)を通じて表現される。この分離により、明確に定義された編成モデルを維持しながら、
サーバーはURI割り当てに柔軟性を持てる。
クライアントがコンテナを取得する場合、サーバーは、そのコンテナおよびその内容を記述する構造化されたコンテナ 表現を返す。この節は、 コンテナ表現の必須および任意のプロパティを定義する。
コンテナ表現は、次のプロパティを含まなければMUSTならない:
items配列内の各エントリーは、コンテナ内に含まれるリソースを記述する。包含リソース記述は、
次を含まなければMUSTならない:
id: 含まれるリソースのURI。type: リソースの型。"DataResource"または
"Container"、あるいはこれら2つの文字列の少なくとも一方を含む配列でなければMUSTならない。
サーバーは、追加のユーザー定義型をURIとして含めてもMAYよい
(例: ["DataResource", "http://example.org/customType"])。
包含リソース記述は、次を含むべきSHOULDである:
mediaType: リソースのメディア型(例:
"text/plain"、"image/jpeg")。DataResourcesについては存在しなければ
MUSTならない。
size: リソースのサイズ(バイト単位)。整数として表現される。
modified: リソースが最後に変更された日時。
ISO 8601日時文字列として表現される。次の例は、2つのリソースを含む/alice/notes/にあるコンテナを示している:
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "/alice/notes/",
"type": "Container",
"totalItems": 2,
"items": [
{
"type": "DataResource",
"id": "/alice/notes/shoppinglist.txt",
"mediaType": "text/plain",
"size": 47,
"modified": "2025-11-24T12:00:00Z"
},
{
"type": ["DataResource", "http://example.org/customType"],
"id": "/alice/notes/todo.json",
"mediaType": "application/json",
"size": 2048,
"modified": "2025-11-24T13:00:00Z"
}
]
}
この節は、Linked Web Storage(LWS)サーバーがサポートしなければMUSTならない4つの中核操作を定義する。これらの操作は、リソースおよびコンテナを トランスポート非依存の方法で操作し、実装の詳細ではなく意味論に焦点を当てる。各操作は、 入力、期待される振る舞い、および可能な応答を指定する。応答には、成功インジケーター、リソース 表現(該当する場合)、およびエラー条件が含まれる。実装は、これらの操作を原子的かつ一貫して処理しなければMUST ならない。つまり、各操作は完全に成功するか、部分的な副作用なしに失敗する。エラーの場合、応答は、 機密情報を漏えいすることなく問題をエージェントが理解できる十分な詳細を提供すべきSHOULDである。
各中核操作(作成、読み取り、更新、削除)について、使用するHTTPメソッド、必須の ヘッダーまたは特別な考慮事項(ETagによる同時実行制御、コンテンツネゴシエーション、および コンテナ一覧のページネーションを含む)、ならびにサーバーが行い返すべき内容を記述する。標準HTTPステータスコードは 結果を示すために使用され、クォータ超過(507 Insufficient Storage)または前提条件失敗(412 Precondition Failed)などのシナリオに対する追加のマッピングを伴う。 このバインディングは、Web標準と自然に統合されるように、HTTP/1.1および 関連RFC(HTTP意味論のための[RFC7231]、 範囲要求のための[RFC7233]、 PATCHのための[RFC5789]、Web Linkingのための[RFC8288]、 およびLink Setsのための[RFC9264]など)に 従うことを試みる。発見可能性は、Linkヘッダーや401応答上のWWW-Authenticateヘッダーのようなメカニズムを通じて重視され、 ハードコードされたURI位置を避ける。メタデータ統合は操作全体で必須であり、原子性ならびにサーバー管理および ユーザー管理プロパティのためのLink Setsの使用を保証する。
注記: この仕様におけるすべての例と同様に、この節で示される例(HTTP要求
および応答スニペット)は非規範的であり、典型的な使用法を示すことを目的とする。実際の
要件は、説明文および表で述べられる。また、このバインディングはHTTP(初期の
対象プロトコルとして)を扱うが、LWS操作は将来的には原則として他のプロトコルにバインドされ得る。
サーバーは、コンテナ表現について、
application/lws+json、
application/ld+json、およびapplication/jsonのコンテンツネゴシエーションをサポートしなければMUSTならない
(11. LWSメディア型を参照)。サーバーはMAYさらにTurtleのような形式をサポートしてもよい。
この節は、LWSリソースに メタデータを関連付けるモデルを定義する。LWSメタデータシステムは、Web Linking [RFC8288]の原則に基づいており、 サーバーが型付きリンクを使用してリソース間の関係を記述できるようにする。メタデータは、 発見可能性を高め、自己記述的APIをサポートし、リソース操作およびコンテナ階層と整合する。
メタデータモデル LWSにおけるすべてのメタデータは、リソース(リンクコンテキスト)から発生する型付きリンクの集合として表現される。 各リンクは次から構成される:
メタデータは、リソースとその表現を区別し、該当する場合には複数のメディア型を 可能にする。データリソースについて、メタデータには表現が含まれ、それぞれが mediaTypeおよび任意のsizeInBytesを持つ。コンテナおよびデータリソースについては、 その親コンテナリソースへのリンクを、そのリソースのメタデータの一部とみなす。
リンクセットリソース ストレージ内の各リソースについて、サーバーは[RFC9264]に従い、 メタデータリンクを独立したリソースとして利用可能にしなければMUSTならない。
rel="linkset"関係を持つLinkヘッダーを介して発見可能である。
application/linkset+jsonとして
利用可能でなければMUSTならない。メタデータの発見 クライアントは、主にGETまたはHEAD要求への応答内のLinkヘッダーを通じてメタデータを発見する。
rel="storageDescription"を持つLinkヘッダーをサポートしなければMUSTならない。
rel="up"を持つLinkヘッダーを含めなければMUSTならない。
https://www.w3.org/ns/lws#PreferLinkRelationsを持つPreferヘッダー[RFC7240]を使用してもMAYよい。
メタデータ型
| カテゴリ | 説明 |
|---|---|
| システム管理 | サーバーにより維持される。読み取り専用。linkset、type、
mediaType、size、modifiedを含む。
|
| 中核メタデータ | クライアントにより管理される(サーバー制限に従う)。up、
items、title、creatorを含む。
|
| ユーザー定義 | ユーザーが作成したカスタム語彙およびインデックス。 |
変更可能性に関する考慮事項 中核メタデータはクライアントによって変更されてもMAYよい。相互運用性を確保するため、サーバーは 標準HTTPヘッダーを用いて自身の機能を広告しなければMUSTならない:
メソッド発見: サーバーは、Allowヘッダーを介してリンクセットリソース上のGETおよびPATCH 操作のサポートを広告しなければMUSTならない。
パッチ形式の発見: サーバーは、Accept-Patchヘッダーを介してJSON Merge
Patch [RFC7386]のサポートを広告しなければMUSTならない:
Accept-Patch: application/merge-patch+json.
任意メソッド: サーバーはPUTまたは代替パッチ形式をサポートしてもMAYよい。 サポートする場合、それらはそれぞれAllowおよびAccept-Patch ヘッダーに含められなければMUSTならない。
[!IMPORTANT] クライアントは、リソースヘッダーで広告されていない限り、PUTまたは特定のパッチ形式のサポートを 仮定すべきではSHOULD NOTなく、405 Method Not Allowedまたは415 Unsupported Media Type応答を適切に処理しなければMUSTならない。
メタデータの管理 メタデータは、リソースに関連付けられたリンクセットリソース URIとやり取りすることで管理される。サーバーは、更新のための同時実行制御をサポートしなければMUSTならない。
部分更新(PATCH): これはメタデータ管理の主要なメカニズムである。サーバーは、
application/merge-patch+jsonを使用するPATCHをサポートしなければMUSTならない。
置換(PUT): Allowヘッダーで広告される場合、クライアントはリンクセット全体を置換してもMAY よい。サーバーがPUTをサポートしない場合、サーバーは405 Method Not Allowedで要求を拒否しなければMUST ならない。
制限: サーバーは、システムの完全性を維持するために、特定のリンク(
upまたはitemsなど)への変更を制限してもMAYよい。
ライフサイクル: メタデータのライフサイクルは、記述されるリソースに結び付けられる。リソースの削除は、 その関連するリンクセットリソースメタデータの自動削除をもたらさなければMUSTならない。
リソースを作成する操作は、新しい提供リソースを既存のコンテナに追加する。この 操作は、データリソースおよびサブコンテナの作成の両方を扱う。
入力:
振る舞い:
可能な応答:
新しいリソースは、対象コンテナURIへのPOSTを使用して作成され、サーバーが
最終的な識別子を割り当てる。クライアントはSlugヘッダーを介して名前を提案してもMAYよい。
クライアントは、[RFC8288]におけるWeb Linkingの構文に従って、
POST要求に1つ以上のLinkヘッダーを含めることで、新しいリソースの初期ユーザー管理メタデータを提供してもMAYよい。
サーバー管理メタデータは、作成時にサーバーによって自動的に生成されなければMUST
ならず、クライアント提供リンクによって上書きされてはMUST NOTならない。
成功時、サーバーは201ステータスコードを、Locationヘッダー内の新しいURIとともに返さなければMUSTならない。
サーバーは、親コンテナ
(rel="up")へのリンク、および作成されたリソース専用のリンクセットリソースへのリンク
(rel="linkset"; type="application/linkset+json")を含む、主要なサーバー管理メタデータの
Linkヘッダーを含めなければMUSTならない。追加リンクは、rel="type"(
https://www.w3.org/ns/lws#Containerまたは
https://www.w3.org/ns/lws#DataResourceを示す)を含むべきSHOULDである。本文は空でもMAYよく、または
リソースの最小表現を含んでもよい。すべてのメタデータ作成およびリンク付けは、一貫性を維持するために、
リソース作成と原子的でなければMUSTならない。
POST(コンテナURIへ) – サーバー割り当て名で作成:
既存のコンテナ内に新しいリソースを追加するにはPOSTを使用する。サーバーはリソースに識別子を割り当て、
任意でSlugヘッダーを介して提案される。サーバーは、命名規則または既存
リソースと競合しない場合、Slugヘッダーを尊重してもMAYよい。クライアントは、作成するリソースの型を次のように示す:
rel="type"を持つLinkヘッダーを含めなければMUSTならない:
Link: <https://www.w3.org/ns/lws#Container>; rel="type".
Content-Typeヘッダーとともに、要求本文にリソースコンテンツを含める。例(新しいデータリソースを作成するPOST):
POST /alice/notes/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Type: text/plain
Content-Length: 47
Slug: shoppinglist.txt
milk
eggs
bread
butter
apples
orange juice
この例では、クライアントはコンテナ/alice/notes/へPOSTしている。
text/plainコンテンツ(買い物リスト)を提供し、新しいリソースの名前として
shoppinglist.txtを提案している。/alice/notes/が存在し、クライアントが
認可されている場合、サーバーは新しいデータリソースを作成し、それをコンテナのメンバーシップに追加する。
例(POSTへの応答 — データリソース):
HTTP/1.1 201 Created
Location: /alice/notes/shoppinglist.txt
Content-Type: text/plain; charset=UTF-8
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Content-Length: 0
成功時、Locationヘッダー内の新しいURIとともに201 Createdを返す。本文は
空でも、最小表現でもよい。
対象コンテナ/alice/notes/が存在しない場合、別のステータスコードがより適切でない限り、サーバーは
404エラーステータスを返さなければMUSTならない。
コンテナの作成: 新しいコンテナを作成するには、クライアントはContainer型を示す
Linkヘッダーを持つ、既存の親コンテナへのPOSTを使用する。
例:
POST /alice/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Length: 0
Slug: notes
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
例(POSTへの応答 — コンテナ):
HTTP/1.1 201 Created
Location: /alice/notes/
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Content-Length: 0
これは、/alice/notes/に新しいコンテナを作成し、rel="type"を
https://www.w3.org/ns/lws#Containerとして含むサーバー生成メタデータを伴う。
Create(HTTPバインディング)に関する追加注記:
rel="storageDescription"を持つLinkヘッダーを含めるべきSHOULDである。
メタデータの管理および取得(作成に関連):
メタデータは主に読み取り操作を介して取得されるが、作成時に生成される。クライアントは、
作成後すぐに、新しいリソースURI上でGETまたはHEADを使用してそれを取得できる。クライアントは、
Preferヘッダーを使用して、特定のメタデータリンク(関係型を介する)および
属性の包含を要求できる。
既存リソースの表現、またはコンテナの一覧を取得する。
リソースを読み取る操作は、HTTP GET要求(およびヘッダーのみの要求のためのHEAD)で
リソース表現を要求する。振る舞いは、対象URLがコンテナであるか、非コンテナリソース(データリソース)であるかにより異なる。サーバーはメタデータを介して
リソース型を区別しなければMUSTならない。すべての応答は、
rel="linkset"、rel="up"、およびrel="type"などの主要な関係のLinkヘッダーを含め、
第8.1節で定義されるメタデータと統合されなければMUSTならない。サーバーは、読み取り中にリソース状態とそのメタデータとの原子性を保証しなければMUSTならない。
GET(非コンテナリソース) – リソースのコンテンツを取得: 完全なコンテンツ(認可されている場合)を得るために、リソースURIへGETを送信する。200 OKで応答し、本文には データを含め、Content-Typeは保存されたメディア型に一致する。サーバーは、部分 取得のために[RFC7233]に従う範囲要求をサポートしなければMUSTならない。応答は、同時実行制御および キャッシュのためにETagヘッダーを含まなければMUSTならない。
例(ファイルをGETする):
GET /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
Accept: text/plain
これは、/alice/notes/shoppinglist.txtのコンテンツを要求し、クライアントが
テキスト形式で望むことを示している。リソースが存在し、テキストであり、クライアントがアクセス権を持つと仮定すると:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 34
ETag: "abc123456"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
milk
cheese
bread
guacamole
soda
chocolate bars
hash
eggs
サーバーは、テキストコンテンツ(Content-Lengthで示されるとおり合計34バイト)を返した。
コンテンツは、ファイルに保存されたデータそのものである。ETag: "abc123456"は、キャッシュまたは同時実行のための
バージョン識別子である。応答には、メタデータの発見可能性のためのLinkヘッダーが含まれ、
upおよびtypeなどの必須フィールドを伴う。
GET(コンテナリソース) – コンテナの内容を一覧化: 対象URIがコンテナ(メタデータ型により判定)に対応する場合、GET要求は コンテナのメンバー一覧を返す。応答本文は、LWSコンテナメディア 型を使用する、コンテナ表現節で定義されるコンテナ表現である。 一覧には、各メンバーのメタデータが含まれる: リソース識別子(MUST)、型(MUST)、メディア型(DataResourcesについてはMUST)、サイズ(SHOULD)、および 変更タイムスタンプ(SHOULD)。
例(コンテナをGETする):
GET /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Accept: application/ld+json
コンテナが存在し、クライアントがアクセス権を持つと仮定すると:
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "container-etag-789"
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "/alice/notes/",
"type": "Container",
"totalItems": 2,
"items": [
{
"type": "DataResource",
"id": "/alice/notes/shoppinglist.txt",
"mediaType": "text/plain",
"size": 47,
"modified": "2025-11-24T12:00:00Z"
},
{
"type": ["DataResource", "http://example.org/customType"],
"id": "/alice/notes/todo.json",
"mediaType": "application/json",
"size": 2048,
"modified": "2025-11-24T13:00:00Z"
}
]
}
この例では、/alice/notes/はコンテナである。応答は
LWSコンテキストを持つJSON-LDを使用し、必須メタデータを持つメンバーを一覧化する。各項目は、
フラットなプロパティとしてtype、
id、mediaType、size、およびmodifiedタイムスタンプを含む。
すべての場合において、サーバーは応答
ヘッダーに次のメタデータを含めなければMUSTならない: ETag(メンバーシップ変更時に変化する一覧バージョンを表す)、
それがコンテナであることを示すrel="type"を持つLink
ヘッダー、rel="linkset"および
rel="up"。
HEAD(任意のリソースまたはコンテナ) – ヘッダー/メタデータのみ: LWSサーバーは、コンテナおよび非コンテナの両方についてHEAD [RFC9110]をサポートしなければMUSTならず、 GETと同じヘッダー(ETag、Content-Type、メタデータ用Linkを含む)を返すが、本文は返さない。これにより、コンテンツを 転送することなくメタデータ取得が可能になる。
キャッシュおよび条件付き要求: LWSはHTTPキャッシュ意味論を活用する。サーバーは If-None-Match(ETag付き)または If-Modified-Sinceヘッダーを介する条件付き要求をサポートしなければMUSTならない。リソースまたはコンテナ一覧が変更されていない場合、冗長な転送を避けるために 304 Not Modifiedで応答する。ETagは、同時実行およびキャッシュサポートのために、 すべてのGET/HEAD応答で提供されなければMUSTならない。
発見可能性と認可: 発見可能性を高めるため、サーバーは、 クライアントをハードコードされたURIなしで導くパラメーターを持つWWW-Authenticateヘッダーを401 Unauthorized応答に 含めるべきSHOULDである。該当する場合、メタデータリンクも含めるべきSHOULDである。
完全置換または部分パッチを介して、既存の[提供リソース]の状態を変更する。
リソースを更新するは、 PUT要求(リソース全体を置換するため)またはPATCH要求(部分的な 変更を適用するため)によって、既存の提供 リソースの内容を変更する。クライアントは、これらの 操作を実行するために、リソースのURLへの書き込みアクセス権を持っていなければならない。 注記: この節は、リソースの主要コンテンツの更新について記述する。そのメタデータを更新するには、第 9.3.2節を参照。 LWSサーバーは、リソースURI上のPUTおよびPATCH要求を、リソースコンテンツのみへの 変更として扱わなければMUSTならず、関連付けられたリンクセットリソースへの既定の影響を持たない。任意で、コンテンツと メタデータの両方を単一の原子的操作で更新するために、クライアントはリソースURIへの PUT/PATCH要求にLinkヘッダーを含め、プリファレンス'Prefer: set-linkset'( RFC 7240で定義)を指定してもMAYよい。この場合、サーバーは、提供されたLinkヘッダーを コンテンツ変更の適用に加えて、リンクセットへの置換(PUTの場合)または部分更新(PATCHの場合)として解釈しなければMUST ならない。この振る舞いはサーバーにとってOPTIONALであるが、サポートされる場合、 意図しないメタデータ上書きを防ぐために、Preferヘッダーを介して明示的に呼び出されなければMUSTならない。結合更新をサポートしないサーバーは、 そのプリファレンスを無視するか、501 Not Implementedで応答しなければMUSTならない。
PUT(リソース全体の置換) – 新しい完全なコンテンツを
本文に含め、一致するContent-Type(通常は既存型と整合)を持つPUTをリソースURIへ送信する。PUTは既存
リソースに対して冪等である。安全のため、現在のETagを持つIf-Matchを含める(第7.3節の同時実行に従う)。不一致は
412 Precondition Failedまたは409 Conflictを生じる。検査なしでは更新は無条件だが、
同時変更を上書きする危険がある。サーバーがリソースについてEtagsをサポートする場合、サーバーは
If-Matchヘッダーを欠く無条件PUT要求を428
Precondition Required応答で拒否しなければMUSTならない。
例(リソースを更新するPUT):
PUT /alice/personalinfo.json HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
If-Match: "abc123456"
{
"name": "Alice",
"age": 30,
"city": "New London",
"state": "Connecticut"
}
この例では、クライアントは/alice/personalinfo.jsonにある既存のJSONリソースを更新している。 以前のGETまたはHEAD要求から取得したETag "abc123456"を持つIf-Matchヘッダーを含めている。 サーバーはそれを現在のETagと比較する。一致する場合、提供されたJSONでコンテンツを置換する。 一致しない場合、サーバーは更新を拒否する(その間に他者によってリソースが変更されたため)。 成功応答: 更新が成功した場合、サーバーは200 OKで応答し、 更新された表現または何らかの確認(新しいコンテンツまたはその一部など)を含めてもよい。あるいは、 サーバーは、本文なしで成功を示すために204 No Contentで応答してもよい(特に追加情報を伝える必要がない場合によく使われる)。 いずれの場合でも、サーバーは新しいバージョンを示す新しい ETagを含めるべきSHOULDであり、本文が返される場合はContent-Typeも含めてもよい。例:
HTTP/1.1 204 No Content
ETag: "def789012"
これは、更新が完了したことをクライアントに知らせ、新しいETagを提供する。サーバーが
更新されたコンテンツを返すことを選択した場合、200 OKを使用して本文にJSONを含め、
ヘッダーも伴うことができる。
If-Matchが一致しなかった場合(同時
変更)、サーバーは412 Precondition Failed(前提条件ヘッダーが失敗したことを意味する)または
409 Conflictを返すことができる。上記の抽象的記述では同時実行の問題に
Conflictを使用しており、409はそのシナリオに対する自然なマッピングである。リソースが存在しない場合、
更新としてのPUTは404 Not Foundになる(意図が作成である場合を除くが、通常クライアントは、自分が何をしているか確実な場合にのみ
PUTを作成に使用するか、またはIf-Matchなしのupsertとして使用する)。クライアントが認可されていない場合は
403 Forbidden(または有効な認証情報が提供されていない場合は401 Unauthorized)。要求ペイロードが有効でない場合は
400 Bad Request。
PATCH(部分更新) – HTTP PATCHメソッド[RFC5789]は、 クライアントがリソース全体の新しいコンテンツを送信するのではなく、部分的な変更を指定できるようにする。 これは、全体コンテンツを送信することが非効率な大きなリソースで、小さな部分だけが変更された場合や、 特定の変更を適用したい同時編集に役立つ。LWS サーバーは、[RFC7386]で定義されるJSON Merge Patch(application/merge-patch+json)を 最低限サポートしなければMUSTならない。
リソースメタデータの更新(リンクセット上のHTTP PUT / PATCH) リソースのメタデータは、rel="linkset"を持つLinkヘッダーを介して発見される、対応するリンクセットリソースを 変更することで更新される。 完全置換(PUT): 完全なリンクセット文書を本文に含む、リンクセットリソースURIへのPUT要求は、 リソースのすべてのメタデータを置換する。 部分更新(PATCH): リンクセットリソースURIへのPATCH要求は、特定のリンクを追加、削除、または 変更する。
メタデータの同時実行制御 リソースのメタデータは複数の行為者によって変更され得るため、同時上書きの防止は 重要である。データ完全性を確保するため、LWSサーバーおよびクライアントは、 リンクセットリソース上のすべての PUTおよびPATCH操作について、条件付き要求[RFC7232]を使用する楽観的同時実行制御を実装しなければMUSTならない。 サーバーの責任: サーバーは、リンクセットリソースに対するGETおよびHEAD要求への応答にEtagヘッダーを含めなければMUSTならない。 リンクセット上のPUTまたはPATCHが成功した場合、サーバーは変更されたリンクセットに対して新しい 一意のEtag値を生成し、それを応答のEtagヘッダーで返さなければMUSTならない。 クライアントの責任: リンクセットリソースを変更する場合、クライアントはそのリソースについて受け取った最新のEtagを含む If-Matchヘッダーを含めなければMUSTならない。 処理規則: If-Matchヘッダー値がリンクセットの現在のEtagと一致しない場合、サーバーは 412 Precondition Failedステータスコードで要求を拒否しなければMUSTならない。 リンクセットURIへのPUTまたはPATCH要求からIf-Matchヘッダーが欠けている場合、サーバーは 428 Precondition Requiredステータスコード[RFC6585]で要求を拒否しなければMUSTならない。 例(リンクセットを置換するPUT): クライアントはまずリンクセットを取得し、そのETagを受け取る。
GET /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Accept: application/linkset+json
HTTP/1.1 200 OK
Content-Type: application/linkset+json
ETag: "meta-v1"
{
"linkset": [
{
"anchor": "/alice/personalinfo.json",
"describedby": [ { "href": "/schemas/personal-info.json" } ]
}
]
}
クライアントは今、ライセンスを追加したい。新しい完全なリンクセット文書を構築し、If-Matchヘッダーを持つPUT 要求を送信する。
PUT /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/linkset+json
If-Match: "meta-v1"
{
"linkset": [
{
"anchor": "/alice/personalinfo.json",
"describedby": [ { "href": "/schemas/personal-info.json" } ],
"license": [ { "href": "https://creativecommons.org/licenses/by/4.0/" } ]
}
]
}
成功した場合、サーバーは成功と新しいETagで応答する。
HTTP/1.1 204 No Content
ETag: "meta-v2"
更新規則の概要 リソースのコンテンツだけを変更したい場合 → リソース自体にPUT/PATCHする。 リソースのリンク(メタデータ)だけを変更したい場合 → リソースに関連付けられたリンクセットリソースにPUT/PATCHする。 コンテンツとリンクの両方を変更したい場合 → 適切な Linkヘッダーおよび'Prefer: set-linkset'を含めてリソース自体にPUT/PATCHする。両方を設定することは既定ではオフである。
リソースおよびその関連メタデータを恒久的に削除する。
リソースを削除する操作は、上記の抽象 操作で定義されるように、HTTP DELETEメソッドを使用して実装される。この節は、入力、振る舞い、および応答のHTTPバインディングを指定する。
DELETE要求は、削除するリソースまたはコンテナのURIを対象とする。クライアントは、
同時実行検査のためにETagを持つIf-Matchヘッダーを含めてもMAYよい。
削除と包含:
リソースが削除される場合、サーバーはそれを
親コンテナのitems一覧から原子的に削除しなければMUSTならない。親コンテナの
totalItems数は、それに応じて更新されるべきSHOULDであり、そのETagは
変更を反映するよう更新されなければMUSTならない。
非コンテナリソースについて、サーバーはリソースコンテンツ、その関連メタデータ(リンクセットリソース)、および親コンテナ内の包含参照を 削除する。
コンテナリソースについて、サーバーは既定で非再帰
削除を行う。コンテナが空でなく、再帰が要求されていない場合、サーバーは
409 Conflictで要求を拒否しなければMUSTならない。サーバーは、
削除されるコンテナ内のすべての包含リソースの再帰削除を
サポートしてもMAYよい。クライアントは、
[RFC4918]で定義されるように、再帰削除を要求するために
Depth: infinityヘッダーを使用しなければMUSTならない。
成功時、サーバーは204 No Contentで応答しなければMUSTならない。サーバーは、 [RFC9110]で定義される条件付き要求をサポートすべきSHOULDである。
クライアントが認可を欠く場合、サーバーは403 Forbidden(クライアントの 身元は既知だが権限が不足している場合)または401 Unauthorized(有効な 認証が提供されていない場合)を返さなければMUSTならない。リソースの存在を明らかにすることがセキュリティリスクをもたらす場合、 サーバーは代わりに404 Not Foundを返してもMAYよい。
例(非コンテナリソースをDELETEする):
DELETE /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
If-Match: "abc123456"
ETagが一致し、クライアントが認可されていると仮定すると、サーバーはリソース、そのメタデータを削除し、
親コンテナ/alice/notes/からそれを原子的に削除する:
HTTP/1.1 204 No Content
例(再帰なしで空でないコンテナをDELETEする):
DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
/alice/notes/がリソースを含むと仮定すると、サーバーは削除を拒否する:
HTTP/1.1 409 Conflict
Content-Type: text/plain
Cannot delete container /alice/notes/ - container is not empty.
例(サポートされる場合、再帰でコンテナをDELETEする):
DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Depth: infinity
サーバーが再帰をサポートし、クライアントがすべての内容に対する権限を持つと仮定すると、サーバーは コンテナとその子孫を原子的に削除する:
HTTP/1.1 204 No Content
この表は、ページネーション、同時実行制御、クォータ制約、およびメタデータ統合などの 特定シナリオを組み込みながら、一貫性のために汎用LWS応答(第 8節から)をHTTPステータスコードおよびペイロードへマッピングする:
| LWS応答 | HTTPステータスコード | HTTPペイロード |
|---|---|---|
| 成功(読み取りまたは更新、データを返す 場合) | 200 OK | 応答本文内のリソース 表現(GETの場合、またはPUT/PATCHがコンテンツを返す場合)。 関連ヘッダー(Content-Type、ETag、rel="linkset"、 rel="up"などのメタデータ用Link)を伴う。コンテナ一覧については、規範的コンテキストおよびメンバー メタデータ(ID、型、サイズ、タイムスタンプ)を持つJSON-LDを含める。 |
| 作成済み(新しいリソース) | 201 Created | 通常は応答本文なし(または新しいリソースの最小表現)。
Locationヘッダーは新しいリソースのURIに設定される。ETagのようなヘッダーは
同時実行のために含まれなければMUSTならない。サーバー管理
メタデータ用のLinkヘッダー。
|
| 削除済み(返すコンテンツなし) | 204 No Content | 応答本文なし。リソースが削除された、または要求が成功し、他に伝えることがないことを示す。 サーバーは恒久的な 削除に410 Goneを使用してもMAYよい。 |
| Bad Request(無効な入力または制約) | 400 Bad Request | 何が誤っていたかを説明するエラー詳細。サーバーは、 構造化エラー応答のために、[RFC9457]で定義される標準形式、 たとえば"type"、"title"、 "status"、"detail"、および"instance"のようなフィールドを持つJSONオブジェクトを使用すべきSHOULDである。 |
アクセス要求と許可は、エージェントがリソースへのアクセスを要求し、 ストレージコントローラーが定義された制約付きでアクセスを許可するためのメカニズムを提供する。 アクセスを要求および許可するためのエンドポイントは、特殊化された受信箱の一種として機能する。
エージェントは、 アクセス許可を認可トークンとしてサーバーに提示するわけではない。 むしろ、アクセス許可は、何が、誰に対して、 どの制約の下で認可されたかの記録として機能する。アクセス許可が作成または取消(削除)された場合、 その変更を反映するために基礎となるアクセスポリシーを調整する責任はサーバーにある。 アクセス許可エンドポイントと特定のポリシー 適用層とのやり取りは、この仕様の範囲外である。
この節で定義されるアクセスプロファイルは、 アクション、制約、および譲受人を含む Open Digital Rights Language(ODRL)の概念に基づく。 他のプロファイルは、異なる概念的フレームワークを使用してもよい。
この節は、次の用語を定義する:
conformsToプロパティでそれらを参照することにより、1つ以上のアクセスプロファイルのサポートを示す。
ストレージは、そのストレージ記述リソース内で、
アクセス要求および
アクセス許可のサポートを広告してもMAYよい。
そのようなサポートが広告される場合、アクセス要求用エンドポイントを記述するサービス
オブジェクトは、文字列AccessRequestServiceに等しいtypeを持たなければ
MUSTならず、アクセス許可用エンドポイントを記述する
サービスオブジェクトは、文字列AccessGrantServiceに等しい
typeを持たなければMUSTならない。サービス
オブジェクトは、そのエンドポイントでサポートされるアクセスプロファイルを識別する
1つ以上のURIの集合を値とするconformsToプロパティを含むべきSHOULDである。
追加のプロパティが含まれてもMAYよい:
{
"@context": [
"https://www.w3.org/ns/lws/v1"
],
"id": "https://storage.example/",
"type": "Storage",
"service": [
{
"type": "AccessRequestService",
"serviceEndpoint": "https://access.example/request/",
"conformsTo": ["https://www.w3.org/ns/lws#AccessProfile"]
},
{
"type": "AccessGrantService",
"serviceEndpoint": "https://access.example/grant/",
"conformsTo": ["https://www.w3.org/ns/lws#AccessProfile"]
}
]
}
アクセス要求またはアクセス許可は、
身元およびルーティングのためのプロパティ、ならびに
要求または許可された操作を記述するaccessオブジェクトを表現するデータ
オブジェクトである。ODRL概念を用いてアクセス要求を記述する
プロファイルは、10.3
アクセスプロファイルで記述される。
次の例は、アクセス要求を示す。この例は、 10.4.1 JSON-LDシリアル化で定義されるJSON-LDシリアル化を用いて示される。
{
"@context": [
"https://www.w3.org/ns/lws/v1"
],
"type": ["AccessRequest"],
"inbox": "https://id.example/agent/inbox/",
"storage": "https://storage.example/",
"access": [{
"type": ["AccessPolicy"],
"action": ["read", "create"],
"assignee": "https://id.example/agent",
"target": {
"type": "StorageResource",
"value": ["https://storage.example/projects/"]
},
"constraint": [
{
"leftOperand": "purpose",
"operator": "eq",
"rightOperand": "https://purpose.example/collaboration"
},
{
"leftOperand": "dateTime",
"operator": "lteq",
"rightOperand": "2026-06-09T10:00:00Z"
}
]
}]
}
次の例は、アクセス許可を示す。この例は、 10.4.1 JSON-LDシリアル化で定義されるJSON-LDシリアル化を用いて示される。
{
"@context": [
"https://www.w3.org/ns/lws/v1"
],
"type": ["AccessGrant"],
"storage": "https://storage.example/",
"access": [{
"type": ["AccessPolicy"],
"action": ["read"],
"assignee": "https://id.example/agent",
"target": {
"type": "StorageResource",
"value": ["https://storage.example/projects/"]
},
"constraint": [
{
"leftOperand": "purpose",
"operator": "eq",
"rightOperand": "https://purpose.example/collaboration"
},
{
"leftOperand": "dateTime",
"operator": "lteq",
"rightOperand": "2026-06-09T10:00:00Z"
}
]
}]
}
アクセス要求および アクセス許可には、他のプロパティが存在してもMAYよい。
typeプロパティは、文書の型を表現する。
typeプロパティの値は、1つ以上の
用語および
絶対URL文字列でなければ
MUSTならない。アクセス要求について、その値は用語AccessRequestを
含まなければMUSTならない。
アクセス許可について、その値は用語
AccessGrantを含まなければMUSTならない。
追加の型値が含まれてもMAYよい。
このプロパティはREQUIREDである。
この文書は、アクセス要求および アクセス許可について、次の型値を定義する:
AccessRequest — リソースへのアクセスを求める、エージェントによる要求。
AccessGrant — リソースへのアクセスを許可する、ストレージ
コントローラーによる認可。
{
"type": ["AccessGrant"]
}
storageプロパティは、
アクセス要求またはアクセス許可の範囲となる
LWSストレージを識別する。
storageプロパティの値はURIでなければMUSTならない。
このプロパティはREQUIREDである。
{
"storage": "https://storage.example/"
}
inboxプロパティは、
アクセス要求またはアクセス許可に関連する通知を受け取るためのURIを指定する
(10.6
通知を参照)。
inboxプロパティの値はURIでなければMUSTならない。
このプロパティはOPTIONALである。
{
"inbox": "https://id.example/agent/inbox/"
}
accessプロパティは、サーバーによってサポートされるプロファイルに基づき、
1つ以上のアクセスプロファイルの特性を記述する。
ODRL情報モデルに基づく
プロファイルは、10.3 アクセスプロファイルで
記述される。
accessプロパティの値は、1つ以上のオブジェクトの集合でなければ
MUSTならない。
このプロパティはREQUIREDである。
この仕様は、
ODRL情報モデルおよびODRL
語彙に基づくアクセスプロファイルを定義し、
次のURLで識別される:
https://www.w3.org/ns/lws#AccessProfile.
typeプロパティは、アクセスポリシーの型を表現する。
typeプロパティの値は、1つ以上の
用語および
絶対URL文字列でなければ
MUSTならず、用語AccessPolicyを含まなければ
MUSTならない。追加の型値が含まれてもMAYよい。
このプロパティはREQUIREDである。
{
"access": [{
"type": ["AccessPolicy"]
}]
}
actionプロパティは、エージェントが
実行したい(要求の場合)、または実行することを認可されている(許可の場合)
操作を記述する。
actionプロパティの値は、1つ以上の
文字列の集合でなければMUSTならない。各値は、サーバーが認識する操作に対応しなければ
MUSTならない。次の値をサポートしなければMUSTならない:
read、modify、
create、およびdelete。read、
modify、およびdeleteの値は、
ODRL語彙によって定義される。
create値は、この
仕様によって定義される。
これらのアクション値は、次のようにLWS操作に対応する:
read — リソースまたはそのメタデータを取得する(HTTP GET、HEAD)modify — 既存リソースを変更する(HTTP PUT、PATCH)create — コンテナ内に新しいリソースを作成する(HTTP POST)
delete — 既存リソースを削除する(HTTP DELETE)このプロパティはREQUIREDである。
{
"access": [{
"action": ["read", "create"]
}]
}
assigneeプロパティは、アクセスを要求している当事者(要求の場合)、
またはアクセスを許可されている当事者(許可の場合)を識別する。
assigneeプロパティの値はURIでなければMUSTならない。
公開アクセスは、
http://xmlns.com/foaf/0.1/AgentというURIで識別される、
FOAF
語彙のAgentクラスを用いて割り当てられてもMAYよい。
このプロパティはREQUIREDである。
{
"access": [{
"assignee": "https://id.example/agent"
}]
}
targetプロパティは、
アクセス要求またはアクセス許可が
適用されるリソースを識別する。
targetプロパティは、次のプロパティを含む
オブジェクトでなければMUSTならない:
この仕様は、対象オブジェクトで使用する次のtype値を定義する:
https://www.w3.org/ns/lws#DataResource — 型lws:DataResourceの
リソースに一致する。
https://www.w3.org/ns/lws#Container — 型lws:Containerの
リソースに一致する。
https://www.w3.org/ns/lws#StorageResource — ストレージによって管理される任意のリソースに一致する。
サーバーは追加の型値をサポートしてもMAYよい。
このプロパティはOPTIONALである。
{
"access": [{
"target": {
"type": "StorageResource",
"value": [
"https://storage.example/data/2025",
"https://storage.example/data/2026"
]
}
}]
}
constraintプロパティは、要求または許可されるアクセスを
制限または限定する条件を定義する。このプロパティは、ODRL
Constraintモデルを使用する。
constraintプロパティの値は、存在する場合、制約オブジェクトの
集合でなければMUSTならない。各制約オブジェクトは、次の
プロパティを含まなければMUSTならない:
leftOperand — 制約されるオペランドを識別する文字列。
operator — 比較演算子を識別する文字列。
rightOperand — 比較対象となる値。型は
leftOperandに依存する。
複数の制約オブジェクトが存在する場合、それらはすべて満たされなければ MUSTならない。
このプロファイルのサポートを広告するサーバーは、次の
leftOperand値をサポートしなければMUSTならない:
client — HTTP要求のクライアント識別子を表す
mediaType — 対象HTTPリソースのメディア型を表す
type — リソースのLinkヘッダーで表現される型URLを表す
purpose — 要求または許可されるアクセスの意図された用途を表す
dateTime — 現在日時を表す
このプロパティはOPTIONALである。
次の例は、これらの制約の使用を示す:
次の例は、leftOperand値
purposeを使用して、要求または許可されるアクセスの意図された
用途を記述する。eq演算子が使用される場合、
rightOperand値は目的を識別するURIである。
isAnyOf演算子が使用される場合、rightOperand
値は目的URIの配列であり、表明された目的が列挙された値のいずれかに一致する場合に
制約は満たされる:
{
"access": [{
"constraint": [
{
"leftOperand": "purpose",
"operator": "isAnyOf",
"rightOperand": [
"https://purpose.example/collaboration",
"https://purpose.example/research"
]
}
]
}]
}
次の例は、leftOperand値
clientを使用して、特定のクライアントアプリケーションに
アクセスを制限する。eq演算子が使用される場合、
rightOperand値はクライアントを識別するURIである:
{
"access": [{
"constraint": [
{
"leftOperand": "client",
"operator": "eq",
"rightOperand": "https://app.example/client-id"
}
]
}]
}
次の例は、leftOperand値
mediaTypeを使用して、
特定のメディア型を持つリソースへのアクセスを制限する。eq演算子が
使用される場合、rightOperand値は
IANAメディア型を識別する文字列である。
isAnyOf演算子が使用される場合、rightOperand値
はメディア型文字列の配列であり、リソースの
メディア型が列挙された値のいずれかに一致する場合にアクセスが許可される:
{
"access": [{
"constraint": [
{
"leftOperand": "mediaType",
"operator": "isAnyOf",
"rightOperand": ["image/jpeg", "image/png"]
}
]
}]
}
すべてのLWSリソースは、型値を示すLinkヘッダーを含む:
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Link: <https://type.example/Playlist>; rel="type"
次の例は、leftOperand値
typeを使用して、HTTP Linkヘッダーで広告された
リソース型に基づきアクセスを制限する。
eq演算子が使用される場合、rightOperand値
はリソース型を識別するURIである。isAnyOf演算子が
使用される場合、rightOperand値は型URIの配列であり、リソースの型が
列挙された値のいずれかに一致する場合にアクセスが許可される:
{
"access": [{
"constraint": [
{
"leftOperand": "type",
"operator": "isAnyOf",
"rightOperand": [
"https://type.example/Playlist",
"https://type.example/Song"
]
}
]
}]
}
次の例は、leftOperand値
dateTimeを使用して、特定の時間枠に
アクセスを制限する。gteq演算子は
時間枠の開始を定義し、lteq演算子は終了を定義する。
時間的制約のrightOperand値は、
XML
SchemaのdateTime文字列である:
{
"access": [{
"constraint": [
{
"leftOperand": "dateTime",
"operator": "gteq",
"rightOperand": "2026-03-09T12:00:00Z"
},
{
"leftOperand": "dateTime",
"operator": "lteq",
"rightOperand": "2026-06-09T10:00:00Z"
}
]
}]
}
複数の制約オブジェクトが存在する場合、アクセスが許可されるためには、それらはすべて 満たされなければMUSTならない。次の例は、 特定の日付より前に特定のクライアントアプリケーションへアクセスを制限する:
{
"access": [{
"action": ["read"],
"assignee": "https://id.example/agent",
"target": {
"type": "StorageResource",
"value": ["https://storage.example/projects/"]
},
"constraint": [
{
"leftOperand": "dateTime",
"operator": "lteq",
"rightOperand": "2026-06-09T10:00:00Z"
},
{
"leftOperand": "client",
"operator": "eq",
"rightOperand": "https://app.example/client-id"
}
]
}]
}
この節で定義されるデータモデルは、特定の シリアル化から独立している。
この仕様は、アクセス要求および
アクセス許可のためのJSON-LDシリアル化を定義する。
このシリアル化を使用する文書は、
https://www.w3.org/ns/lws/v1を含む順序付き集合を値とする
@contextプロパティを含まなければMUSTならない。拡張用語を定義するために、追加のコンテキストエントリーが
含まれてもMAYよい。
このシリアル化に関連付けられるメディア型はapplication/lws+jsonである。
{
"@context": [
"https://www.w3.org/ns/lws/v1"
]
}
アクセス要求およびアクセス許可のエンドポイント はLWSコンテナであり、この仕様で定義される規則に適合しなければMUST ならない。
これらのエンドポイントは、少なくともGETおよびPOST操作のサポートを必要とする。DELETE操作は RECOMMENDEDである。他の操作がサポートされてもMAYよい。
これらのエンドポイントは、要求および応答ペイロードの両方について、 10.4.1 JSON-LD シリアル化で定義されるJSON-LDシリアル化をサポートしなければMUSTならない。 サーバーは追加のシリアル化をサポートしてもMAYよい。
エージェントは、
アクセス要求エンドポイントへ
POST要求を送信することで、アクセス要求を作成する。
ストレージ
コントローラーは、アクセス許可エンドポイントへ
POST要求を送信することで、アクセス許可を作成する。
成功したPOST操作は、新しいリソースのURLに設定された
Locationヘッダーを返して応答しなければMUSTならない。
POST / — アクセス要求を作成する。GET / — アクセス要求の一覧を取得する。GET /:id — 特定のアクセス要求を取得する。DELETE /:id — アクセス要求を取り消す。POST / — アクセス許可を作成する。GET / — アクセス許可の一覧を取得する。GET /:id — 特定のアクセス許可を取得する。DELETE /:id — アクセス許可を取り消す。
通知は、エージェントおよびストレージ
コントローラーに対して、
アクセス要求およびアクセス許可の変更を知らせるための
メカニズムを提供する。アクセス要求またはアクセス許可に
inboxプロパティが存在する場合、サーバーは
譲受人にイベントを知らせる通知をそのエンドポイントへ配信すべきSHOULDである。
通知のシリアル化は、LWS通知データモデルの要件に適合しなければMUSTならない。
inboxエンドポイントに配信される通知は、通知配信のためのLWSプロトコルで定義される
要件に適合しなければMUSTならない。
この節で記述される通知メカニズムは、
Linked Data Notificationsパターンと比較できる。
そのパターンでは、通知はinboxプロパティを介して発見され、
その受信箱へPOST要求を送信することで配信される。
サーバーは、次のイベントに応じて通知を送信すべきSHOULDである:
inboxに通知されるべきSHOULDである。
サーバーは、他のイベントに応じて通知を送信してもMAYよい。
LWSのコンテナ表現およびストレージ記述リソースは、メディア型
application/lws+jsonを使用しなければMUSTならない。
LWSコンテナ表現はJSON-LDの規約を使用するが、LWSに対する制約および要件は、
特定のメディア型の使用を正当化する。LWSコンテナはJSON-LDの制限されたプロファイルとみなせるため、
実装は
application/ld+json; profile="https://www.w3.org/ns/lws/v1"メディア型を
application/lws+jsonと等価なものとして扱うべきSHOULDである。
サーバーは、コンテナ表現についてコンテンツネゴシエーションをサポートしなければMUSTならない。
応答ペイロードは、要求されたメディア型にかかわらず同一でなければMUSTならない —
変化するのはContent-Type応答ヘッダーのみである:
application/lws+jsonを要求した場合、サーバーは
Content-Type: application/lws+jsonで応答しなければMUSTならない。
application/ld+jsonを要求した場合、サーバーは
Content-Type: application/ld+jsonで応答しなければMUSTならない。
application/jsonを要求した場合、サーバーは
Content-Type: application/jsonで応答しなければMUSTならない。
3つの場合すべてにおいて、応答本文はLWSコンテナ語彙に適合する同じJSON-LD文書である。
サーバーは、コンテンツネゴシエーションを通じて追加のメディア型(例: text/turtle)を
自由にサポートできる。
コンテナのような特定の複合リソースは、多数のリソースを保持することがある。 クライアントが一覧を段階的に取得できるようにするため、サーバーは、メンバーシップがサーバーによって決定された しきい値を超えるコンテナについて、ページネーションをサポートすべき SHOULDである。
ページネーションはリンクに基づく: サーバーはHTTP Linkヘッダーを介してページネーションURIを提供する
[RFC8288]。
これにより、クライアントは数値オフセットに依存することなく完全な一覧をナビゲートできる。
一覧がページ分割される場合、応答本文には現在のページの項目のみが含まれる。
複合リソースのid、type、およびtotalItemsプロパティは
メンバーシップ全体を反映し、itemsには現在のページ上のリソースのみが含まれる。
ページネーションURIは、次の標準リンク関係を使用してLinkヘッダーで伝達される:
rel="first": 結果の最初のページのURI。ページ分割された応答に存在しなければ
MUSTならない。
rel="last": 結果の最後のページのURI。ページ分割された応答に存在しても
MAYよい。
rel="next": 結果の次のページのURI。後続ページがある場合は
存在しなければMUSTならない。最後のページでは省略されなければ
MUSTならない。
rel="prev": 結果の前のページのURI。先行ページがある場合は
存在してもMAYよい。最初のページでは省略されなければ
MUSTならない。
すべてのページネーションURIは、クライアントにとって不透明である。クライアントはページネーション URIを構築または変更すべきではSHOULD NOTなく、 サーバーが提供するURIを使用すべきSHOULDである。
クライアントは、最初のページを取得するために複合リソースのURIを要求する。応答には、クライアントが 後続ページを取得するために辿るページネーション Linkヘッダーが含まれる。サーバーは、以前の走査中に取得されたページネーションURIを介して、 特定ページへの直接アクセスもサポートしてもMAYよい。
ページ分割された応答が返される場合、サーバーは200
OKで応答しなければMUSTならない。応答本文のtotalItems
プロパティは、現在のページだけでなく、全ページにわたる項目の総数を反映すべき
SHOULDである。
要求:
GET /alice/photos/ HTTP/1.1
Authorization: Bearer <token>
Accept: application/lws+json
応答(最初のページ):
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page1-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Link: </alice/photos/?page=1>; rel="first"
Link: </alice/photos/?page=3>; rel="last"
Link: </alice/photos/?page=2>; rel="next"
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "/alice/photos/",
"type": "Container",
"totalItems": 150,
"items": [
{
"type": "DataResource",
"id": "/alice/photos/vacation.jpg",
"mediaType": "image/jpeg",
"size": 248392,
"modified": "2025-11-20T10:30:00Z"
},
{
"type": "DataResource",
"id": "/alice/photos/portrait.png",
"mediaType": "image/png",
"size": 102400,
"modified": "2025-11-21T14:15:00Z"
}
]
}
要求(次のページ):
GET /alice/photos/?page=2 HTTP/1.1
Authorization: Bearer <token>
Accept: application/lws+json
応答(中間ページ):
HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page2-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Link: </alice/photos/?page=1>; rel="first"
Link: </alice/photos/?page=1>; rel="prev"
Link: </alice/photos/?page=3>; rel="next"
Link: </alice/photos/?page=3>; rel="last"
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "/alice/photos/",
"type": "Container",
"totalItems": 150,
"items": [
{
"type": "DataResource",
"id": "/alice/photos/sunset.jpg",
"mediaType": "image/jpeg",
"size": 315000,
"modified": "2025-11-22T09:00:00Z"
}
]
}
コンテナ表現は、次の@context
値を含まなければMUSTならない:
"@context": "https://www.w3.org/ns/lws/v1"
規範的JSON-LDコンテキスト文書は、 コンテナ表現で使用される短いプロパティ名と、 LWSおよび関連語彙における完全なURIとの対応を定義する。コンテキストは次のように定義される:
{
"@context": {
"@version": 1.1,
"@protected": true,
"lws": "https://www.w3.org/ns/lws#",
"as": "https://www.w3.org/ns/activitystreams#",
"schema": "https://schema.org/",
"xs": "http://www.w3.org/2001/XMLSchema#",
"id": "@id",
"type": "@type",
"Container": "lws:Container",
"DataResource": "lws:DataResource",
"items": "lws:items",
"totalItems": "as:totalItems",
"mediaType": "as:mediaType",
"size": {
"@id": "schema:size",
"@type": "xs:long"
},
"modified": {
"@id": "as:updated",
"@type": "xs:dateTime"
}
}
}
コンテキストは@protectedであり、用語定義が他のコンテキストによって上書きされないことを保証する。
LWS語彙は、コンテナ 表現で使用される次の型およびプロパティを定義する:
型:
| 用語 | URI | 説明 |
|---|---|---|
Container |
lws:Container |
他のリソースを含むリソース |
DataResource |
lws:DataResource |
データを保持するリソース |
プロパティ:
| 用語 | URI | 説明 |
|---|---|---|
items |
lws:items |
コンテナに含まれるリソースの一覧 |
totalItems |
as:totalItems |
含まれるリソースの総数 |
mediaType |
as:mediaType |
リソースのメディア型 |
size |
schema:size |
リソースのサイズ(バイト単位) |
modified |
as:updated |
リソースが最後に変更された日時 |
URIスキーム、リソース命名規約、および解決メカニズムを含め、LWSプロトコル内で リソースがどのように識別されアドレス指定されるかを定義する。この節は、別の節、たとえばリソースアクセスへ移動される可能性がある
ここは意図的に空白のままとする
相互運用性を維持しながら、LWS実装が異なるプラットフォーム、環境、およびストレージバックエンドで動作できることを保証するための 考慮事項を記述し、ストレージプロバイダーの変更を可能にするアフォーダンスを提供する
ここは意図的に空白のままとする
この節は非規範的である。
安全なLWS展開のための脅威モデル、セキュリティ要件、および 実装ガイダンスを扱う正式なセキュリティ考慮事項の節。
OAuth 2.0 SecurityのBest Current Practice [RFC9700]で記述される推奨事項は、この 仕様に適用される。
この節は非規範的である。
Transport Layer Security(TLS)は、改ざん、なりすまし、および 情報開示を防止するための重要なメカニズムである。TLSで保護された通信は、[RFC6125]に従って検証できる。 実装に関するセキュリティ考慮事項は、「Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)」[RFC9325]で確認できる。
この節は非規範的である。
ベアラートークンおよびデジタル資格情報は、盗難およびリプレイに対して脆弱である。 緩和策には、合理的に短い存続期間を使用すること、トークンを特定のオーディエンスにバインドすること、 およびトークンを安全に保存することが含まれる。
audクレームなどの手段により特定の宛先サーバーにバインドされた
アクセストークンは、そのバインディングに依存してトークンリプレイから保護できる。
制限のないオーディエンスを持つ資格情報を扱うアプリケーションは、これらの
資格情報を他の実体、特に信頼されていない認可サーバーへ送信する際に注意する必要がある。
資格情報発行者がトークンのオーディエンスを制限できない場合、クライアントは、
異なるセキュリティドメイン内の認可サーバーとやり取りする前に、OAuth 2.0 Token
Exchange [RFC8693]などのメカニズムを使用して、
オーディエンス制約付き資格情報を作成できる。
localStorage、URL、
またはログに保存されるたびに、そのトークンは流出攻撃を受けやすくなる。
この節は非規範的である。
assignee値が、要求元エージェントの認証済み身元に関連付けられていることを
検証することが推奨される。
この節は非規範的である。
データ最小化、ユーザー同意、および プライバシー保護型実装パターンを含む、LWSプロトコルのプライバシー上の影響。
資格情報は、ユーザーおよびエージェントに関する情報を運ぶ。デジタル署名は改ざんから保護できるが、 クライアントまたは第三者が暗号化されていない資格情報内部の値を読み取ることは可能である。
その結果、資格情報発行者は、認証または認可に必要な情報のみを含むトークンを作成し、 必要でない限り機微な属性を含めないことが推奨される。
一般に、暗号化されていない資格情報データをログに書き込むことはアンチパターンである。これが 必要な場合、実装は、資格情報主体のプライバシーを保護するために、資格情報を切り詰めるかハッシュ化できる。
JWTで仮名識別子を使用する場合、ストレージサーバーは同じエージェント からの要求を時間の経過にわたり相関できる可能性がある。 この場合にユーザープライバシーを保護するため、クライアントアプリケーションは、各 JWTが一度だけ使用されるJWTのバッチ発行を要求できる。 これは、JWTコンテンツの類似性や送信元IPアドレスなどの他の情報を使用して ストレージサーバーが要求を相関することを防がない。仮名識別子を使用する場合、認可サーバーは 同じ識別子を複数回発行しないよう注意する必要がある。
この節は非規範的である。
この節は非規範的である。
この仕様は、RFC 5785 [RFC5785]によって確立された 「Well-Known URIs」レジストリに、 次の値を追加する。
この仕様は、Linked Web Storageコンテナ形式に適合する文書を識別するために、
application/lws+jsonメディア型を登録する。
application/lws+jsonメディア型を使用するリソースは、
application/jsonメディア型に対するすべての要件に適合することが要求されるため、
[RFC8259]の第11節で指定される
同じ符号化に関する考慮事項の対象となる。
Linked Web Storage形式はJSON-LDの規約を使用するが、LWS実装には、 特定のメディア型の使用を正当化する多くの制約および追加要件があることに注意すること。
LWSコンテナはJSON-LDの制限されたプロファイルとみなせるため、実装は、
application/ld+json; profile="https://www.w3.org/ns/lws/v1"メディア型を
application/lws+jsonと等価なものとして扱うべきSHOULDである。
この節は非規範的である。
この仕様は、Solid Protocol [Solid-Protocol]に大きく依拠している。同プロトコルは、長期間にわたり Sarven Capadisli、Tim Berners-Lee、Kjetil Kjernsmo、Ruben Verborgh、Justin Bingham、Dmitri Zagidulinによって編集された。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: