Branch feat/phase-2-class-grants @ 6532b5c (pushed, 5 commits off main 9e6d189) implements access-management Phase 2 per §4 of the proposal. The SW is the sole security boundary, so sign-off-gated.
What it adds
- Grant key widened to
(origin, dataClass, modes, purpose, expiry, webId) — fail-closed validation, tampered records dropped.
- The SW enforces the PINNED resolved target set on
.fetch, not just origin: grant-time Type-Index resolution pins concrete targets (the §6.2 TOCTOU mitigation); out-of-set → 403 with zero egress; mode matrix (GET→read, PUT/PATCH/DELETE→write, POST→append, write⊇append); path-traversal + sibling-prefix + cross-origin all denied.
- Expiry enforced per request (+ pruned), revocation effective next request, WebID-bound session boundary, unknown class fail-closed.
- Unspoofable consent window — a web page cannot approve its own request.
- Backwards compatible: legacy origin-only grants keep working (dual-read, documented).
- Client JS API live on
window.solid: requestAccess({classes, modes, purpose, duration}), listGrants(), revokeGrant(id), resolveClass(iri) — an extension grant and a standalone-app grant produce identical on-pod artifacts.
Review rigor
4 roborev rounds (codex): a High grant-store write race (a stale save could resurrect a revoked grant → serialized mutations through a mutex, concurrency-tested), a class-resolution info leak, two SSRF confinements on the resolver (pod-only origin set, issuer excluded), and a mutex bypass — all fixed with regression tests. One round-3 partial-false-positive triaged with a CSS-single-origin test proving the rationale. Final: "No issues found." Gate: lint/typecheck/347 tests/build green.
Honest limits (documented in-repo, beaded)
Resolution ladder ships the Type-Index rung only (SAI + SHACL-validate rungs are seams); a revoked class's replica bytes stay resident until logout (gate denies first — propagation bound documented); requestAccess needs a gesture/rate-limit (annoyance, not breach); MV3 SW death mid-consent fails closed.
Ask: merge feat/phase-2-class-grants → main.
🤖 PSS agent — @jeswr's agent for prod-solid-server / the Solid app+Pod-Manager suite
Branch
feat/phase-2-class-grants@6532b5c(pushed, 5 commits off main9e6d189) implements access-management Phase 2 per §4 of the proposal. The SW is the sole security boundary, so sign-off-gated.What it adds
(origin, dataClass, modes, purpose, expiry, webId)— fail-closed validation, tampered records dropped..fetch, not just origin: grant-time Type-Index resolution pins concrete targets (the §6.2 TOCTOU mitigation); out-of-set → 403 with zero egress; mode matrix (GET→read, PUT/PATCH/DELETE→write, POST→append, write⊇append); path-traversal + sibling-prefix + cross-origin all denied.window.solid:requestAccess({classes, modes, purpose, duration}),listGrants(),revokeGrant(id),resolveClass(iri)— an extension grant and a standalone-app grant produce identical on-pod artifacts.Review rigor
4 roborev rounds (codex): a High grant-store write race (a stale save could resurrect a revoked grant → serialized mutations through a mutex, concurrency-tested), a class-resolution info leak, two SSRF confinements on the resolver (pod-only origin set, issuer excluded), and a mutex bypass — all fixed with regression tests. One round-3 partial-false-positive triaged with a CSS-single-origin test proving the rationale. Final: "No issues found." Gate: lint/typecheck/347 tests/build green.
Honest limits (documented in-repo, beaded)
Resolution ladder ships the Type-Index rung only (SAI + SHACL-validate rungs are seams); a revoked class's replica bytes stay resident until logout (gate denies first — propagation bound documented);
requestAccessneeds a gesture/rate-limit (annoyance, not breach); MV3 SW death mid-consent fails closed.Ask: merge
feat/phase-2-class-grants→main.🤖 PSS agent — @jeswr's agent for
prod-solid-server/ the Solid app+Pod-Manager suite