solid / solid/object

Authorization.accessTo / .default are single-valued but acl:accessTo / acl:default are multi-valued

Open
#33 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
0
Forks
2
PR merge metrics
No merged PRs in 30d

Description

Summary

Authorization.accessTo and Authorization.default are typed and implemented as single-valued (string | undefined), but the WAC predicates acl:accessTo and acl:default are multi-valued — an ACL Authorization may list several target resources / default containers. The accessor silently drops all but one value.

Evidence (source)

src/wac/Authorization.ts @ 3ba394a (v0.6.0):

// lines 32-34
get accessTo(): string | undefined {
    return OptionalFrom.subjectPredicate(this, ACL.accessTo, NamedNodeAs.string)
}
// lines 45-47
get default(): string | undefined {
    return OptionalFrom.subjectPredicate(this, ACL.default, NamedNodeAs.string)
}

OptionalFrom.subjectPredicate returns at most one value. Compare mode, agent, agentClass, origin, which correctly use SetFrom.subjectPredicateSet<string>.

Spec

The WAC "Authorization Conformance" section requires "At least one acl:accessTo or acl:default property value" — i.e. these are ordinary multi-valued RDF predicates. The Access Objects definitions use singular prose but do not prohibit multiple values, and real ACL documents attach one Authorization to several resources.

Minimal repro (execution-verified against @solid/object@0.6.0)

import { DataFactory, Parser, Store } from "n3";
import { Authorization } from "@solid/object";

const ttl = `
@prefix acl:  <http://www.w3.org/ns/auth/acl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<#a> a acl:Authorization ;
    acl:accessTo <https://pod.example/doc1>, <https://pod.example/doc2> ;
    acl:mode acl:Read ; acl:agentClass foaf:Agent .
`;
const store = new Store();
store.addQuads(new Parser({ baseIRI: "https://pod.example/.acl" }).parse(ttl));
const a = new Authorization(
  DataFactory.namedNode("https://pod.example/.acl#a"), store, DataFactory);

console.log(a.accessTo); // => "https://pod.example/doc1"   (doc2 silently dropped)

Expected: both doc1 and doc2 are observable.
Actual: only one target is returned; the other is lost.

Impact

A downstream access-management UI (grant editor) could not read an Authorization that grants access to several resources, and had to work around it by splitting shared Authorization nodes.

Suggested fix (note: breaking API change)

Change accessTo / default to Set<string> via SetFrom.subjectPredicate (mirroring mode/agent/origin). This is a public-API return-type change and also touches the internal consumers src/accessControlConversion/wacToAcp.ts (iterate the set) and src/accessControlConversion/acpToWac.ts (add to the set), so the exact API shape is a maintainer call — happy to open a PR once you confirm the preferred shape. See #34 for the related conforms OR-vs-AND bug.


🤖 PSS agent — @jeswr's agent for prod-solid-server / the Solid app+Pod-Manager suite

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the accessTo and default getters in src/wac/Authorization.ts, then trace their consumers in src/accessControlConversion/wacToAcp.ts and src/accessControlConversion/acpToWac.ts. Compare the existing mode, agent, and origin SetFrom.subjectPredicate accessors. Done means multiple accessTo and default values remain observable through the public API and are preserved by both conversion paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authorization, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.