Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Linked Web Storage Protocol 명세는 애플리케이션이 상호 운용 가능한 방식으로 외부에 저장된 데이터에 안전하고 권한이 부여된 접근을 할 수 있도록 하는 것을 목표로 한다.
이 절은 발행 당시 이 문서의 상태를 설명한다. 현재 W3C 발행물과 이 기술 보고서의 최신 개정판 목록은 W3C 표준 및 초안 색인에서 확인할 수 있다.
이는 비공식 제안이다.
이 문서는 Linked Web Storage Working Group에서 권고안 트랙을 사용하여 작업 초안으로 발행했다.
작업 초안으로의 발행은 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" 문을 준수해야 한다.
LWS 클라이언트는 이 명세의 관련 "MUST" 문을 모두 준수하는 HTTP 클라이언트 [rfc9112]이다. 구체적으로, 이 문서의 9. 작업에 있는 관련 규범적 "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 권한 부여 프레임워크와 함께 사용할 수 있는 방법을 설명한다.
이 절에서 설명하는 데이터 모델은 인증 자격 증명의 모든 구체적인 직렬화에 대한 요구사항을 개괄한다.
인증 자격 증명은 주체에 관한 변조 증거가 있는 클레임을 포함해야 하며, 여기에는 다음이 포함된다:
인증 자격 증명의 검증에는 자격 증명의 검증자와 발급자 사이의 신뢰 관계가 필요하다. 이 신뢰 관계는 MAY 대역 외 메커니즘을 통해 수립될 수 있다. 검증자와 발급자 사이의 신뢰를 수립하기 위한 추가 메커니즘은 특정 인증 스위트에 개괄된다.
인증 자격 증명은 MUST 서명되어야 한다. 그 서명에 비대칭 암호화를 사용하는 것이 RECOMMENDED된다.
각 인증 스위트는 토큰 유형 URI와 연관되어야 한다. 인증 스위트는 IANA "OAuth URI" 레지스트리에 정의된 URI를 사용하는 것이 SHOULD된다.
스토리지 설명 리소스는 클라이언트가 스토리지와 상호작용할 때 사용할 수 있는 정보를 제공하며, 여기에는 기능 및 서비스 엔드포인트에 대한 설명이 포함된다.
id - id 속성은 REQUIRED이다. 그 값은
스토리지를 식별하는 URI여야 한다.
type - type 속성은 REQUIRED이다.
그 값은
Storage와 같은 문자열이거나 Storage와 같은 항목을 포함하는 문자열 집합이어야 한다
(대소문자 구분).
capability - capability 속성은 OPTIONAL이다. 그 값은 기능의 집합이어야 하며,
각 기능은 다음 속성을 포함하는 맵으로 설명된다.
추가 속성이 존재할 MAY 있다.
id - id 속성은 OPTIONAL이다. 존재하는 경우, 그 값은 URI여야 한다.type - type 속성은 REQUIRED이다. 그 값은 문자열 또는 문자열 집합이어야 한다.service - service 속성은 REQUIRED이다. 그 값은 서비스의 집합이어야 하며,
각 서비스는 다음 속성을 포함하는 맵으로 설명된다. 추가
속성이 존재할 MAY 있다.
id - id 속성은 OPTIONAL이다. 존재하는 경우, 그 값은 URI여야 한다.type - type 속성은 REQUIRED이다. 그 값은 문자열
또는 문자열 집합이어야 한다.serviceEndpoint - serviceEndpoint
속성은 REQUIRED이다. 그 값은
URI여야 한다.{
"@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인
Link 헤더를 포함해야 하며, 그 값이
https://www.w3.org/ns/lws#storageDescription와 같은 관계
(rel) 매개변수를 포함해야 한다.
역참조될 때, 스토리지 설명은
스토리지를
식별하는 id 속성을 포함해야 한다.
또한 service 속성은 그 type이
StorageDescription과 같고 serviceEndpoint가
스토리지 설명의 URL과 같은
서비스 설명을 포함해야 한다.
StorageDescription 서비스 외에도, 스토리지 설명
리소스는
스토리지에 연결된 다른 서비스에 대한 링크를 포함할 수 있다.
이러한 서비스의 API 정의는 이 명세의 범위를 벗어난다.
스토리지 설명 리소스는
미디어 유형 application/lws+json으로 직렬화 가능해야 한다.
다른 표현은 콘텐츠 협상을 통해 사용 가능할 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' 유형을 사용하여 구성원 목록에 대한 페이지네이션을 지원해야 하며, 'first', 'next', 'prev', 'last'와 같은 속성을 가진다. 표현은 특정 프레임과 규범적 컨텍스트를 가진 JSON-LD를 사용해야 하며, 선택적으로 'Vary: Accept' 헤더를 통해 콘텐츠 협상을 알릴 수 있다. 스토리지는 루트 컨테이너로 기능하여 직접 쓰기를 가능하게 할 MAY 있다.
모든 LWS 스토리지에는 최상위 조직 단위 역할을 하는 스토리지 루트가 있다. 스토리지 루트는 부모가 없으며 스토리지 계층의 진입점 역할을 한다.
LWS의 리소스는 다음 중 하나로 분류된다:
리소스와 그 부모 컨테이너 사이의 포함 관계는 rel="up" 링크
관계를 통해 표현된다. 서버는 루트가 아닌 모든 리소스에 대한 GET 및 HEAD 요청의 응답에서
부모 컨테이너를 가리키는 rel="up"이 있는 Link 헤더를
포함해야 한다.
Link: </alice/notes/>; rel="up"
컨테이너의 구성원은 그 표현에서
items 속성을 사용하여 나열된다. 서버가 이 목록을 관리하며, 클라이언트는 이를 직접 수정할 수 없다.
구성원 변경은 리소스 생성 및 삭제의 부수 효과로 발생한다.
서버는 항상 포함 관계 무결성을 유지해야 한다:
리소스는 URI로 식별된다. 리소스의 URI는 포함 관계 계층에서의 위치와 독립적이다. 서버는 리소스
생성 중 URI를 할당하고, 클라이언트 힌트(예: Slug 헤더)를
포함할 MAY 있지만, 클라이언트는 URI 구조가 포함 관계를 반영한다고
가정해서는 안 된다.
포함
관계는 URI 경로 구조가 아니라
메타데이터(rel="up" 링크 및 컨테이너
표현의 items 속성)를 통해 표현된다. 이러한 분리는 서버가
명확히 정의된 조직 모델을 유지하면서도 URI 할당에서 유연성을 가질 수 있게 한다.
클라이언트가 컨테이너를 검색하면, 서버는 그 컨테이너와 그 내용을 설명하는 구조화된 컨테이너 표현을 반환한다. 이 절은 컨테이너 표현의 필수 및 선택 속성을 정의한다.
컨테이너 표현은 다음 속성을 포함해야 한다:
items 배열의 각 항목은 컨테이너 안에 포함된 리소스를 설명한다. 포함된 리소스 설명은
다음을 포함해야 한다:
id: 포함된 리소스의 URI.type: 리소스의 유형. "DataResource" 또는
"Container"이거나, 이 두 문자열 중 적어도 하나를 포함하는 배열이어야 한다.
서버는 추가 사용자 정의 유형을 URI로 포함할 MAY 있다
(예: ["DataResource", "http://example.org/customType"]).
포함된 리소스 설명은 다음을 포함하는 것이 SHOULD된다:
mediaType: 리소스의 미디어 유형(예:
"text/plain", "image/jpeg"). DataResources의 경우 존재해야 한다.
size: 정수로 표현된 리소스의 바이트 단위 크기.
modified: ISO 8601 date-time 문자열로 표현된,
리소스가 마지막으로 수정된 날짜와 시간.다음 예시는 두 개의 리소스를 포함하는 /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) 서버가 지원해야 하는 네 가지 핵심 작업을 정의한다. 이러한 작업은 리소스와 컨테이너를 전송 방식에 독립적인 방식으로 조작하며, 구현 세부사항보다 의미론에 초점을 둔다. 각 작업은 입력, 예상 동작 및 가능한 응답을 지정한다. 응답에는 성공 표시자, 리소스 표현(해당되는 경우) 및 오류 조건이 포함된다. 구현은 이러한 작업을 원자적이고 일관되게 처리해야 하며, 이는 각 작업이 완전히 성공하거나 부분적인 부수 효과 없이 실패해야 함을 의미한다. 오류가 발생한 경우, 응답은 민감한 정보를 누출하지 않으면서 에이전트가 문제를 이해할 수 있을 만큼 충분한 세부 정보를 제공하는 것이 SHOULD된다.
각 핵심 작업(create, read, update, delete)에 대해 사용할 HTTP 메서드, 필요한 헤더 또는 특별한 고려사항(ETags를 통한 동시성 제어, 콘텐츠 협상 및 컨테이너 목록에 대한 페이지네이션 포함), 그리고 서버가 수행하고 반환해야 하는 것을 설명한다. 표준 HTTP 상태 코드는 결과를 나타내는 데 사용되며, 할당량 초과(507 Insufficient Storage) 또는 사전 조건 실패(412 Precondition Failed)와 같은 시나리오에 대한 추가 매핑을 포함한다. 이 바인딩은 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의 콘텐츠 협상을 지원해야 한다
(11. LWS 미디어 유형 참조).
서버는 Turtle과 같은 형식을 추가로 지원할 MAY 있다.
이 절은 LWS 리소스와 메타데이터를 연결하기 위한 모델을 정의한다. LWS 메타데이터 시스템은 Web Linking [RFC8288]의 원칙을 기반으로 하며, 이를 통해 서버는 형식화된 링크를 사용하여 리소스 간 관계를 설명할 수 있다. 메타데이터는 발견 가능성을 높이고, 자기 설명적 API를 지원하며, 리소스 작업 및 컨테이너 계층과 정렬된다.
메타데이터 모델 LWS의 모든 메타데이터는 리소스(링크 컨텍스트)에서 시작되는 형식화된 링크의 집합으로 표현된다. 각 링크는 다음으로 구성된다:
메타데이터는 리소스와 그 표현을 구별하여, 해당되는 경우 여러 미디어 유형을 허용한다. 데이터 리소스의 경우, 메타데이터에는 표현이 포함되며, 각 표현은 mediaType 및 선택적 sizeInBytes를 가진다. 컨테이너와 데이터 리소스의 경우, 그 부모 컨테이너 리소스에 대한 링크를 해당 리소스의 메타데이터 일부로 간주한다.
Linkset 리소스 스토리지의 각 리소스에 대해, 서버는 [RFC9264]에 따라 메타데이터 링크를 독립형 리소스로 사용할 수 있게 해야 한다.
rel="linkset"이 있는 Link 헤더를 통해 발견 가능하다.
application/linkset+json으로 사용 가능해야 한다.
메타데이터 발견 클라이언트는 주로 GET 또는 HEAD 요청에 대한 응답의 Link 헤더를 통해 메타데이터를 발견한다.
rel="storageDescription"이 있는 Link 헤더를 지원해야 한다.
rel="up"이 있는 Link 헤더를 포함해야 한다.https://www.w3.org/ns/lws#PreferLinkRelations와 함께
Prefer 헤더 [RFC7240]를 사용할 MAY 있다.
메타데이터 유형
| 범주 | 설명 |
|---|---|
| 시스템 관리 | 서버가 유지 관리하며 읽기 전용이다. linkset, type,
mediaType, size, modified를 포함한다.
|
| 핵심 메타데이터 | 클라이언트가 관리한다(서버 제한의 적용을 받음). up,
items, title, creator를 포함한다.
|
| 사용자 정의 | 사용자가 생성한 사용자 지정 어휘 및 색인. |
수정 가능성 고려사항 핵심 메타데이터는 클라이언트가 수정할 MAY 있다. 상호 운용성을 보장하기 위해, 서버는 자신의 기능을 알리기 위해 표준 HTTP 헤더를 사용해야 한다:
메서드 발견: 서버는 Allow 헤더를 통해 linkset 리소스에 대한 GET 및 PATCH 작업 지원을 알려야 한다.
패치 형식 발견: 서버는 Accept-Patch 헤더를 통해 JSON Merge
Patch [RFC7386] 지원을 알려야 한다:
Accept-Patch: application/merge-patch+json.
선택적 메서드: 서버는 PUT 또는 대체 패치 형식을 지원할 MAY 있으며, 지원하는 경우 각각 Allow 및 Accept-Patch 헤더에 포함되어야 한다.
[!IMPORTANT] 클라이언트는 리소스 헤더에 광고되지 않은 한 PUT 또는 특정 패치 형식 지원을 가정해서는 안 되며, 405 Method Not Allowed 또는 415 Unsupported Media Type 응답을 우아하게 처리해야 한다.
메타데이터 관리 메타데이터는 리소스와 연결된 linkset 리소스 URI와 상호작용하여 관리된다. 서버는 갱신에 대한 동시성 제어를 지원해야 한다.
부분 갱신(PATCH): 이는 메타데이터 관리를 위한 주요 메커니즘이다. 서버는
application/merge-patch+json을 사용하는 PATCH를 지원해야 한다.
대체(PUT): Allow 헤더에 광고된 경우, 클라이언트는 전체 linkset을 대체할 MAY 있다. 서버가 PUT을 지원하지 않는 경우, 405 Method Not Allowed로 요청을 거부해야 한다.
제한: 서버는 시스템 무결성을 유지하기 위해 특정 링크(예:
up 또는 items)에 대한 수정을 제한할 MAY 있다.
수명주기: 메타데이터 수명주기는 설명 대상 리소스에 묶여 있다. 리소스를 삭제하면 연결된 linkset 리소스 메타데이터가 자동으로 제거되어야 한다.
리소스 생성 작업은 새 제공되는 리소스를 기존 컨테이너에 추가한다. 이 작업은 데이터 리소스와 하위 컨테이너 생성을 모두 처리한다.
입력:
동작:
가능한 응답:
새 리소스는 대상 컨테이너 URI에 POST를 사용하여 생성되며,
서버가 최종 식별자를 할당한다. 클라이언트는 Slug 헤더를 통해 이름을 제안할
MAY 있다. 클라이언트는 [RFC8288]의 Web Linking 구문에 따라 POST 요청에
하나 이상의 Link 헤더를 포함하여 새 리소스에 대한 초기 사용자 관리 메타데이터를
제공할 MAY 있다. 서버 관리 메타데이터는 생성 시 서버가 자동으로 생성해야 하며,
클라이언트가 제공한 링크로 재정의되어서는 안 된다.
성공 시, 서버는 새 URI를
Location 헤더에 넣어 201 상태 코드를 반환해야 한다. 서버는 부모 컨테이너
(rel="up")에 대한 링크와 생성된 리소스의 전용 linkset 리소스에 대한 링크
(rel="linkset"; type="application/linkset+json")를 포함하여 핵심 서버 관리 메타데이터에 대한
Link 헤더를 포함해야 한다. 추가 링크는
rel="type"(https://www.w3.org/ns/lws#Container 또는
https://www.w3.org/ns/lws#DataResource를 나타냄)를 포함하는 것이
SHOULD된다. 본문은 비어 있거나 리소스의 최소 표현을 포함할 MAY 있다.
모든 메타데이터 생성 및 링크는 일관성을 유지하기 위해 리소스 생성과 원자적이어야 한다.
POST (컨테이너 URI로) – 서버가 할당한 이름으로 생성:
기존 컨테이너 안에 새 리소스를 추가하려면 POST를 사용한다.
서버는 리소스에 식별자를 할당하며, 선택적으로 Slug 헤더를 통해 제안될 수 있다.
서버는 Slug 헤더가 명명 규칙 또는 기존 리소스와 충돌하지 않는 경우 이를 존중할
MAY 있다. 클라이언트는 생성할 리소스 유형을 다음과 같이 나타낸다:
rel="type"이 있는 Link 헤더를
포함해야 한다:
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/에 게시하고 있다.
클라이언트는 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
성공 시, 새 URI를 Location 헤더에 넣어 201 Created를 반환한다. 본문은
비어 있거나 최소 표현일 수 있다.
대상 컨테이너 /alice/notes/가 존재하지 않는 경우,
다른 상태 코드가 더 적절하지 않은 한 서버는 404 오류 상태를 반환해야 한다.
컨테이너 생성: 새 컨테이너를 생성하려면, 클라이언트는
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/에 새 컨테이너를 생성하며, 서버가 생성한 메타데이터에는
https://www.w3.org/ns/lws#Container인 rel="type"이 포함된다.
Create에 대한 추가 참고사항(HTTP 바인딩):
rel="storageDescription"이 있는 Link 헤더를 포함하는 것이
SHOULD된다.
메타데이터 관리 및 검색(생성과 관련):
메타데이터는 주로 읽기 작업을 통해 검색되지만, 생성 중에 만들어진다. 클라이언트는 생성 직후
새 리소스 URI에 GET 또는 HEAD를 사용하여 이를 즉시 검색할 수 있다. 클라이언트는
Prefer 헤더를 사용하여 특정 메타데이터 링크(관계 유형을 통해)와
속성의 포함을 요청할 수 있다.
기존 리소스의 표현 또는 컨테이너의 목록을 검색한다.
리소스 읽기 작업은 HTTP GET 요청(및 헤더 전용 요청을 위한 HEAD)으로 리소스 표현을 요청한다.
동작은 대상 URL이 컨테이너인지 또는 컨테이너가 아닌 리소스(데이터 리소스)인지에 따라 다르다.
서버는 메타데이터를 통해
리소스 유형을 구별해야 한다. 모든 응답은
rel="linkset", rel="up", rel="type"과 같은 핵심 관계에 대한
Link 헤더를 포함하여 제8.1절에 정의된 메타데이터와 통합되어야 한다. 서버는 읽기 중
리소스 상태와 그 메타데이터 사이의 원자성을 보장해야 한다.
GET (컨테이너가 아닌 리소스) – 리소스의 콘텐츠 검색: 전체 콘텐츠를 얻기 위해 리소스 URI에 GET을 보낸다(권한이 있는 경우). 200 OK, 데이터를 포함한 본문, 그리고 저장된 미디어 유형과 일치하는 Content-Type으로 응답한다. 서버는 부분 검색을 위해 [RFC7233]에 따른 범위 요청을 지원해야 한다. 응답은 동시성 제어 및 캐싱을 위해 ETag 헤더를 포함해야 한다.
예시(파일 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 타임스탬프를 평면 속성으로 포함한다.
모든 경우에, 서버는 응답 헤더에 다음 메타데이터를 포함해야 한다:
ETag(구성원 수정 시 변경되는 목록 버전을 나타냄), 그리고 그것이 컨테이너임을 나타내는
rel="type", rel="linkset", 및
rel="up"이 있는 Link 헤더.
HEAD (모든 리소스 또는 컨테이너) – 헤더/메타데이터만: LWS 서버는 컨테이너와 비컨테이너 모두에 대해 HEAD [RFC9110]를 지원해야 하며, GET과 동일한 헤더(ETag, Content-Type, 메타데이터에 대한 Link 포함)를 반환하되 본문은 반환하지 않는다. 이를 통해 콘텐츠를 전송하지 않고 메타데이터를 검색할 수 있다.
캐싱 및 조건부 요청: LWS는 HTTP 캐싱 의미론을 활용한다. 서버는 If-None-Match(ETags 사용) 또는 If-Modified-Since 헤더를 통한 조건부 요청을 지원해야 한다. 리소스 또는 컨테이너 목록이 변경되지 않은 경우, 중복 전송을 피하기 위해 304 Not Modified로 응답한다. ETags는 동시성 및 캐싱 지원을 위해 모든 GET/HEAD 응답에 제공되어야 한다.
발견 가능성 및 권한 부여: 향상된 발견 가능성을 위해, 서버는 하드코딩된 URI 없이 클라이언트를 안내하는 매개변수와 함께 401 Unauthorized 응답에 WWW-Authenticate 헤더를 포함하는 것이 SHOULD된다. 해당되는 경우 메타데이터 링크를 포함하는 것이 SHOULD된다.
전체 대체 또는 부분 패치를 통해 기존 [served resource]의 상태를 수정한다.
리소스 갱신은 PUT 요청(전체 리소스를 대체) 또는 PATCH 요청(부분 수정을 적용)을 통해 기존 제공되는 리소스의 콘텐츠를 수정한다. 클라이언트는 이러한 작업을 수행하려면 리소스 URL에 대한 쓰기 접근 권한을 가져야 한다. 참고: 이 절은 리소스의 기본 콘텐츠 갱신을 설명한다. 그 메타데이터를 갱신하려면 제9.3.2절을 참조하라. LWS 서버는 리소스 URI에 대한 PUT 및 PATCH 요청을 리소스 콘텐츠에 대한 수정으로만 처리해야 하며, 연결된 linkset 리소스에는 기본적으로 영향을 주지 않아야 한다. 콘텐츠와 메타데이터를 하나의 원자적 작업으로 선택적으로 갱신하려면, 클라이언트는 리소스 URI에 대한 PUT/PATCH 요청에 Link 헤더를 포함하고 'Prefer: set-linkset' 선호사항(RFC 7240에 정의됨)을 지정할 MAY 있다. 이 경우, 서버는 제공된 Link 헤더를 콘텐츠 변경 적용과 더불어 linkset에 대한 대체(PUT의 경우) 또는 부분 갱신(PATCH의 경우)으로 해석해야 한다. 이 동작은 서버에게 OPTIONAL이지만, 지원되는 경우 의도하지 않은 메타데이터 덮어쓰기를 방지하기 위해 Prefer 헤더를 통해 명시적으로 호출되어야 한다. 결합 갱신을 지원하지 않는 서버는 선호사항을 무시하거나 501 Not Implemented로 응답해야 한다.
PUT (전체 리소스 대체) – 리소스 URI에 PUT을 보내며, 본문에는 새 전체 콘텐츠를,
Content-Type에는 일치하는 유형(일반적으로 기존 유형과 일관됨)을 포함한다. PUT은 기존 리소스에 대해
멱등적이다. 안전을 위해 현재 ETag와 함께 If-Match를 포함한다(제7.3절 동시성 참조).
불일치하면 412 Precondition Failed 또는 409 Conflict가 발생한다. 검사 없이 갱신은 무조건적이지만
동시 변경을 덮어쓸 위험이 있다. 서버가 리소스에 대해 Etags를 지원하는 경우,
If-Match 헤더가 없는 무조건 PUT 요청을 428 Precondition Required 응답으로 거부해야 한다.
예시(리소스를 갱신하기 위한 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)를 최소한 지원해야 한다.
리소스 메타데이터 갱신(HTTP PUT / PATCH on Linkset) 리소스의 메타데이터는 rel="linkset"이 있는 Link 헤더를 통해 발견되는 해당 linkset 리소스를 수정하여 갱신된다. 전체 대체(PUT): 전체 linkset 문서를 본문에 담아 linkset 리소스 URI에 PUT 요청을 보내면 리소스의 모든 메타데이터가 대체된다. 부분 갱신(PATCH): linkset 리소스 URI에 대한 PATCH 요청은 특정 링크를 추가, 제거 또는 수정한다.
메타데이터에 대한 동시성 제어 리소스의 메타데이터는 여러 행위자가 수정할 수 있으므로, 동시 덮어쓰기를 방지하는 것이 중요하다. 데이터 무결성을 보장하기 위해, LWS 서버와 클라이언트는 linkset 리소스에 대한 모든 PUT 및 PATCH 작업에서 조건부 요청 [RFC7232]을 사용하는 낙관적 동시성 제어를 구현해야 한다. 서버 책임: 서버는 linkset 리소스에 대한 GET 및 HEAD 요청 응답에 Etag 헤더를 포함해야 한다. linkset에 대한 PUT 또는 PATCH가 성공하면, 서버는 수정된 linkset에 대해 새롭고 고유한 Etag 값을 생성하고 응답의 Etag 헤더에 반환해야 한다. 클라이언트 책임: linkset 리소스를 수정할 때, 클라이언트는 해당 리소스에 대해 가장 최근에 받은 Etag를 포함하는 If-Match 헤더를 포함해야 한다. 처리 규칙: If-Match 헤더 값이 linkset의 현재 Etag와 일치하지 않으면, 서버는 412 Precondition Failed 상태 코드로 요청을 거부해야 한다. linkset URI에 대한 PUT 또는 PATCH 요청에서 If-Match 헤더가 누락된 경우, 서버는 428 Precondition Required 상태 코드 [RFC6585]로 요청을 거부해야 한다. 예시(linkset을 대체하기 위한 PUT): 클라이언트가 먼저 linkset을 가져오고 그 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" } ]
}
]
}
이제 클라이언트는 라이선스를 추가하려 한다. 새롭고 완전한 linkset 문서를 구성하고 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한다. 리소스의 링크(메타데이터)만 변경하려는 경우 → 리소스와 연결된 linkset 리소스에 PUT/PATCH한다. 콘텐츠와 링크를 모두 변경하려는 경우 → 적절한 Link 헤더와 'Prefer: set-linkset'을 포함하여 리소스 자체에 PUT/PATCH한다. 둘을 모두 설정하는 것은 기본적으로 꺼져 있다.
리소스와 그 연결된 메타데이터를 영구적으로 제거한다.
리소스 삭제 작업은 위의 추상 작업에서 정의한 대로 HTTP DELETE 메서드를 사용하여 구현된다. 이 절은 입력, 동작 및 응답에 대한 HTTP 바인딩을 지정한다.
DELETE 요청은 제거할 리소스 또는 컨테이너의 URI를 대상으로 한다.
클라이언트는 동시성 검사를 위해 ETag가 있는 If-Match 헤더를 포함할
MAY 있다.
삭제 및 포함 관계:
리소스가 삭제되면, 서버는 이를 부모 컨테이너의 items 목록에서 원자적으로 제거해야 한다.
부모 컨테이너의 totalItems 개수는 그에 따라 갱신되는 것이
SHOULD되며, 그 ETag는 변경을 반영하도록 갱신되어야 한다.
컨테이너가 아닌 리소스의 경우, 서버는 리소스 콘텐츠, 그 연결된 메타데이터(linkset 리소스), 그리고 부모 컨테이너의 포함 관계 참조를 제거한다.
컨테이너 리소스의 경우, 서버는 기본적으로 비재귀 삭제를 사용한다.
컨테이너가 비어 있지 않고 재귀가 요청되지 않은 경우,
서버는 409 Conflict로 요청을 거부해야 한다. 서버는 삭제되는 컨테이너 내의
모든 포함 리소스에 대한 재귀 삭제를 지원할 MAY 있다.
클라이언트는 [RFC4918]에
정의된 대로 재귀 삭제를 요청하기 위해 Depth: infinity 헤더를 사용해야 한다.
성공 시, 서버는 204 No Content로 응답해야 한다. 서버는 [RFC9110]에 정의된 조건부 요청을 지원하는 것이 SHOULD된다.
클라이언트에게 권한이 없는 경우, 서버는 403 Forbidden(클라이언트의 식별자는 알려져 있지만 권한이 부족한 경우) 또는 401 Unauthorized(유효한 인증이 제공되지 않은 경우)를 반환해야 한다. 리소스 존재를 드러내는 것이 보안 위험을 야기하는 경우, 서버는 대신 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)와 함께. 컨테이너 목록의 경우, 규범적 컨텍스트와 구성원 메타데이터(IDs, types, sizes, timestamps)를 가진 JSON-LD를 포함한다. |
| Created (새 리소스) | 201 Created | 일반적으로 응답 본문 없음(또는 새 리소스의 최소 표현). Location
헤더는 새 리소스의 URI로 설정된다. 동시성을 위한 ETag 같은 헤더와 서버 관리
메타데이터에 대한 Link 헤더가 포함되어야 한다.
|
| Deleted (반환할 콘텐츠 없음) | 204 No Content | 응답 본문 없음. 리소스가 삭제되었거나 요청이 성공했고 더 말할 내용이 없음을 나타낸다. 서버는 영구 삭제에 410 Gone을 사용할 MAY 있다. |
| Bad Request (잘못된 입력 또는 제약 조건) | 400 Bad Request | 무엇이 잘못되었는지 설명하는 오류 세부사항. 서버는 구조화된 오류 응답을 위해 [RFC9457]에 정의된 표준 형식을 사용하는 것이 SHOULD되며, 예를 들어 "type", "title", "status", "detail", "instance"와 같은 필드를 가진 JSON 객체를 사용할 수 있다. |
접근 요청 및 허가는 에이전트가 리소스에 대한 접근을 요청하고, 스토리지 컨트롤러가 정의된 제약 조건과 함께 접근을 허가하기 위한 메커니즘을 제공한다. 접근을 요청하고 허가하기 위한 엔드포인트는 특수한 수신함의 한 유형으로 동작한다.
에이전트는 접근 허가를 권한 부여 토큰으로 서버에 제시하지 않는다. 오히려 접근 허가는 무엇이, 누구에게, 어떤 제약 조건 아래에서 권한 부여되었는지에 대한 기록 역할을 한다. 접근 허가가 생성되거나 철회(삭제)될 때, 그 변경을 반영하도록 기반 접근 정책을 조정하는 것은 서버의 책임이다. 접근 허가 엔드포인트와 특정 정책 집행 계층 사이의 상호작용은 이 명세의 범위를 벗어난다.
이 절에서 정의하는 접근 프로파일은 동작, 제약 조건 및 피할당자를 포함하여 Open Digital Rights Language (ODRL)의 개념을 기반으로 한다. 다른 프로파일은 다른 개념적 프레임워크를 사용할 수 있다.
이 절은 다음 용어를 정의한다:
conformsTo 속성에서 이를 참조하여 하나 이상의 접근 프로파일 지원을
나타낸다.
스토리지는 자신의 스토리지 설명 리소스에서
접근 요청 및
접근
허가에 대한 지원을 알릴 MAY 있다.
이러한 지원이 광고되는 경우,
접근 요청을 위한 엔드포인트를 설명하는 서비스 객체는
문자열 AccessRequestService와 같은 type을 가져야 하며,
접근
허가를 위한 엔드포인트를 설명하는
서비스 객체는 문자열 AccessGrantService와 같은 type을 가져야 한다.
서비스 객체는 해당 엔드포인트에서 지원되는 접근 프로파일을 식별하는
하나 이상의 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 속성의 값은 하나 이상의
terms 및
absolute URL strings이어야 한다.
접근 요청의 경우, 값은
AccessRequest term을 포함해야 한다.
접근 허가의 경우, 값은
AccessGrant term을 포함해야 한다. 추가 유형 값이 포함될 MAY 있다.
이 속성은 REQUIRED이다.
이 문서는 접근 요청 및 접근 허가에 대해 다음 유형 값을 정의한다:
{
"type": ["AccessGrant"]
}
storage 속성은
접근 요청 또는 접근 허가의 범위가
지정되는 LWS 스토리지를 식별한다.
storage 속성의 값은 URI여야 한다.
이 속성은 REQUIRED이다.
{
"storage": "https://storage.example/"
}
inbox 속성은
접근 요청 또는 접근 허가와 관련된
알림을 받기 위한 URI를 지정한다
(10.6
알림 참조).
inbox 속성의 값은 URI여야 한다.
이 속성은 OPTIONAL이다.
{
"inbox": "https://id.example/agent/inbox/"
}
access 속성은 서버가 지원하는 프로파일을 기반으로, 하나 이상의
접근 프로파일의 특성을 설명한다.
ODRL Information Model을 기반으로 하는
프로파일은 10.3 접근 프로파일에
설명되어 있다.
access 속성의 값은 하나 이상의
객체 컬렉션이어야 한다.
이 속성은 REQUIRED이다.
이 명세는 ODRL Information Model 및 ODRL
Vocabulary를 기반으로 하는 접근 프로파일을 정의하며,
다음 URL로 식별된다:
https://www.w3.org/ns/lws#AccessProfile.
type 속성은 접근 정책의 유형을 표현한다.
type 속성의 값은 하나 이상의
terms 및
absolute URL strings이어야 하며,
AccessPolicy term을 포함해야 한다. 추가 유형 값이 포함될
MAY 있다.
이 속성은 REQUIRED이다.
{
"access": [{
"type": ["AccessPolicy"]
}]
}
action 속성은 에이전트가
(요청의 경우) 수행하기를 원하는, 또는 (허가의 경우) 수행할 권한이 부여된
작업을 설명한다.
action 속성의 값은 하나 이상의 문자열 컬렉션이어야 한다.
각 값은 서버가 인식하는 작업에 해당해야 한다. 다음 값은 지원되어야 한다:
read, modify, create, 및 delete.
read, modify, 및 delete 값은
ODRL Vocabulary가 정의한다.
create 값은 이 명세가 정의한다.
이러한 동작 값은 다음과 같이 LWS 작업에 대응한다:
read — 리소스 또는 그 메타데이터를 검색한다(HTTP GET, HEAD)modify — 기존 리소스를 수정한다(HTTP PUT, PATCH)create — 컨테이너 안에 새 리소스를 생성한다(HTTP POST)
delete — 기존 리소스를 제거한다(HTTP DELETE)이 속성은 REQUIRED이다.
{
"access": [{
"action": ["read", "create"]
}]
}
assignee 속성은 (요청의 경우) 접근을 요청하는 당사자 또는
(허가의 경우) 접근을 부여받는 당사자를 식별한다.
assignee 속성의 값은 URI여야 한다. 공개 접근은
FOAF
vocabulary의 Agent 클래스를 사용하여 할당될 MAY 있으며,
이는 URI http://xmlns.com/foaf/0.1/Agent로 식별된다.
이 속성은 REQUIRED이다.
{
"access": [{
"assignee": "https://id.example/agent"
}]
}
target 속성은
접근 요청 또는 접근 허가가
적용되는 리소스를 식별한다.
target 속성은 다음 속성을 포함하는 객체여야 한다:
type — 대상 매처의 유형을 식별하는
term 또는
absolute URL string.
value — 대상 리소스를 식별하는 데 사용되는 하나 이상의 문자열 컬렉션.
이 명세는 target 객체와 함께 사용하기 위한 다음 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 속성의 값은 존재하는 경우
제약 조건 객체 컬렉션이어야 한다. 각 제약 조건 객체는 다음 속성을 포함해야 한다:
leftOperand — 제약되는 피연산자를 식별하는 문자열.
operator — 비교 연산자를 식별하는 문자열.
rightOperand — 비교 대상 값. 유형은
leftOperand에 따라 달라진다.
여러 제약 조건 객체가 존재하는 경우, 그 모두가 충족되어야 한다.
이 프로파일에 대한 지원을 알리는 서버는 다음
leftOperand 값을 지원해야 한다:
client — HTTP 요청에 대한 클라이언트 식별자를 나타냄
mediaType — 대상 HTTP 리소스의 미디어 유형을 나타냄
type — 리소스의 link 헤더에 표현된 유형 URL을 나타냄
purpose — 요청되거나 허가되는 접근의 의도된 사용을 나타냄
dateTime — 현재 날짜와 시간을 나타냄
이 속성은 OPTIONAL이다.
다음 예시는 이러한 제약 조건의 사용을 보여준다:
다음 예시는 요청되거나 허가되는 접근의 의도된 사용을 설명하기 위해
purpose의 leftOperand 값을 사용한다.
eq 연산자가 사용되는 경우, rightOperand 값은
목적을 식별하는 URI이다. isAnyOf 연산자가 사용되는 경우,
rightOperand 값은 목적 URI의 배열이며, 명시된 목적이
나열된 값 중 하나와 일치하면 제약 조건이 충족된다:
{
"access": [{
"constraint": [
{
"leftOperand": "purpose",
"operator": "isAnyOf",
"rightOperand": [
"https://purpose.example/collaboration",
"https://purpose.example/research"
]
}
]
}]
}
다음 예시는 특정 클라이언트 애플리케이션으로 접근을 제한하기 위해
client의 leftOperand 값을 사용한다.
eq 연산자가 사용되는 경우,
rightOperand 값은 클라이언트를 식별하는 URI이다:
{
"access": [{
"constraint": [
{
"leftOperand": "client",
"operator": "eq",
"rightOperand": "https://app.example/client-id"
}
]
}]
}
다음 예시는 특정 미디어 유형을 가진 리소스로 접근을 제한하기 위해
mediaType의 leftOperand 값을 사용한다.
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"
다음 예시는 HTTP Link 헤더에 광고된 리소스 유형을 기반으로
접근을 제한하기 위해 type의 leftOperand 값을 사용한다.
eq 연산자가 사용되는 경우, rightOperand 값은
리소스 유형을 식별하는 URI이다. isAnyOf 연산자가 사용되는 경우,
rightOperand 값은 유형 URI의 배열이며, 리소스의 유형이
나열된 값 중 하나와 일치하면 접근이 허용된다:
{
"access": [{
"constraint": [
{
"leftOperand": "type",
"operator": "isAnyOf",
"rightOperand": [
"https://type.example/Playlist",
"https://type.example/Song"
]
}
]
}]
}
다음 예시는 특정 시간 창으로 접근을 제한하기 위해
dateTime의 leftOperand 값을 사용한다.
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"
}
]
}]
}
여러 제약 조건 객체가 존재하는 경우, 접근이 허용되려면 그 모두가 충족되어야 한다. 다음 예시는 특정 날짜 이전에 특정 클라이언트 애플리케이션으로 접근을 제한한다:
{
"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 속성을 포함해야 한다. 확장 terms를 정의하기 위해 추가 context 항목이
포함될 MAY 있다.
이 직렬화와 연결된 미디어 유형은 application/lws+json이다.
{
"@context": [
"https://www.w3.org/ns/lws/v1"
]
}
접근 요청 및 접근 허가 엔드포인트는 LWS 컨테이너이며, 이 명세에 정의된 규칙을 준수해야 한다.
이러한 엔드포인트는 최소한 GET 및 POST 작업 지원을 필요로 한다. DELETE 작업은 RECOMMENDED된다. 다른 작업이 지원될 MAY 있다.
이러한 엔드포인트는 요청 및 응답 페이로드 모두에 대해 10.4.1 JSON-LD 직렬화에 정의된 JSON-LD 직렬화를 지원해야 한다. 서버는 추가 직렬화를 지원할 MAY 있다.
에이전트는
접근 요청 엔드포인트에 POST 요청을 제출하여
접근 요청을 생성한다. 스토리지
컨트롤러는 접근 허가 엔드포인트에
POST 요청을 제출하여 접근 허가를 생성한다.
성공적인 POST 작업은 새 리소스의 URL로 설정된
Location 헤더로 응답해야 한다.
POST / — 접근 요청을 생성한다.GET / — 접근 요청 목록을 검색한다.GET /:id — 특정 접근 요청을 검색한다.DELETE /:id — 접근 요청을 취소한다.POST / — 접근 허가를 생성한다.GET / — 접근 허가 목록을 검색한다.GET /:id — 특정 접근 허가를 검색한다.DELETE /:id — 접근 허가를 철회한다.
알림은 에이전트 및
스토리지
컨트롤러에게 접근 요청 및 접근 허가의 변경을
알리기 위한 메커니즘을 제공한다. 접근 요청 또는 접근 허가에
inbox 속성이 존재하는 경우, 서버는 해당 엔드포인트로 알림을 전달하여
피할당자에게 이벤트를 알리는 것이 SHOULD된다.
알림의 직렬화는 LWS 알림 데이터 모델의 요구사항을 준수해야 한다.
inbox 엔드포인트로 전달되는 알림은 알림 전달에 대해 LWS 프로토콜에 정의된
요구사항을 준수해야 한다.
이 절에서 설명하는 알림 메커니즘은
Linked Data Notifications 패턴과 유사하며,
여기서 알림은 inbox 속성을 통해 발견되고, 해당 수신함으로
POST 요청을 보내 전달된다.
서버는 다음 이벤트에 대한 응답으로 알림을 보내는 것이 SHOULD된다:
inbox에서 알림을 받는 것이 SHOULD된다.
서버는 다른 이벤트에 대한 응답으로 알림을 보낼 MAY 있다.
LWS 컨테이너 표현 및 스토리지 설명 리소스는 미디어 유형
application/lws+json을 사용해야 한다.
LWS 컨테이너 표현은 JSON-LD 규약을 사용하지만, LWS의 제약 조건과 요구사항은 특정 미디어 유형의
사용을 정당화한다. LWS 컨테이너는 JSON-LD의 제한된 프로파일로 간주될 수 있으므로,
구현은 application/ld+json; profile="https://www.w3.org/ns/lws/v1" 미디어 유형을
application/lws+json과 동등한 것으로 간주하는 것이 SHOULD된다.
서버는 컨테이너 표현에 대한 콘텐츠 협상을 지원해야 한다. 응답 페이로드는 요청된 미디어 유형과
관계없이 동일해야 하며 — Content-Type 응답 헤더만 달라진다:
application/lws+json을 요청하는 경우, 서버는
Content-Type: application/lws+json으로 응답해야 한다.
application/ld+json을 요청하는 경우, 서버는
Content-Type: application/ld+json으로 응답해야 한다.
application/json을 요청하는 경우, 서버는
Content-Type: application/json으로 응답해야 한다.
세 경우 모두 응답 본문은 LWS 컨테이너 어휘를 준수하는 동일한 JSON-LD 문서이다.
서버는 콘텐츠 협상을 통해 추가 미디어 유형(예: text/turtle)을 자유롭게 지원할 수 있다.
컨테이너와 같은 특정 복합 리소스는 많은 수의 리소스를 보유할 수 있다. 클라이언트가 목록을 점진적으로 검색할 수 있도록, 서버는 구성원 수가 서버가 정한 임계값을 초과하는 컨테이너에 대해 페이지네이션을 지원하는 것이 SHOULD된다.
페이지네이션은 링크 기반이다. 서버는 HTTP Link 헤더
[RFC8288]를 통해 페이지네이션 URI를 제공하며,
클라이언트가 숫자 오프셋에 의존하지 않고 전체 목록을 탐색할 수 있게 한다.
목록이 페이지네이션되는 경우, 응답 본문은 현재 페이지의 항목만 포함한다.
복합 리소스의 id, type, 및 totalItems 속성은
전체 구성원 관계를 반영하며, items는 현재 페이지의 리소스만 포함한다.
페이지네이션 URI는 다음 표준 링크 관계를 사용하여 Link 헤더에 전달된다:
rel="first": 결과의 첫 번째 페이지 URI. 페이지네이션된
응답에는 반드시 존재해야 한다.rel="last": 결과의 마지막 페이지 URI. 페이지네이션된
응답에 존재할 MAY 있다.rel="next": 결과의 다음 페이지 URI. 후속 페이지가 있을 때
반드시 존재해야 한다. 마지막 페이지에서는 반드시 생략되어야 한다.rel="prev": 결과의 이전 페이지 URI. 앞선 페이지가 있을 때
존재할 MAY 있다. 첫 번째 페이지에서는 반드시 생략되어야 한다.모든 페이지네이션 URI는 클라이언트에 대해 불투명하다. 클라이언트는 페이지네이션 URI를 구성하거나 수정해서는 안 되며, 서버가 제공한 URI를 사용하는 것이 SHOULD된다.
클라이언트는 첫 번째 페이지를 얻기 위해 복합 리소스의 URI를 요청한다. 응답에는 클라이언트가 후속 페이지를 검색하기 위해 따라갈 페이지네이션 Link 헤더가 포함된다. 서버는 이전 스캔 중 얻은 페이지네이션 URI를 통해 특정 페이지에 직접 접근하는 것도 지원할 MAY 있다.
페이지네이션된 응답이 반환되는 경우, 서버는 200 OK로 응답해야 한다. 응답 본문의
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 값을 포함해야 한다:
"@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이며, 이는 term 정의가 다른 컨텍스트에 의해 재정의될 수 없도록 보장한다.
LWS 어휘는 컨테이너 표현에서 사용되는 다음 유형과 속성을 정의한다:
유형:
| Term | URI | 설명 |
|---|---|---|
Container |
lws:Container |
다른 리소스를 포함하는 리소스 |
DataResource |
lws:DataResource |
데이터를 담고 있는 리소스 |
속성:
| Term | URI | 설명 |
|---|---|---|
items |
lws:items |
컨테이너에 포함된 리소스의 목록 |
totalItems |
as:totalItems |
포함된 리소스의 총 개수 |
mediaType |
as:mediaType |
리소스의 미디어 유형 |
size |
schema:size |
바이트 단위 리소스 크기 |
modified |
as:updated |
리소스가 마지막으로 수정된 날짜-시간 |
URI 스킴, 리소스 명명 규약 및 해석 메커니즘을 포함하여 LWS Protocol 내에서 리소스가 어떻게 식별되고 주소 지정되는지 정의한다. 이 절은 다른 절(예: Resource Access) 안으로 이동될 수 있다
이 부분은 의도적으로 비워 둔다
LWS 구현이 상호 운용성을 유지하면서 다양한 플랫폼, 환경 및 스토리지 백엔드에서 작동할 수 있도록 보장하기 위한 고려사항을 설명하고, 스토리지 제공자 변경을 가능하게 하는 affordance를 제공한다
이 부분은 의도적으로 비워 둔다
이 절은 비규범적이다.
보안 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]에서 확인할 수 있다.
이 절은 비규범적이다.
Bearer 토큰과 디지털 자격 증명은 도난 및 재생 공격에 취약하다. 완화책에는 합리적으로 짧은 수명 사용, 토큰을 특정 대상자에 바인딩하는 것, 토큰을 안전하게 저장하는 것이 포함된다.
aud 클레임과 같은 수단으로 특정 목적지 서버에 바인딩된
접근 토큰은 그 바인딩에 의존하여 토큰 재생을 방지할 수 있다. 제한 없는 대상자를 가진
자격 증명을 처리하는 애플리케이션은 이러한 자격 증명을 다른 엔터티, 특히 신뢰할 수 없는
권한 부여 서버에 보낼 때 주의해야 한다. 자격 증명 발급자가 토큰의 대상자를 제한할 수 없는 경우,
클라이언트는 다른 보안 도메인의 권한 부여 서버와 상호작용하기 전에 OAuth 2.0 Token
Exchange [RFC8693]와 같은 메커니즘을 사용하여
대상자가 제한된 자격 증명을 생성할 수 있다.
localStorage, URL 또는 로그에
저장될 때마다, 해당 토큰은 유출 공격에 더 취약해진다.
이 절은 비규범적이다.
assignee 값이 요청 에이전트의 인증된 식별자와 연결되어 있는지 검증할 것을 권장한다.
이 절은 비규범적이다.
데이터 최소화, 사용자 동의 및 개인정보 보호 구현 패턴을 포함한 LWS Protocol의 개인정보 보호 영향.
자격 증명은 사용자와 에이전트에 대한 정보를 포함한다. 디지털 서명은 변조를 방지할 수 있지만, 클라이언트 또는 제3자가 암호화되지 않은 자격 증명 내부의 값을 읽을 가능성이 있다.
그 결과, 자격 증명 발급자는 인증 또는 권한 부여에 필요한 정보만 포함하는 토큰을 만들고, 필요한 경우가 아니라면 민감한 속성을 포함하지 않을 것을 권장한다.
일반적으로 암호화되지 않은 자격 증명 데이터를 로그에 기록하는 것은 안티패턴이다. 이것이 필요한 경우, 구현은 자격 증명의 주체의 개인정보를 보호하기 위해 자격 증명을 잘라내거나 해시할 수 있다.
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: