Linked Web Storageプロトコル 1.0

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-lws10-core-20260622/
最新公開バージョン:
https://www.w3.org/TR/lws10-core/
最新の編集者草案:
https://w3c.github.io/lws-protocol/lws10-core/
履歴:
https://www.w3.org/standards/history/lws10-core/
コミット履歴
編集者:
Jesse Wright (オックスフォード大学)
Erich Bremer (ストーニーブルック大学)
フィードバック:
GitHub w3c/lws-protocol (プルリクエスト, 新しい課題, 未解決の課題)

概要

Linked Web Storage Protocol仕様は、アプリケーションに対し、外部に保存されたデータへの安全で許可に基づく アクセスを相互運用可能な方法で提供することを目的とする。

この文書の位置付け

この節は、この 文書の公開時点における位置付けを説明する。現在のW3C 公開物の一覧およびこの技術報告書の最新版は、 W3C標準および草案 インデックスで確認できる。

これは非公式な提案である。

この文書は、Linked Web Storageワーキング グループにより、 勧告 トラックを用いる作業草案として公開された。

作業草案としての公開は、 W3Cおよびそのメンバーによる承認を 意味しない。

これは草案文書であり、いつでも他の文書により更新、置換、または廃止される可能性がある。 この文書を進行中の作業以外のものとして引用することは不適切である。

この文書は、 W3C 特許 ポリシー の下で運営されるグループにより作成された。 W3Cは、このグループの成果物に関連して行われた 特許開示の公開一覧 を管理している。そのページには、 特許を開示するための手順も含まれる。個人が、 必須クレーム を含むとその個人が信じる特許について実際の知識を有する場合、 W3C特許ポリシー第6節 に従ってその情報を開示しなければならない。

この文書は、 2025年8月18日のW3Cプロセス文書 によって管理される。

1. 文書規約

この節は非規範的である。

2. 序論

2.1 リソースアクセス

LWSプロトコルは、ある主体が何らかのリソースを何らかのエージェントに利用可能にできる標準的なやり取りを定義する。

2.2 セキュリティとプライバシー

リソース管理者は、提供リソースを 非公開に保つことも、誰にでも公開することも、その可視性を制約された一群の 要求エージェントに限定することもできる。

2.3 適合性

非規範的と明示された節に加え、この仕様におけるすべての作成ガイドライン、図、例、および注記は 非規範的である。この仕様のそれ以外のすべては規範的である。

この文書におけるキーワードMAYMUSTMUST NOTOPTIONALRECOMMENDEDREQUIREDSHOULD、およびSHOULD NOTは、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されるとおりに解釈される。

LWSサーバーは、この仕様における関連するすべての「MUST」 文に適合するHTTPサーバー[rfc9112]である。具体的には、 この文書の9. 操作における関連する規範的な「MUST」文を尊重MUSTする。

LWS クライアントは、この仕様における関連するすべての「MUST」文に適合するHTTPクライアント[rfc9112]である。具体的には、この文書の9. 操作における関連する規範的な 「MUST」文をMUST尊重する。

3. 用語

「authorization server」および「client」という用語は、OAuth 2.0 Authorization Framework [RFC6749]によって定義される。

「end-user」および「issuer」という用語は、OpenID Connect Core 1.0 [OPENID-CONNECT-CORE]によって定義される。

この仕様は、次の用語を定義する:

(リスクのある機能)課題: 節が削除される可能性がある

この仕様は、提供 リソースに対する操作、結果として生じる状態変更、および要求エージェントに要求された情報を提供する、または操作の結果を通知することを意図した応答 を定義する。 操作とは、提供リソースに対して実行できる次のいずれかのアクションである:

  • リソースを作成する -
  • リソースを 読み取る -
  • リソースを 更新する -
  • リソースを 削除する -

次の節では、これらの操作の意味論と応答について記述するが、 次の中核 応答は任意の操作に適用される:

  • 成功 - 操作が完了したと考えられる。これには、提供リソースの内容を伝えるリソース表現が伴う場合がある。成功応答は リソースを作成する操作については定義されない。代わりに作成済みを参照。
  • 許可されて いない
  • 不明な 要求者
  • 不明な エラー - 仕様で予期されていない発生したエラー条件のために予約される

4. 認証

この節は、Linked Web Storageサーバーとやり取りするエージェントおよびエンドユーザーを識別するためのメカニズムを定義する。 この仕様は、認証資格情報の特定の形式を義務付けないが、既存の身元システムを Linked Web Storage認可フレームワークと組み合わせて使用する方法を記述する。

4.1 認証 資格情報データモデル

この節で記述されるデータモデルは、認証資格情報の任意の 具体的なシリアル化に対する要件を概説する。

認証資格情報は、主体に関する改ざん明示的なクレームを含まなければMUSTならず、これには次が含まれる:

4.2 認証 資格情報の検証

認証資格情報の検証には、検証者と資格情報の発行者との間の信頼 関係が必要である。この信頼関係は、アウトオブバンドのメカニズムを通じて確立されてもMAYよい。 検証者と発行者との間の信頼を確立するための追加メカニズムは、特定の認証スイートで概説される。

認証資格情報は署名されなければMUSTならない。署名には非対称暗号を用いることがRECOMMENDEDされる。

4.3 認証 資格情報型識別子

認証スイートは、トークン型URIに関連付けられなければMUSTならない。 認証スイートは、IANA「OAuth URI」レジストリで定義されたURIを使用すべきSHOULDである。

5. 認可

Linked Web Storageは、Web上で保護されたデータを永続化し管理するためのメカニズムを記述する。 認可は、 エージェントが この保護されたデータにアクセスするためにアクセストークンを要求し提示するためのメカニズムである。

この節は、アクセストークンを取得し提示するための基準メカニズムとして、OAuth 2.0 [RFC6749]に基づく認可フレームワークを定義する。 サーバーは、この基準を超える追加の認可メカニズムをサポートしてもMAYよい。

5.1 ロール

LWS認可におけるロールは、OAuth 2.0 第1.1節 [RFC6749]で定義されるものと同じである: リソース所有者リソースサーバー、 クライアント(曖昧さを避けるため、この仕様では認可クライアントと呼ぶ)、および 認可サーバー。 ストレージサーバーは、LWSストレージ仕様にも適合するリソースサーバーの一種である。

5.2 プロトコルフロー

この仕様は、クライアントと認可サーバーとの間のやり取り、および クライアントと適合ストレージサーバーとの間のやり取りを記述する。

認可サーバーとストレージサーバーとの間のやり取りは、この仕様の範囲外である。 認可サーバーはストレージサーバーと同じサーバーであってもよく、別個の実体であってもよい。

5.2.1 認可サーバー の発見

ストレージサーバーによって管理されるすべての保護リソースは、信頼された 認可サーバーによって生成された有効なアクセストークンを必要とする。クライアントは、 保護リソースに対して未認可のHTTP要求を行うことで、信頼された認可サーバーの場所を発見できる。

401(Unauthorized)応答を生成するストレージサーバーは、少なくとも1つの適合するチャレンジを含む WWW-Authenticateヘッダー フィールドを送信しなければMUSTならない。適合するチャレンジは、 以下に記述するパラメーターを含む:

  • as_uri REQUIRED — この パラメーターの値は、クライアントがアクセストークンを取得できる認可サーバーを識別するURIである。 このパラメーターの値は、有効なアクセストークンの issクレームと同じである。
  • realm REQUIRED — この パラメーターの値は、保護の範囲を示すURIである。 この値は、アクセストークンのオーディエンス(aud)クレームに含まれる。 クライアントは、 送信元要求のURIが、この応答で提示されたrealm内に論理的に含まれていることを 検証しなければMUSTならない。

他のヘッダーおよびパラメーターが含まれてもMAYよい。

401応答の例を以下に示す。

HTTP/2 401 Unauthorized
Link: <https://storage.example/storage_1/metadata>; rel="storageDescription"
WWW-Authenticate: Bearer as_uri="https://authorization.example",
                realm="https://storage.example/storage_1",
                error="invalid_token"

5.2.2 認可サーバー メタデータ

認可サーバーは、[RFC8414]に記述されるように、 クライアントがエンドポイントの場所および機能を発見できるようにするメタデータリソースを提供しなければMUSTならない。 このメタデータリソースは、 /.well-known/lws-configurationというパスを持つURLで利用可能でなければMUSTならない。

認可サーバーは、サーバーメタデータ文書にsubject_token_types_supported エントリーを含めることによって、サポートするサブジェクトトークンを広告すべきSHOULDである。 このエントリーは、認可サーバーのトークンエンドポイントで指定できる有効な subject_token_type値の一覧を含むJSON配列である。

認可サーバーメタデータリソースの例を以下に示す。

{
    "issuer": "https://authorization.example",
    "grant_types_supported": [
        "urn:ietf:params:oauth:grant-type:token-exchange"],
    "token_endpoint": "https://authorization.example/token",
    "jwks_uri": "https://authorization.example/jwks",
    "claims_supported": [
        "sub",
        "iss",
        "client_id",
        "aud"],
    "response_types_supported": [
        "token"],
    "subject_token_types_supported": [
        "urn:ietf:params:oauth:token-type:jwt",
        "urn:ietf:params:oauth:token-type:id-token"]
}

5.2.3 トークン交換

LWS認可サーバーは、ストレージサーバーで使用するための アクセストークンをクライアントに発行できる、適合するOAuth 2.0認可サーバーである。 アクセストークンを発行するために、クライアントはまず、 認証資格情報などの有効なサブジェクトトークンを、 OAuth 2.0 Token Exchange [RFC8693]を介して 認可サーバーに提示しなければならない。

5.2.3.1 要求

認可サーバーのトークンエンドポイントは、OAuth 2.0 Token Exchange [RFC8693]で記述される、 urn:ietf:params:oauth:grant-type:token-exchange グラント型をサポートしなければMUSTならない。

トークン交換グラント型を実行する場合、次の追加要件が適用される:

  • resourceパラメーターはREQUIREDである。この パラメーターの値はURIでなければMUSTならず、結果として得られるアクセストークン内の aud(オーディエンス)クレームを設定するために使用される。指定された値は、 WWW-Authenticateチャレンジにおける realmパラメーター応答と同じである。 認可サーバーは、 resourceパラメーターが不明または信頼されていないストレージを識別する要求を拒否しなければMUSTならない。
  • subject_tokenパラメーターはREQUIREDである。この パラメーターの値は、 認証 資格情報などの有効なサブジェクトトークンを含まなければMUSTならない。
  • クライアントにアクセストークンを返す前に、認可サーバーは提示されたすべてのトークンを正常に検証しなければMUSTならない。

トークン要求の非規範的な例(subject_tokenパラメーターは 省略されている)。

POST /token HTTP/1.1
Host: authorization.example
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fstorage.example%2Fstorage_1
&subject_token=eyJ0eXAiOiJhcytqd3QiLCJhbGciO...fiK51VwhsxJ-siBMR-YFiA
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
5.2.3.2 応答

トークン要求が有効であり、クライアントがその要求を行うことを認可されている場合、 認可サーバー応答は、OAuth 2.0 Authorization Framework [RFC6749]の第5.1節に 適合しなければMUSTならない。結果として得られるアクセストークンは、 JSON Web Token Profile for OAuth 2.0 Access Tokens [RFC9068]に 適合しなければMUSTならない。

さらに、アクセストークンは次の要件を満たさなければならない:

  • sub(主体)— REQUIRED。このクレームは、 操作を実行するエージェントを識別するURIでなければMUSTならない
  • iss(発行者)— REQUIRED。このクレームは、 認可サーバーのURIでなければMUSTならない
  • client_id(クライアントID)— REQUIRED。 このクレームは、クライアントを識別するURIでなければMUSTならない。
  • aud(オーディエンス)— REQUIRED。このクレームは、 resourceパラメーターでクライアントにより指定されたURIを含まなければMUSTならない。 この値は、アクセストークンが有効となる実体を制限するために使用される。これは、 ストレージサーバーがWWW-Authenticateチャレンジのrealmパラメーターで提供する値と 同じ値になる。
  • exp(有効期限)— REQUIRED。 認可サーバーは、トークン窃取による露出を制限するため、短い存続期間のトークン (RECOMMENDED: 300秒以下)を発行すべきSHOULDである。
  • iat(発行時刻)— REQUIRED
  • jti(JWT ID)— REQUIRED

成功したトークン応答の非規範的な例を以下に示す。

HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token":"eyJ0eXAiOiJhcytqd3QiLCJhbGciOiJFUzI1NiIs...DeWt4QuZXso",
    "token_type":"Bearer",
    "expires_in":3600
}

無効または未認可のすべての要求は、OAuth 2.0 Authorization Framework [RFC6749]の第5.2節に 記述されるエラー応答にならなければMUSTならない。

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "error":"invalid_request"
}
5.2.3.3 アクセストークンの例

この節は非規範的である。

認可サーバーによって発行されたアクセストークンの例を以下に示す。

{
  "kid": "ec51c6b2",
  "kty": "EC",
  "alg": "ES256",
  "crv": "P-256",
  "typ": "at+jwt"
}
.
{
  "sub": "https://id.example/agent",
  "iss": "https://authorization.example",
  "client_id": "https://app.example/id",
  "aud": "https://storage.example",
  "exp": 1735686300,
  "iat": 1735686000,
  "jti": "550e8400-e29b-41d4-a716-446655440000"
}
.
signature

5.2.4 ストレージサーバー によるトークン検証

クライアントがアクセストークンを保持すると、そのトークンをストレージサーバーに提示する。 ストレージサーバーは、任意の操作を実行する前に、このトークンを検証する責任を負う。

5.2.4.1 提示

クライアントは、[RFC6750]で定義される認証スキームを用いて、 Authorizationヘッダーによりアクセストークンをストレージサーバーに提示しなければMUSTならない。

Authorization: Bearer eyJ0eXAiOiJhcytqd3QiLCJhbGciOiJFUzI1NiIs...DeWt4QuZXso
5.2.4.2 検証

ストレージサーバーは、次の検査を実行し、いずれかが失敗した場合には要求を拒否することによって、 アクセストークンを検証しなければMUSTならない:

  • JWT署名検証: 認可サーバーメタデータで指定された jwks_uriから取得した認可サーバーの公開鍵を用いてJWT署名を検証する。 ストレージサーバーは、これらの鍵をキャッシュすべきSHOULDであり、 鍵ローテーションをサポートしなければMUSTならない。
  • 発行者検証: issクレームが想定される認可サーバー識別子と一致することを検証する。
  • オーディエンス検証: audクレームが正確に1つの値を含み、この 値が対象リソースを論理的に含むストレージサーバーを識別するURIであることを検証する。
  • システム間で許容されるクロックスキューを前提とした時間検証。
    • 現在時刻がexp(有効期限)クレームより前であることを検証する。
    • nbf(not before)クレームが存在する場合、現在時刻がそれより前でないことを検証する。
    • iat(発行時刻)クレームが未来でないことを検証する。

検証に失敗した場合、ストレージサーバーは、適切なエラーパラメーター(例: invalid_token、invalid_request、または insufficient_scope)を含むWWW-Authenticateヘッダーを付けて、 401 Unauthorizedを返さなければMUSTならない。

トークンがその他の点では有効であるが、認可ポリシーが要求された操作を許可しない場合、 ストレージサーバーは要求を拒否しなければMUSTならない。

6. 発見

6.1 ストレージ記述リソース

ストレージ記述リソースは、クライアントが ストレージとやり取りする際に使用できる情報を提供し、 機能およびサービスエンドポイントの記述を含む。

6.1.1 データモデル

  • 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 ならない。
8: 最小のストレージ記述リソース
{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "https://storage.example/",
  "type": "Storage",
  "service": [{
    "type": "StorageDescription",
    "serviceEndpoint": "https://storage.example/description"
  }]
}

6.1.2 発見とバインディング

ストレージリソースを対象とする GETおよびHEAD要求に対するすべての応答は、 ストレージ 記述リソースのURIをターゲットとし、 値が https://www.w3.org/ns/lws#storageDescriptionに等しい関係 (rel)パラメーターを含むLinkヘッダーを 含まなければMUSTならない。

参照解決された場合、ストレージ記述は、 ストレージを識別するidプロパティを含まなければ MUSTならない。さらに、serviceプロパティは、 型がStorageDescriptionに等しく、そのserviceEndpointストレージ記述のURLに等しい サービス記述を含まなければMUSTならない。

注記

ストレージ記述のURIは、 ストレージを識別するURIとは異なっていてもよく、 それはストレージルートとも異なっていてもよい。結果として得られる表現が この文書で概説される要件に適合する限り、これらのURIは同一でもよい。

6.1.3 ストレージ機能

ストレージ記述は、 ストレージによってサポートされる 追加機能の記述を含んでもよい。

6.1.4 ストレージサービス

StorageDescriptionサービスに加えて、 ストレージ記述リソースは、 ストレージに接続された他のサービスへのリンクを含んでもよい。 これらのサービスのAPI定義は、この仕様の範囲外である。

6.1.5 ストレージ 記述表現

ストレージ記述リソースは、 メディア型application/lws+jsonでシリアル化可能でなければMUSTならない。 他の表現は、コンテンツネゴシエーションを介して利用可能であってもMAYよい。

9: ストレージ記述リソース
{
  "@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"
  }]
}

7. 論理リソース編成

7.1 コンテナモデル

Linked Web Storageは、リソースをコンテナに編成する。コンテナは、 メンバーと呼ばれる他のリソースへの参照を保持する特殊化されたリソースである。コンテナは、 ディレクトリまたはコレクションに類似した編成単位として機能し、クライアントがリソースをグループ化、発見、 およびナビゲートできるようにする。コンテナは、そのメンバーリソースへの参照を保持し、 それらは非コンテナリソースと追加のコンテナリソースの両方から構成されてもよく、それにより 階層的な構成が可能になる。通常、コンテナは、メンバーのメタデータまたは列挙を超える 最小限の固有コンテンツを保持し、その主な役割は下位リソースを集約し構造化することである。 ストレージシステムのルートはコンテナとして指定され、 上位の親を持たない最上位の編成単位として機能する。コンテナは、'ContainerPage'型を使用して メンバーシップ一覧のページネーションをサポートしなければMUSTならず、'first'、 'next'、'prev'、および'last'などのプロパティを用いる。表現は、特定のフレームおよび規範的コンテキストを伴う JSON-LDを使用しなければMUSTならず、任意で'Vary: Accept'ヘッダーを介して コンテンツネゴシエーションを広告してもよい。 ストレージは、ルートコンテナとして機能し、直接書き込みを可能にしてもMAYよい。

すべてのLWSストレージには、最上位の編成単位として機能するストレージ ルートがある。ストレージルートは親を持たず、 ストレージ 階層へのエントリーポイントとして機能する。

LWS内のリソースは、次のいずれかに分類される:

7.2 包含

リソースとその親コンテナとの間の包含関係は、rel="up"リンク 関係によって表現される。サーバーは、任意の 非ルートリソースに対するGETおよびHEAD要求への応答において、親コンテナを指す rel="up"を持つLinkヘッダーを含めなければMUSTならない。

Link: </alice/notes/>; rel="up"

コンテナのメンバーは、その表現内で itemsプロパティを用いて一覧化される。サーバーがこの一覧を管理するため、クライアントは直接変更できない。 メンバーシップの変更は、リソースの作成および削除の副作用として発生する。

7.3 包含の完全性

サーバーは、常に包含の完全性を維持しなければMUSTならない:

7.4 リソース識別

リソースはURIによって識別される。リソースのURIは、包含階層における位置とは独立している。サーバーは、リソース作成時にURIを割り当て、 クライアントヒント(例: Slugヘッダー)を組み込んでもMAYよいが、 クライアントはURI構造が包含を反映していると仮定すべきではSHOULD NOTない。

包含関係は、URIパス構造ではなく、メタデータ (rel="up"リンクおよびコンテナ 表現内のitemsプロパティ)を通じて表現される。この分離により、明確に定義された編成モデルを維持しながら、 サーバーはURI割り当てに柔軟性を持てる。

7.5 コンテナメンバーシップ と認可

クライアントがコンテナへの読み取りアクセス権を持つ場合、 コンテナ 表現は、そのコンテナに含まれるリソースのうち、 クライアントがアクセス権を持つすべてのリソースの識別子を含まなければMUSTならない。また、そのコンテナに含まれるリソースのうち、クライアントがアクセス権を持たないリソースの識別子を 含んでもMAYよい。

クライアントがコンテナ一覧を読み取れることは、含まれる リソース自体へのアクセス権を意味せず、その逆も同様である。

8. コンテナ

8.1 コンテナ表現

クライアントがコンテナを取得する場合、サーバーは、そのコンテナおよびその内容を記述する構造化されたコンテナ 表現を返す。この節は、 コンテナ表現の必須および任意のプロパティを定義する。

8.1.1 コンテナプロパティ

コンテナ表現は、次のプロパティを含まなければMUSTならない:

  • id: コンテナのURI。
  • type: 値"Container"
  • totalItems: クライアントに開示できるコンテナ内に含まれるリソースの総数を示す整数。 この数は正確であるべきSHOULDだが、概算であってもMAYよい。
  • items: 含まれるリソース記述の配列(下記参照)。 コンテナが空の場合、これは空配列でなければMUST ならない。コンテナ一覧が ページ分割されている場合、itemsは現在のページのリソースのみを含む。詳細はページネーションを参照。

8.1.2 包含リソース 記述

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日時文字列として表現される。

8.1.3 コンテナ 表現の例

次の例は、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"
    }
  ]
}

9. 操作

この節は、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+jsonapplication/ld+json、およびapplication/jsonのコンテンツネゴシエーションをサポートしなければMUSTならない (11. LWSメディア型を参照)。サーバーはMAYさらにTurtleのような形式をサポートしてもよい。

9.1 メタデータ

この節は、LWSリソースに メタデータを関連付けるモデルを定義する。LWSメタデータシステムは、Web Linking [RFC8288]の原則に基づいており、 サーバーが型付きリンクを使用してリソース間の関係を記述できるようにする。メタデータは、 発見可能性を高め、自己記述的APIをサポートし、リソース操作およびコンテナ階層と整合する。

メタデータモデル LWSにおけるすべてのメタデータは、リソース(リンクコンテキスト)から発生する型付きリンクの集合として表現される。 各リンクは次から構成される:

メタデータは、リソースとその表現を区別し、該当する場合には複数のメディア型を 可能にする。データリソースについて、メタデータには表現が含まれ、それぞれが mediaTypeおよび任意のsizeInBytesを持つ。コンテナおよびデータリソースについては、 その親コンテナリソースへのリンクを、そのリソースのメタデータの一部とみなす。

リンクセットリソース ストレージ内の各リソースについて、サーバーは[RFC9264]に従い、 メタデータリンクを独立したリソースとして利用可能にしなければMUSTならない。

メタデータの発見 クライアントは、主にGETまたはHEAD要求への応答内のLinkヘッダーを通じてメタデータを発見する。

メタデータ型

カテゴリ 説明
システム管理 サーバーにより維持される。読み取り専用。linksettypemediaTypesizemodifiedを含む。
中核メタデータ クライアントにより管理される(サーバー制限に従う)。upitemstitlecreatorを含む。
ユーザー定義 ユーザーが作成したカスタム語彙およびインデックス。

変更可能性に関する考慮事項 中核メタデータはクライアントによって変更されてもMAYよい。相互運用性を確保するため、サーバーは 標準HTTPヘッダーを用いて自身の機能を広告しなければMUSTならない:

  1. メソッド発見: サーバーは、Allowヘッダーを介してリンクセットリソース上のGETおよびPATCH 操作のサポートを広告しなければMUSTならない。

  2. パッチ形式の発見: サーバーは、Accept-Patchヘッダーを介してJSON Merge Patch [RFC7386]のサポートを広告しなければMUSTならない: Accept-Patch: application/merge-patch+json.

  3. 任意メソッド: サーバーはPUTまたは代替パッチ形式をサポートしてもMAYよい。 サポートする場合、それらはそれぞれAllowおよびAccept-Patch ヘッダーに含められなければMUSTならない。

[!IMPORTANT] クライアントは、リソースヘッダーで広告されていない限り、PUTまたは特定のパッチ形式のサポートを 仮定すべきではSHOULD NOTなく、405 Method Not Allowedまたは415 Unsupported Media Type応答を適切に処理しなければMUSTならない。

メタデータの管理 メタデータは、リソースに関連付けられたリンクセットリソース URIとやり取りすることで管理される。サーバーは、更新のための同時実行制御をサポートしなければMUSTならない。

9.2 リソースを作成する

リソースを作成する操作は、新しい提供リソースを既存のコンテナに追加する。この 操作は、データリソースおよびサブコンテナの作成の両方を扱う。

入力:

振る舞い:

可能な応答:

新しいリソースは、対象コンテナ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よい。クライアントは、作成するリソースの型を次のように示す:

例(新しいデータリソースを作成する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バインディング)に関する追加注記:

メタデータの管理および取得(作成に関連): メタデータは主に読み取り操作を介して取得されるが、作成時に生成される。クライアントは、 作成後すぐに、新しいリソースURI上でGETまたはHEADを使用してそれを取得できる。クライアントは、 Preferヘッダーを使用して、特定のメタデータリンク(関係型を介する)および 属性の包含を要求できる。

9.3 リソースを読み取る

既存リソースの表現、またはコンテナの一覧を取得する。

リソースを読み取る操作は、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を使用し、必須メタデータを持つメンバーを一覧化する。各項目は、 フラットなプロパティとしてtypeidmediaTypesize、および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である。

9.4 リソースを更新する

完全置換または部分パッチを介して、既存の[提供リソース]の状態を変更する。

リソースを更新するは、 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を含め、 ヘッダーも伴うことができる。

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する。両方を設定することは既定ではオフである。

9.5 リソースを削除する

リソースおよびその関連メタデータを恒久的に削除する。

リソースを削除する操作は、上記の抽象 操作で定義されるように、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

9.6 HTTPステータス マッピングの概要

この表は、ページネーション、同時実行制御、クォータ制約、およびメタデータ統合などの 特定シナリオを組み込みながら、一貫性のために汎用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である。

10. アクセス要求と許可

アクセス要求と許可は、エージェントがリソースへのアクセスを要求し、 ストレージコントローラーが定義された制約付きでアクセスを許可するためのメカニズムを提供する。 アクセスを要求および許可するためのエンドポイントは、特殊化された受信箱の一種として機能する。

エージェントは、 アクセス許可を認可トークンとしてサーバーに提示するわけではない。 むしろ、アクセス許可は、何が、誰に対して、 どの制約の下で認可されたかの記録として機能する。アクセス許可が作成または取消(削除)された場合、 その変更を反映するために基礎となるアクセスポリシーを調整する責任はサーバーにある。 アクセス許可エンドポイントと特定のポリシー 適用層とのやり取りは、この仕様の範囲外である。

この節で定義されるアクセスプロファイルは、 アクション、制約、および譲受人を含む Open Digital Rights Language(ODRL)の概念に基づく。 他のプロファイルは、異なる概念的フレームワークを使用してもよい。

課題: 主要な用語節と 統合する

この節は、次の用語を定義する:

  • アクセス要求エージェントによって送信されるデータオブジェクトであり、 望ましい範囲および制約を含め、ストレージリソースに対して特定のアクションを実行する 要求を表現する。
  • アクセス許可ストレージコントローラーによって作成されるデータオブジェクトであり、 エージェントが、一定の定義された制約内で ストレージリソースに対して 特定のアクションを実行できる能力を表現する。
  • アクセスプロファイル — アクセスプロファイルは、 有効なアクセスポリシーを表現するための要件を記述する。すべてのアクセスプロファイルは URIで識別され、サーバーは、その ストレージ記述リソース内のサービスオブジェクトの conformsToプロパティでそれらを参照することにより、1つ以上のアクセスプロファイルのサポートを示す。

10.1 発見

ストレージは、そのストレージ記述リソース内で、 アクセス要求および アクセス許可のサポートを広告してもMAYよい。 そのようなサポートが広告される場合、アクセス要求用エンドポイントを記述するサービス オブジェクトは、文字列AccessRequestServiceに等しいtypeを持たなければ MUSTならず、アクセス許可用エンドポイントを記述する サービスオブジェクトは、文字列AccessGrantServiceに等しい typeを持たなければMUSTならない。サービス オブジェクトは、そのエンドポイントでサポートされるアクセスプロファイルを識別する 1つ以上のURIの集合を値とするconformsToプロパティを含むべきSHOULDである。 追加のプロパティが含まれてもMAYよい:

10: アクセス要求および許可 サービスを持つストレージ記述
{
  "@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"]
    }
  ]
}

10.2 データモデル

アクセス要求またはアクセス許可は、 身元およびルーティングのためのプロパティ、ならびに 要求または許可された操作を記述するaccessオブジェクトを表現するデータ オブジェクトである。ODRL概念を用いてアクセス要求を記述する プロファイルは、10.3 アクセスプロファイルで記述される。

次の例は、アクセス要求を示す。この例は、 10.4.1 JSON-LDシリアル化で定義されるJSON-LDシリアル化を用いて示される。

11: アクセス要求
{
  "@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シリアル化を用いて示される。

12: アクセス許可
{
  "@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よい。

10.2.1

typeプロパティは、文書の型を表現する。

typeプロパティの値は、1つ以上の 用語および 絶対URL文字列でなければ MUSTならない。アクセス要求について、その値は用語AccessRequestを 含まなければMUSTならない。 アクセス許可について、その値は用語 AccessGrantを含まなければMUSTならない。 追加の型値が含まれてもMAYよい。

このプロパティはREQUIREDである。

この文書は、アクセス要求および アクセス許可について、次の型値を定義する:

13: typeプロパティ
{
  "type": ["AccessGrant"]
}

10.2.2 ストレージ

storageプロパティは、 アクセス要求またはアクセス許可の範囲となる LWSストレージを識別する。

storageプロパティの値はURIでなければMUSTならない。

このプロパティはREQUIREDである。

14: storageプロパティ
{
  "storage": "https://storage.example/"
}

10.2.3 受信箱

inboxプロパティは、 アクセス要求またはアクセス許可に関連する通知を受け取るためのURIを指定する (10.6 通知を参照)。

inboxプロパティの値はURIでなければMUSTならない。

このプロパティはOPTIONALである。

15: inboxプロパティ
{
  "inbox": "https://id.example/agent/inbox/"
}

10.2.4 アクセス

accessプロパティは、サーバーによってサポートされるプロファイルに基づき、 1つ以上のアクセスプロファイルの特性を記述する。 ODRL情報モデルに基づく プロファイルは、10.3 アクセスプロファイルで 記述される。

accessプロパティの値は、1つ以上のオブジェクトの集合でなければ MUSTならない。

このプロパティはREQUIREDである。

10.3 アクセスプロファイル

この仕様は、 ODRL情報モデルおよびODRL 語彙に基づくアクセスプロファイルを定義し、 次のURLで識別される: https://www.w3.org/ns/lws#AccessProfile.

10.3.1

typeプロパティは、アクセスポリシーの型を表現する。

typeプロパティの値は、1つ以上の 用語および 絶対URL文字列でなければ MUSTならず、用語AccessPolicyを含まなければ MUSTならない。追加の型値が含まれてもMAYよい。

このプロパティはREQUIREDである。

16: アクセスポリシー型
{
  "access": [{
    "type": ["AccessPolicy"]
  }]
}

10.3.2 アクション

actionプロパティは、エージェントが 実行したい(要求の場合)、または実行することを認可されている(許可の場合) 操作を記述する。

actionプロパティの値は、1つ以上の 文字列の集合でなければMUSTならない。各値は、サーバーが認識する操作に対応しなければ MUSTならない。次の値をサポートしなければMUSTならない: readmodifycreate、およびdeletereadmodify、およびdeleteの値は、 ODRL語彙によって定義される。 create値は、この 仕様によって定義される。

これらのアクション値は、次のようにLWS操作に対応する:

  • read — リソースまたはそのメタデータを取得する(HTTP GET、HEAD)
  • modify — 既存リソースを変更する(HTTP PUT、PATCH)
  • create — コンテナ内に新しいリソースを作成する(HTTP POST)
  • delete — 既存リソースを削除する(HTTP DELETE)

このプロパティはREQUIREDである。

17: actionプロパティ
{
  "access": [{
    "action": ["read", "create"]
  }]
}

10.3.3 譲受人

assigneeプロパティは、アクセスを要求している当事者(要求の場合)、 またはアクセスを許可されている当事者(許可の場合)を識別する。

assigneeプロパティの値はURIでなければMUSTならない。 公開アクセスは、 http://xmlns.com/foaf/0.1/AgentというURIで識別される、 FOAF 語彙Agentクラスを用いて割り当てられてもMAYよい。

このプロパティはREQUIREDである。

18: assigneeプロパティ
{
  "access": [{
    "assignee": "https://id.example/agent"
  }]
}

10.3.4 対象

targetプロパティは、 アクセス要求またはアクセス許可が 適用されるリソースを識別する。

targetプロパティは、次のプロパティを含む オブジェクトでなければMUSTならない:

  • type — 対象マッチャーの型を識別する 用語または 絶対URL文字列
  • value — 対象リソースを識別するために使用される 1つ以上の文字列の集合。

この仕様は、対象オブジェクトで使用する次の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である。

19: リソース型を持つtargetプロパティ
{
  "access": [{
    "target": {
      "type": "StorageResource",
      "value": [
        "https://storage.example/data/2025",
        "https://storage.example/data/2026"
      ]
    }
  }]
}

10.3.5 制約

constraintプロパティは、要求または許可されるアクセスを 制限または限定する条件を定義する。このプロパティは、ODRL Constraintモデルを使用する。

constraintプロパティの値は、存在する場合、制約オブジェクトの 集合でなければMUSTならない。各制約オブジェクトは、次の プロパティを含まなければMUSTならない:

  • leftOperand — 制約されるオペランドを識別する文字列。
  • operator — 比較演算子を識別する文字列。
  • rightOperand — 比較対象となる値。型は leftOperandに依存する。

複数の制約オブジェクトが存在する場合、それらはすべて満たされなければ MUSTならない。

このプロファイルのサポートを広告するサーバーは、次の leftOperand値をサポートしなければMUSTならない:

  • client — HTTP要求のクライアント識別子を表す
  • mediaType — 対象HTTPリソースのメディア型を表す
  • type — リソースのLinkヘッダーで表現される型URLを表す
  • purpose — 要求または許可されるアクセスの意図された用途を表す
  • dateTime — 現在日時を表す

このプロパティはOPTIONALである。

次の例は、これらの制約の使用を示す:

10.3.5.1 目的の制約

次の例は、leftOperandpurposeを使用して、要求または許可されるアクセスの意図された 用途を記述する。eq演算子が使用される場合、 rightOperand値は目的を識別するURIである。 isAnyOf演算子が使用される場合、rightOperand 値は目的URIの配列であり、表明された目的が列挙された値のいずれかに一致する場合に 制約は満たされる:

20: 目的の制約
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "purpose",
        "operator": "isAnyOf",
        "rightOperand": [
          "https://purpose.example/collaboration",
          "https://purpose.example/research"
        ]
      }
    ]
  }]
}
10.3.5.2 クライアントの制約

次の例は、leftOperandclientを使用して、特定のクライアントアプリケーションに アクセスを制限する。eq演算子が使用される場合、 rightOperand値はクライアントを識別するURIである:

21: クライアントの制約
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "client",
        "operator": "eq",
        "rightOperand": "https://app.example/client-id"
      }
    ]
  }]
}
10.3.5.3 メディア型 制約

次の例は、leftOperandmediaTypeを使用して、 特定のメディア型を持つリソースへのアクセスを制限する。eq演算子が 使用される場合、rightOperand値は IANAメディア型を識別する文字列である。 isAnyOf演算子が使用される場合、rightOperand値 はメディア型文字列の配列であり、リソースの メディア型が列挙された値のいずれかに一致する場合にアクセスが許可される:

22: メディア型の制約
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "mediaType",
        "operator": "isAnyOf",
        "rightOperand": ["image/jpeg", "image/png"]
      }
    ]
  }]
}
10.3.5.4 リソース型 制約

すべてのLWSリソースは、型値を示すLinkヘッダーを含む:

次の例は、leftOperandtypeを使用して、HTTP Linkヘッダーで広告された リソース型に基づきアクセスを制限する。 eq演算子が使用される場合、rightOperand値 はリソース型を識別するURIである。isAnyOf演算子が 使用される場合、rightOperand値は型URIの配列であり、リソースの型が 列挙された値のいずれかに一致する場合にアクセスが許可される:

24: リソース型の制約
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "type",
        "operator": "isAnyOf",
        "rightOperand": [
          "https://type.example/Playlist",
          "https://type.example/Song"
        ]
      }
    ]
  }]
}
10.3.5.5 時間的制約

次の例は、leftOperanddateTimeを使用して、特定の時間枠に アクセスを制限する。gteq演算子は 時間枠の開始を定義し、lteq演算子は終了を定義する。 時間的制約のrightOperand値は、 XML SchemadateTime文字列である:

25: 時間的制約
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "dateTime",
        "operator": "gteq",
        "rightOperand": "2026-03-09T12:00:00Z"
      },
      {
        "leftOperand": "dateTime",
        "operator": "lteq",
        "rightOperand": "2026-06-09T10:00:00Z"
      }
    ]
  }]
}
10.3.5.6 制約の組み合わせ

複数の制約オブジェクトが存在する場合、アクセスが許可されるためには、それらはすべて 満たされなければMUSTならない。次の例は、 特定の日付より前に特定のクライアントアプリケーションへアクセスを制限する:

26: 組み合わせられた制約
{
  "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"
      }
    ]
  }]
}

10.4 シリアル化

この節で定義されるデータモデルは、特定の シリアル化から独立している。

10.4.1 JSON-LDシリアル化

この仕様は、アクセス要求および アクセス許可のためのJSON-LDシリアル化を定義する。 このシリアル化を使用する文書は、 https://www.w3.org/ns/lws/v1を含む順序付き集合を値とする @contextプロパティを含まなければMUSTならない。拡張用語を定義するために、追加のコンテキストエントリーが 含まれてもMAYよい。

このシリアル化に関連付けられるメディア型はapplication/lws+jsonである。

27: JSON-LD @context
{
  "@context": [
    "https://www.w3.org/ns/lws/v1"
  ]
}

10.5 プロトコル

アクセス要求およびアクセス許可のエンドポイント はLWSコンテナであり、この仕様で定義される規則に適合しなければMUST ならない。

これらのエンドポイントは、少なくともGETおよびPOST操作のサポートを必要とする。DELETE操作は RECOMMENDEDである。他の操作がサポートされてもMAYよい。

これらのエンドポイントは、要求および応答ペイロードの両方について、 10.4.1 JSON-LD シリアル化で定義されるJSON-LDシリアル化をサポートしなければMUSTならない。 サーバーは追加のシリアル化をサポートしてもMAYよい。

エージェントは、 アクセス要求エンドポイントへ POST要求を送信することで、アクセス要求を作成する。 ストレージ コントローラーは、アクセス許可エンドポイントへ POST要求を送信することで、アクセス許可を作成する。

成功したPOST操作は、新しいリソースのURLに設定された Locationヘッダーを返して応答しなければMUSTならない。

10.5.1 アクセス要求エンドポイント

  • POST / — アクセス要求を作成する。
  • GET / — アクセス要求の一覧を取得する。
  • GET /:id — 特定のアクセス要求を取得する。
  • DELETE /:id — アクセス要求を取り消す。

10.5.2 アクセス許可エンドポイント

  • POST / — アクセス許可を作成する。
  • GET / — アクセス許可の一覧を取得する。
  • GET /:id — 特定のアクセス許可を取得する。
  • DELETE /:id — アクセス許可を取り消す。

10.6 通知

課題 103: LWS Notifications Feature work-item

この節は、まだ定義されていないLWSの通知節と整合させる必要がある。

通知は、エージェントおよびストレージ コントローラーに対して、 アクセス要求およびアクセス許可の変更を知らせるための メカニズムを提供する。アクセス要求またはアクセス許可inboxプロパティが存在する場合、サーバーは 譲受人にイベントを知らせる通知をそのエンドポイントへ配信すべきSHOULDである。

通知のシリアル化は、LWS通知データモデルの要件に適合しなければMUSTならない。

inboxエンドポイントに配信される通知は、通知配信のためのLWSプロトコルで定義される 要件に適合しなければMUSTならない。

注記

この節で記述される通知メカニズムは、 Linked Data Notificationsパターンと比較できる。 そのパターンでは、通知はinboxプロパティを介して発見され、 その受信箱へPOST要求を送信することで配信される。

10.6.1 通知イベント

サーバーは、次のイベントに応じて通知を送信すべきSHOULDである:

サーバーは、他のイベントに応じて通知を送信してもMAYよい。

11. LWSメディア型

11.1 LWSメディア型

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である。

11.1.1 コンテンツネゴシエーション

サーバーは、コンテナ表現についてコンテンツネゴシエーションをサポートしなければ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)を 自由にサポートできる。

11.1.2 ページネーション

コンテナのような特定の複合リソースは、多数のリソースを保持することがある。 クライアントが一覧を段階的に取得できるようにするため、サーバーは、メンバーシップがサーバーによって決定された しきい値を超えるコンテナについて、ページネーションをサポートすべき SHOULDである。

11.1.2.1 ページネーションモデル

ページネーションはリンクに基づく: サーバーはHTTP Linkヘッダーを介してページネーションURIを提供する [RFC8288]。 これにより、クライアントは数値オフセットに依存することなく完全な一覧をナビゲートできる。

一覧がページ分割される場合、応答本文には現在のページの項目のみが含まれる。 複合リソースのidtype、およびtotalItemsプロパティは メンバーシップ全体を反映し、itemsには現在のページ上のリソースのみが含まれる。

11.1.2.3 ページの要求

クライアントは、最初のページを取得するために複合リソースのURIを要求する。応答には、クライアントが 後続ページを取得するために辿るページネーション Linkヘッダーが含まれる。サーバーは、以前の走査中に取得されたページネーションURIを介して、 特定ページへの直接アクセスもサポートしてもMAYよい。

ページ分割された応答が返される場合、サーバーは200 OKで応答しなければMUSTならない。応答本文のtotalItems プロパティは、現在のページだけでなく、全ページにわたる項目の総数を反映すべき SHOULDである。

11.1.2.4 例: ページ分割されたコンテナ

要求:

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"
    }
  ]
}

12. JSON-LDコンテキストと語彙

12.1 JSON-LDコンテキストと 語彙

12.1.1 規範的JSON-LDコンテキスト

コンテナ表現は、次の@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であり、用語定義が他のコンテキストによって上書きされないことを保証する。

12.1.2 語彙

LWS語彙は、コンテナ 表現で使用される次の型およびプロパティを定義する:

型:

用語 URI 説明
Container lws:Container 他のリソースを含むリソース
DataResource lws:DataResource データを保持するリソース

プロパティ:

用語 URI 説明
items lws:items コンテナに含まれるリソースの一覧
totalItems as:totalItems 含まれるリソースの総数
mediaType as:mediaType リソースのメディア型
size schema:size リソースのサイズ(バイト単位)
modified as:updated リソースが最後に変更された日時

13. リソース識別

URIスキーム、リソース命名規約、および解決メカニズムを含め、LWSプロトコル内で リソースがどのように識別されアドレス指定されるかを定義する。この節は、別の節、たとえばリソースアクセスへ移動される可能性がある

ここは意図的に空白のままとする

14. 移植性に関する考慮事項

相互運用性を維持しながら、LWS実装が異なるプラットフォーム、環境、およびストレージバックエンドで動作できることを保証するための 考慮事項を記述し、ストレージプロバイダーの変更を可能にするアフォーダンスを提供する

ここは意図的に空白のままとする

15. セキュリティに関する考慮事項

この節は非規範的である。

安全なLWS展開のための脅威モデル、セキュリティ要件、および 実装ガイダンスを扱う正式なセキュリティ考慮事項の節。

OAuth 2.0 SecurityのBest Current Practice [RFC9700]で記述される推奨事項は、この 仕様に適用される。

15.1 トランスポートセキュリティ

この節は非規範的である。

Transport Layer Security(TLS)は、改ざん、なりすまし、および 情報開示を防止するための重要なメカニズムである。TLSで保護された通信は、[RFC6125]に従って検証できる。 実装に関するセキュリティ考慮事項は、「Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)」[RFC9325]で確認できる。

15.2 トークンセキュリティ

この節は非規範的である。

ベアラートークンおよびデジタル資格情報は、盗難およびリプレイに対して脆弱である。 緩和策には、合理的に短い存続期間を使用すること、トークンを特定のオーディエンスにバインドすること、 およびトークンを安全に保存することが含まれる。

15.3 アクセス要求と許可

この節は非規範的である。

16. プライバシーに関する考慮事項

この節は非規範的である。

データ最小化、ユーザー同意、および プライバシー保護型実装パターンを含む、LWSプロトコルのプライバシー上の影響。

資格情報は、ユーザーおよびエージェントに関する情報を運ぶ。デジタル署名は改ざんから保護できるが、 クライアントまたは第三者が暗号化されていない資格情報内部の値を読み取ることは可能である。

その結果、資格情報発行者は、認証または認可に必要な情報のみを含むトークンを作成し、 必要でない限り機微な属性を含めないことが推奨される。

一般に、暗号化されていない資格情報データをログに書き込むことはアンチパターンである。これが 必要な場合、実装は、資格情報主体のプライバシーを保護するために、資格情報を切り詰めるかハッシュ化できる。

JWTで仮名識別子を使用する場合、ストレージサーバーは同じエージェント からの要求を時間の経過にわたり相関できる可能性がある。 この場合にユーザープライバシーを保護するため、クライアントアプリケーションは、各 JWTが一度だけ使用されるJWTのバッチ発行を要求できる。 これは、JWTコンテンツの類似性や送信元IPアドレスなどの他の情報を使用して ストレージサーバーが要求を相関することを防がない。仮名識別子を使用する場合、認可サーバーは 同じ識別子を複数回発行しないよう注意する必要がある。

16.1 アクセス要求と許可

この節は非規範的である。

17. IANAに関する考慮事項

この節は非規範的である。

17.1 well-known URIレジストリ

この仕様は、RFC 5785 [RFC5785]によって確立された 「Well-Known URIs」レジストリに、 次の値を追加する。

17.2 OAuth 認可サーバーメタデータレジストリ

この仕様は、[RFC8414]によって確立された 「OAuth Authorization Server Metadata」レジストリに、 次の値を追加する。

17.3 application/lws+jsonメディア型

この仕様は、Linked Web Storageコンテナ形式に適合する文書を識別するために、 application/lws+jsonメディア型を登録する。

Linked Web Storage形式はJSON-LDの規約を使用するが、LWS実装には、 特定のメディア型の使用を正当化する多くの制約および追加要件があることに注意すること。

LWSコンテナはJSON-LDの制限されたプロファイルとみなせるため、実装は、 application/ld+json; profile="https://www.w3.org/ns/lws/v1"メディア型を application/lws+jsonと等価なものとして扱うべきSHOULDである。

A. 謝辞

この節は非規範的である。

この仕様は、Solid Protocol [Solid-Protocol]に大きく依拠している。同プロトコルは、長期間にわたり Sarven Capadisli、Tim Berners-Lee、Kjetil Kjernsmo、Ruben Verborgh、Justin Bingham、Dmitri Zagidulinによって編集された。

B. 参考文献

B.1 規範的参考文献

[FOAF]
FOAF Vocabulary Specification 0.99 (Paddington Edition). Dan Brickley; Libby Miller. FOAF project. 14 January 2014. URL: http://xmlns.com/foaf/spec/
[JSON-LD11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11/
[ODRL-MODEL]
ODRL Information Model 2.2. Renato Iannella; Serena Villata. W3C. 15 February 2018. W3C Recommendation. URL: https://www.w3.org/TR/odrl-model/
[ODRL-VOCAB]
ODRL Vocabulary & Expression 2.2. Renato Iannella; Michael Steidl; Stuart Myles; Víctor Rodríguez-Doncel. W3C. 15 February 2018. W3C Recommendation. URL: https://www.w3.org/TR/odrl-vocab/
[OPENID-CONNECT-CORE]
OpenID Connect Core 1.0 incorporating errata set 2. N. Sakimura; J. Bradley; M. Jones; B. de Medeiros; C. Mortimore. OpenID Foundation. 15 December 2023. Final. URL: https://openid.net/specs/openid-connect-core-1_0.html
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4918]
HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV). L. Dusseault, Ed. IETF. June 2007. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4918
[RFC5789]
PATCH Method for HTTP. L. Dusseault; J. Snell. IETF. March 2010. Proposed Standard. URL: https://httpwg.org/specs/rfc5789.html
[RFC6585]
Additional HTTP Status Codes. M. Nottingham; R. Fielding. IETF. April 2012. Proposed Standard. URL: https://httpwg.org/specs/rfc6585.html
[RFC6749]
The OAuth 2.0 Authorization Framework. D. Hardt, Ed. IETF. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6749
[RFC6750]
The OAuth 2.0 Authorization Framework: Bearer Token Usage. M. Jones; D. Hardt. IETF. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6750
[RFC7231]
Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. R. Fielding, Ed.; J. Reschke, Ed. IETF. June 2014. Proposed Standard. URL: https://httpwg.org/specs/rfc7231.html
[RFC7232]
Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests. R. Fielding, Ed.; J. Reschke, Ed. IETF. June 2014. Proposed Standard. URL: https://httpwg.org/specs/rfc7232.html
[RFC7233]
Hypertext Transfer Protocol (HTTP/1.1): Range Requests. R. Fielding, Ed.; Y. Lafon, Ed.; J. Reschke, Ed. IETF. June 2014. Proposed Standard. URL: https://httpwg.org/specs/rfc7233.html
[RFC7240]
Prefer Header for HTTP. J. Snell. IETF. June 2014. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7240
[RFC7386]
JSON Merge Patch. P. Hoffman; J. Snell. IETF. October 2014. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7386
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8288]
Web Linking. M. Nottingham. IETF. October 2017. Proposed Standard. URL: https://httpwg.org/specs/rfc8288.html
[RFC8414]
OAuth 2.0 Authorization Server Metadata. M. Jones; N. Sakimura; J. Bradley. IETF. June 2018. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8414
[RFC8693]
OAuth 2.0 Token Exchange. M. Jones; A. Nadalin; B. Campbell, Ed.; J. Bradley; C. Mortimore. IETF. January 2020. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8693
[RFC9068]
JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens. V. Bertocci. IETF. October 2021. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9068
[RFC9110]
HTTP Semantics. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[rfc9112]
HTTP/1.1. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9112.html
[RFC9264]
Linkset: Media Types and a Link Relation Type for Link Sets. E. Wilde; H. Van de Sompel. IETF. July 2022. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9264
[RFC9457]
Problem Details for HTTP APIs. M. Nottingham; E. Wilde; S. Dalal. IETF. July 2023. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9457
[URL]
URL Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[WebArch]
Architecture of the World Wide Web, Volume One. Ian Jacobs; Norman Walsh. W3C. 15 December 2004. W3C Recommendation. URL: https://www.w3.org/TR/webarch/
[XMLSCHEMA11-2]
W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 5 April 2012. W3C Recommendation. URL: https://www.w3.org/TR/xmlschema11-2/

B.2 参考情報文献

[LDN]
Linked Data Notifications. Sarven Capadisli; Amy Guy. W3C. 2 May 2017. W3C Recommendation. URL: https://www.w3.org/TR/ldn/
[RFC5785]
Defining Well-Known Uniform Resource Identifiers (URIs). M. Nottingham; E. Hammer-Lahav. IETF. April 2010. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5785
[RFC6125]
Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS). P. Saint-Andre; J. Hodges. IETF. March 2011. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6125
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format. T. Bray, Ed. IETF. December 2017. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc8259
[RFC9325]
Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS). Y. Sheffer; P. Saint-Andre; T. Fossati. IETF. November 2022. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc9325
[RFC9700]
Best Current Practice for OAuth 2.0 Security. T. Lodderstedt; J. Bradley; A. Labunets; D. Fett. IETF. January 2025. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc9700
[Solid-Protocol]
Solid Protocol. Sarven Capadisli; Tim Berners-Lee; Kjetil Kjernsmo. Solid Community Group. 12 May 2024. Draft Community Group Report. URL: https://solidproject.org/TR/protocol