Problem
With subdomains: true + baseDomain: solid.social, any file at the base domain's root returns 401 even with a public-read ACL. The root container itself (GET /) works; direct file access (GET /mashlib.js, /index.html, /terms.html) does not.
Root cause
buildResourceUrl in src/auth/middleware.js rewrites the resource URL when the request hits the base domain:
if (subdomainsEnabled && hostname === baseDomain && !podName) {
const pathMatch = urlPath.match(/^\/([^/]+)(\/.*)?$/);
if (pathMatch && !pathMatch[1].startsWith('.')) {
const podName = pathMatch[1];
const remainder = pathMatch[2] || '/';
return `${protocol}://${podName}.${baseDomain}${remainder}`;
}
}
For GET solid.social/mashlib.js:
- Path matches → podName =
mashlib.js
- Returns
https://mashlib.js.solid.social/
- ACL check is now against a domain that doesn't exist
- Root ACL (
accessTo: https://solid.social/) doesn't match → 401
Reproduction
On a JSS with subdomains: true + baseDomain set:
# Works — base domain container
curl -I https://DOMAIN/ # 200
# All fail — base domain files
curl -I https://DOMAIN/mashlib.js # 401
curl -I https://DOMAIN/index.html # 401
curl -I https://DOMAIN/any-file.txt # 401
Impact
Core assets (mashlib.js, mashlib.css) hosted at the base domain become unreachable, breaking the data browser for pods on that server. Operators can work around by moving assets to a subdomain or CDN, but the default setup is broken.
Proposed fix
Only treat a path segment as a pod name if it can't be served directly. Options:
- Check file existence first — if
data/${segment} exists as a file, serve it directly
- Pattern exemption — treat anything with a file extension (
.js, .css, .html, etc.) as a file, not a pod
- Explicit allow-list — operators can list reserved root paths
(1) is the most correct but requires storage lookup in the auth middleware. (2) is a fast pragmatic fix: if (pathMatch[1].includes('.')) → don't rewrite.
Context
Found while debugging why mashlib wasn't loading on solid.social. mashlib.js.acl and mashlib.css.acl were both present with public-read rules but still returning 401 — because the rules apply to https://solid.social/mashlib.js but the ACL checker was comparing against https://mashlib.js.solid.social/.
Problem
With
subdomains: true+baseDomain: solid.social, any file at the base domain's root returns 401 even with a public-read ACL. The root container itself (GET /) works; direct file access (GET /mashlib.js,/index.html,/terms.html) does not.Root cause
buildResourceUrlinsrc/auth/middleware.jsrewrites the resource URL when the request hits the base domain:For
GET solid.social/mashlib.js:mashlib.jshttps://mashlib.js.solid.social/accessTo: https://solid.social/) doesn't match → 401Reproduction
On a JSS with
subdomains: true+baseDomainset:Impact
Core assets (
mashlib.js,mashlib.css) hosted at the base domain become unreachable, breaking the data browser for pods on that server. Operators can work around by moving assets to a subdomain or CDN, but the default setup is broken.Proposed fix
Only treat a path segment as a pod name if it can't be served directly. Options:
data/${segment}exists as a file, serve it directly.js,.css,.html, etc.) as a file, not a pod(1) is the most correct but requires storage lookup in the auth middleware. (2) is a fast pragmatic fix:
if (pathMatch[1].includes('.'))→ don't rewrite.Context
Found while debugging why mashlib wasn't loading on solid.social.
mashlib.js.aclandmashlib.css.aclwere both present with public-read rules but still returning 401 — because the rules apply tohttps://solid.social/mashlib.jsbut the ACL checker was comparing againsthttps://mashlib.js.solid.social/.