Repository navigation
Conversation
Adds components and configurations to serve the Linked Web Storage (LWS) protocol, based on the LWS editor's draft of 28 September 2026, either on its own or together with the Solid Protocol, using WAC or ACP. - Storage description on the storage root (application/lws+cid) - LWS container representation (application/lws+json) - LWS Link headers: storage, up, type, and linkset - Linksets (RFC 9264) backed by description resources, with JSON Merge Patch - JSON Merge Patch (RFC 7386) for JSON resources - 204 responses after successful modifications - LWS authorization server: metadata, JWKS, and token exchange (RFC 8693) accepting did:key, controlled identifier, and OpenID Connect credentials - Validation of LWS access tokens and the LWS WWW-Authenticate challenge - New lws, lws-acp, solid-lws, and solid-lws-acp configurations - GET/HEAD requests with a failing If-Match or If-Unmodified-Since now get 412 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QzAV2EGR8JGsCnqErKMUWx
… delete and problem details Container listings are paginated with first/last/prev/next links. Every storage gets access request and access grant containers that are validated against the LWS Access Profile, and grants add permissions next to WAC or ACP. Webhook subscriptions deliver signed LWS notifications with delivery-time authorization. DELETE with Depth: infinity removes containers recursively, and errors fall back to application/problem+json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QzAV2EGR8JGsCnqErKMUWx
|
@jeswr why not do this based on https://github.com/CommunitySolidServer/CommunitySolidServer/tree/versions/next-major |
3 of 4 tasks
Owner
Author
|
@elf-pavlik here is a version rebased onto It is the same LWS work, ported to the v8 changes (policy engine permissions, the extracted handler and logging libraries, the new storage middleware layout). The full unit and integration suites pass on it, including the LWS integration tests with WAC and ACP. The PR description lists the differences from this PR. Generated by Claude Code |
This was referenced Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Jesse · project thread
📁 Related issues
None yet. This adds support for the Linked Web Storage (LWS) draft. An issue can be opened to track it if maintainers prefer.
✍️ Description
Before: CSS can only serve the Solid Protocol.
After: CSS can also be configured to serve LWS, either on its own or together with Solid, with WAC or ACP for authorization. There are four new presets:
lws.json,lws-acp.json,solid-lws.jsonandsolid-lws-acp.json. They have the same setup asfile.json, and every pod is an LWS storage. This includes pagination, access requests and grants, webhook notifications, recursive deletes and problem details. Existing configurations behave as before, except for the 412 fix listed under "Core changes".The work follows the LWS editor's draft at w3c/lws-protocol
9b03b32(28 Sep 2026). User documentation is indocumentation/markdown/usage/linked-web-storage.md.How it works. Everything is new components plus new config options (
lws/solid-lws) for the handler, metadata parser/writer, modes, authentication, storage middleware and representation conversion.Resources and discovery
LwsStorageDescriptionHandlerserves the storage description (application/lws+cid) on the storage root, using conneg.LwsStorageDescribers add services and verification methods to it.LwsLinkMetadataWriteradds thelws#storage,up,type,linksetand pagination links.LwsContainerTypeParseracceptsLink: <lws#Container>; rel="type"when creating a container.NoContentOperationHandlermaps 205 to 204.Containers, linksets and PATCH
ContainerToLwsJsonConverterproduces theapplication/lws+jsoncontainer representation. Listings overpageSize(default 1000) are paginated via?page=N(parsed byLwsPagePreferenceParser) withfirst/last/prev/nextlinks.LinksetMapper,QuadToLinksetConverterandLinksetMergePatcherexpose the existing description resource (.meta) as an RFC 9264 linkset, modifiable with JSON Merge Patch.JsonMergePatcherandJsonMergePatchModesExtractoradd RFC 7386 JSON Merge Patch for JSON resources.DepthParser,RecursiveDeleteModesExtractorandRecursiveDeleteOperationHandlersupportDELETEwithDepth: infinity, requiring delete permission on every contained resource.ErrorToProblemJsonConverterandFallbackErrorHandlerreturnapplication/problem+jsonwhenever the error can't be converted to a type the client prefers.Authorization server and tokens
LwsTokenHttpHandler,LwsAuthorizationServerMetadataHttpHandler,LwsJwksHttpHandlerandLwsAccessTokenIssuerform the LWS authorization server (/.well-known/lws-configuration, RFC 8693 token exchange).DidKeySubjectTokenVerifier,CidSubjectTokenVerifierandOidcSubjectTokenVerifier(which also acceptssolid:oidcIssuer).LwsAccessTokenExtractorvalidatesat+jwtBearer tokens;LwsWwwAuthMetadataWritersendsWWW-Authenticate: Bearer as_uri, realm[, error="invalid_token"].Access requests and grants
.lws/requests/and.lws/grants/containers, created lazily byAccessContainerInitializingHandlerand advertised byAccessServiceDescriberwith thelws#AccessProfile.AccessDocumentOperationHandlervalidates posted documents against the Access Profile, makes them immutable (GET/HEAD/DELETE only), forbids targets inside.lws/, and notifies the grant'sinbox.AccessGrantReader(added to thePathBasedReader) grants permissions from grants cached byAccessGrantIndex: exact, non-recursive targets with a type filter;foaf:Agentfor public access;createon a container covers its direct members; client, format, type and dateTime constraints are enforced, and purpose is accepted. Authenticated agents can create access requests. Grants only add to WAC/ACP; deleting one revokes it.Webhook notifications
LwsSubscriptionHttpHandlerserves/.notifications/lws/: create (topics must be readable), list the subscriber's subscriptions as an LWS container, GET and DELETE a subscription.LwsNotificationListenerturns resource changes into Create/Update/Delete activities (no actor), matches recursive container topics, and re-checks read permission at delivery time. Subscriptions are removed after 5 consecutive failures or on410 Gone.WebhookLwsNotificationSenderPOSTsapplication/lws+jsonenvelopes signed byHttpMessageSigner(RFC 9421, ES256,content-digest), retrying 5xx and network errors.LwsNotificationServiceDescriberadvertises the service and the key asverificationMethod+authentication.Core changes outside the new components
assertReadConditions: a GET or HEAD with a failingIf-MatchorIf-Unmodified-Sincenow returns 412 instead of 304, as RFC 9110 §13.1 requires.DataAccessorBasedStore: a.metaGET carries the subject's modification date, so linksets get ETags.Choices made where LWS is ambiguous or conflicts with Solid (reviewers may want to weigh in)
Accept, or a preference forapplication/lws+cid, gets the storage description; for*/*the LWS-only presets return the description and the dual presets the container.application/ld+jsonon containers keeps returning LDP JSON-LD, so two Touchstone conneg MUSTs fail in dual mode. (Being revisited separately.)webidclaim is treated as Solid-OIDC; every other Bearer token as LWS.audholds only the client are accepted.Not implemented yet: notifying the storage controller of new access requests (LWS doesn't define how its inbox is found), requesters reading or deleting their own requests, and SAML.
Testing
test/integration/LinkedWebStorage.test.tsruns did:key, grants, access requests, webhook delivery (with a local inbox), Depth delete and problem details against all four combinations.core: 116 passed, 0 failed (pagination run with a page size of 2; the rest of the inapplicable tests need harness-issued tokens).notifications/webhook: 11 of 11 passed, including signature verification, retry and deactivation.application/ld+jsonconneg MUSTs and one SHOULD from choice 2.auth(from the first round): 23 of 23, 3 SAML tests inapplicable.✅ PR check list
🤖 Generated with Claude Code
https://claude.ai/code/session_01QzAV2EGR8JGsCnqErKMUWx