Locally FAIR: UI Download button and Preview fail with 404 for authorized users (session-authenticated requests get no API token injected)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 564
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 29
Description
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 (
JSESSIONIDstable 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 viaX-Dataverse-keyheader or?key=query param.JSESSIONIDis 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. Requiresdataverse.api.signature-secretto 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
- N/A
Related docs / code
- User guide, Locally FAIR Collections and Datasets: https://guides.dataverse.org/en/6.11/user/dataverse-management.html#locally-fair
- Native API, Locally FAIR endpoints: https://guides.dataverse.org/en/6.11/api/native-api.html#locally-fair-list-role-assignees
- External Tools signedUrl placeholder: https://guides.dataverse.org/en/6.11/api/external-tools.html
Additional context
Happy to provide additional info and test any proposed patch on our OpenShift v6.11 deployment.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the UI generation of /api/access/datafile links and the external-tool signedUrl handling, then compare the existing restricted-file token injection with Locally FAIR collection authorization. Verify the Download button and Preview iframe for authorized role assignees, while unauthorized requests remain hidden with 404 responses.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, authentication, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100