Summary
When a collection is marked Locally FAIR (feature flag dataverse.feature.allow-locally-fair-data), the UI Download button and the external-tool Preview iframe both fail with HTTP 404 for users who are correctly authorized via the collection's locallyFairRoleAssignees. The same file downloads successfully via the REST API when X-Dataverse-key / ?key= is supplied. Public (non-FAIR) datasets are unaffected.
Environment
- Dataverse v6.11 (image
gdcc/dataverse:6.11-noble)
- Feature flag:
dataverse.feature.allow-locally-fair-data=1
- Deployment: OpenShift, Payara behind an Apache reverse proxy (HTTPS termination +
X-Forwarded-* headers correctly forwarded)
- Browsers reproduced with: Edge (
JSESSIONID stable across requests)
Reproduction
- Enable
dataverse.feature.allow-locally-fair-data.
- Create a published collection
internal; mark it Locally FAIR.
- Add a user (or explicit group) to
PUT /api/dataverses/internal/locallyFairRoleAssignees/{roleAssignee}.
- Publish a dataset with an unrestricted file inside the collection.
- Log in as that authorized user in the browser.
- Click Download on the file (or Preview for a supported MIME type).
Actual behavior
Download button issues:
GET https://<host>/api/access/datafile/16?gbrecs=true
Cookie: JSESSIONID=<valid session for authorized user>
(no X-Dataverse-key header, no ?key= param)
Response:
{
"status": "ERROR",
"code": 404,
"message": "API endpoint does not exist on this server. ..."
}
Preview iframe: the previewer's subsequent /api/access/datafile/16 fetch returns the same 404. External tools receive no signed URL for FAIR-hidden files.
Expected behavior
An authorized viewer (member of locallyFairRoleAssignees, either directly or through a group) should be able to download and preview files in a Locally FAIR collection from the UI, without having to manually append an API token to URLs.
Root cause analysis (confirmed by us)
-
/api/* is stateless — it authenticates only via X-Dataverse-key header or ?key= query param. JSESSIONID is intentionally ignored. Confirmed from the logged-in browser:
fetch('/api/users/:me', { credentials: 'include' })
// → {"status":"ERROR","message":"User with token null not found."}
-
Server-side authorization is correct. From inside the container, using the authorized user's token:
curl -H "X-Dataverse-key: $TOKEN" http://localhost:8080/api/access/datafile/16
# → HTTP 200, 720597 bytes
-
The UI only appends ?key=<token> to /api/access/datafile/{id} links when the file itself is restricted. Locally FAIR is a collection-level visibility control; files remain "unrestricted", so the UI emits the plain URL, which then hits the FAIR check as an anonymous caller and returns 404 (the FAIR hide-as-404 semantics apply to the API too, per the docs: "API access is also blocked for unauthorized access.").
-
Same story for external-tool previewers: no signed URL is generated for FAIR files, so the tool's fetch is anonymous → 404.
Net effect: Locally FAIR is only usable via the API when the caller supplies a token; the built-in web UI cannot preview or download FAIR content for any user, superuser included, because it does not attach any credential to those requests.
Suggested fix(es)
Any of the following would resolve the UI break.
- (a) Treat Locally FAIR as a trigger for injecting
?key=<token> into the UI's /api/access/datafile/* and dataset-ZIP download links for the currently authenticated user (same mechanism used today for restricted files).
- (b) Generate signed URLs (
{signedUrl} placeholder) for external tools whenever the containing collection is Locally FAIR, not only for restricted files. Requires dataverse.api.signature-secret to be configured, which is already the recommended prod setting.
- (c) Have
/api/access/datafile/* (and related endpoints) fall back to accepting the JSF session (JSESSIONID) for read access when the request originates from the same-origin UI. This is a broader change and might have security implications, so (a)/(b) are preferred.
Workarounds available today
Related docs / code
Additional context
Happy to provide additional info and test any proposed patch on our OpenShift v6.11 deployment.
Summary
When a collection is marked Locally FAIR (feature flag
dataverse.feature.allow-locally-fair-data), the UI Download button and the external-tool Preview iframe both fail with HTTP 404 for users who are correctly authorized via the collection'slocallyFairRoleAssignees. The same file downloads successfully via the REST API whenX-Dataverse-key/?key=is supplied. Public (non-FAIR) datasets are unaffected.Environment
gdcc/dataverse:6.11-noble)dataverse.feature.allow-locally-fair-data=1X-Forwarded-*headers correctly forwarded)JSESSIONIDstable across requests)Reproduction
dataverse.feature.allow-locally-fair-data.internal; mark it Locally FAIR.PUT /api/dataverses/internal/locallyFairRoleAssignees/{roleAssignee}.Actual behavior
Download button issues:
Response:
{ "status": "ERROR", "code": 404, "message": "API endpoint does not exist on this server. ..." }Preview iframe: the previewer's subsequent
/api/access/datafile/16fetch returns the same 404. External tools receive no signed URL for FAIR-hidden files.Expected behavior
An authorized viewer (member of
locallyFairRoleAssignees, either directly or through a group) should be able to download and preview files in a Locally FAIR collection from the UI, without having to manually append an API token to URLs.Root cause analysis (confirmed by us)
/api/*is stateless — it authenticates only viaX-Dataverse-keyheader or?key=query param.JSESSIONIDis intentionally ignored. Confirmed from the logged-in browser:Server-side authorization is correct. From inside the container, using the authorized user's token:
The UI only appends
?key=<token>to/api/access/datafile/{id}links when the file itself is restricted. Locally FAIR is a collection-level visibility control; files remain "unrestricted", so the UI emits the plain URL, which then hits the FAIR check as an anonymous caller and returns 404 (the FAIR hide-as-404 semantics apply to the API too, per the docs: "API access is also blocked for unauthorized access.").Same story for external-tool previewers: no signed URL is generated for FAIR files, so the tool's fetch is anonymous → 404.
Net effect: Locally FAIR is only usable via the API when the caller supplies a token; the built-in web UI cannot preview or download FAIR content for any user, superuser included, because it does not attach any credential to those requests.
Suggested fix(es)
Any of the following would resolve the UI break.
?key=<token>into the UI's/api/access/datafile/*and dataset-ZIP download links for the currently authenticated user (same mechanism used today for restricted files).{signedUrl}placeholder) for external tools whenever the containing collection is Locally FAIR, not only for restricted files. Requiresdataverse.api.signature-secretto be configured, which is already the recommended prod setting./api/access/datafile/*(and related endpoints) fall back to accepting the JSF session (JSESSIONID) for read access when the request originates from the same-origin UI. This is a broader change and might have security implications, so (a)/(b) are preferred.Workarounds available today
Related docs / code
Additional context
Happy to provide additional info and test any proposed patch on our OpenShift v6.11 deployment.