WICG / file-system-access

Expose the file system on the user’s device, so Web apps can interoperate with the user’s native applications.
https://wicg.github.io/file-system-access/
Other
667 stars 66 forks source link

Feedback on the File System API #238

Closed BjornMoren closed 2 years ago

BjornMoren commented 4 years ago

This is feedback on the API, as described on the page:

https://web.dev/file-system-access/

I think this API has very limited use, because it will annoy the user with file access questions all the time. The common user response will be "But I already installed this app on my device, so why does it keep asking me to give file permissions all the time?" A PWA install will become like a second rate install, and never able to compete with a native install.

To make a PWA truly feel lika a native app, the PWA must be able to: A) Read, write and create files on the user's system without any prompts. B) Those files must be as secure as normal files, so they can't be part of data that can be wiped out by the "Clear browsing data" function. C) The user should only have to grant these privileges once for the PWA (at installation). Same model as when you install a APK.

It would really help my PWA product if a fully functional file system API was developed. Right now I'm stuck storing blobs in IndexedDB, which is not an optimal solution. Contrary to what you might have heard, IndexedDB really is cleared when disk space is beginning to run out, so it is not secure storage.

BjornMoren commented 4 years ago

An alternative that would also work for me would be if the user could be prompted to grant the PWA perpetual storage in IndexedDB. In other words, the browser would never ever under any circumstance remove the data for the PWA from IndexedDB. The only way to clear it would be to uninstall the PWA. I'm kind of surprised that it doesn't work that way by default. I mean, from the user perspective, if you have installed a PWA, then why wouldn't you also want its data to be secure? The way it works right now is that the browser kind of tries to keep the data, and if you ask the browser to persist (navigator.storage.persist) then it tries a little harder to keep the data, but there are no guarantees. It is very difficult to develop apps when secure data storage isn't available.

kaizhu256 commented 4 years ago

my current workaround to "secure data storage" in indexeddb is to add 2 extra buttons to pwa:

its not ideal, and datasets are limited to browser-dependent limits on blob-size for an indexeddb record.

BjornMoren commented 4 years ago

Kaizhu256, I do exactly the same. But I still worry that users will be very annoyed if their data is lost.

tomayac commented 4 years ago

(Not related to the initial post, just relevant for the later comments: Are you aware of persistent storage?)

BjornMoren commented 4 years ago

Tomayac: Thanks for the suggestion. Yes, I'm using it right now with IndexedDB using "navigator.storage.persist". But persistent storage is only a suggestion to the browser to keep the data, not a guarantee.

Jaifroid commented 3 years ago

I have a PWA that works with a specific directory which the user can pick once the first time they wish to access files in that directory. Thereafter, the app can access any file there without further permission prompts for the duration of the session. When the user initiates a new session at a later time, they are simply asked to verify once that they still wish to allow the app access to the folder with a simple prompt. This is a great improvement in UX compared to picking a file every time the app is opened.

However, I do agree with comments in this thread that this UX still feels second-class compared to a native app. All that is needed is to persist the permission across sessions for apps that have been installed. This would still be more secure than a native app, because it is very easy to revoike permission from the file icon at the top of the PWA (see screenshot). The security model here seems clear: the ability to persist permissions should be an extra privilege that is granted only when the app is installed. This is exactly how native app Storage permissions work. This is the one piece of the puzzle missing to make PWAs into first-class citizens.

image

mkruisselbrink commented 3 years ago

All that is needed is to persist the permission across sessions for apps that have been installed

This is more or less exactly what we are planning to work on sometime this year.

bradisbell commented 3 years ago

@mkruisselbrink Please consider enabling persistent permission without the install. Not everyone wants extra shortcuts to things on their computer. Having behavior differences between going to a site and installing a PWA will create confusion.

BjornMoren commented 3 years ago

@bradisbell As it is now, things are very confusing for the users, because regular web sites can look and behave a bit like an installed app. But PWAs, who are supposed to be just like a normal app, can't really do the things a normal app can. I think there must be a clear line: web sites should have no access at all to APIs that are typically used by apps (file system, etc), and installed PWAs should have full access. BTW, I think it should not be called PWA unless it is installed.

bradisbell commented 3 years ago

@BjornMoren There is no reason to require additional hurdles for users. If the user gives permission to something, then the user agent should respect what the user wants to do and allow that permission. PWA installation is in effect the adding of a convenient shortcut... or at least, it should be. Gating arbitrary levels of functionality behind this step doesn't make any sense to me. Users should be able to do what they want, in the most convenient ways. Much of the success of the web as an application platform has been due to the fact that users don't have to install anything.

pwnall commented 3 years ago

I think that granting permissions is a product-level decision that each browser gets to make. I would expect that, at most, this specification will make a non-normative recommendation around persisting permissions.

The feedback here appears to be around Chrome's implementation of the API. I think it'll be better to discuss this feedback at crbug.com, where we can focus on a concrete implementation of the permissions model, and discuss about the user experience on your sites given this implementation.

zedL commented 3 years ago

How about asking the user once when creating/selecting a folder? From then on, the browser can have full access below the folder.

Jaifroid commented 3 years ago

I think that granting permissions is a product-level decision that each browser gets to make. I would expect that, at most, this specification will make a non-normative recommendation around persisting permissions.

@pwnall Is this really a browser-level decision? Are we going to go back to the hell of the 2010s where each browser implemented their own version of a feature? If this is to be a WICG-proposed API, then it should be the case that if a browser vendor decides to implement the API, they should implement all of it. If a vendor chooses to omit part of the API, then they have only partially implemented it.

Currently the API proposal is only implemented Chromium browsers, so I think it is understood by all contributors here that we are discussing what we would like to see for those browsers that implement this API. But I would argue quite strongly that fundamental decisions around persistence of permissions should be part of the API, not part of this or that implementation of it.

BjornMoren commented 3 years ago

Currently the API proposal is only implemented Chromium browsers, so I think it is understood by all contributors here that we are discussing what we would like to see for those browsers that implement this API. But I would argue quite strongly that fundamental decisions around persistence of permissions should be part of the API, not part of this or that implementation of it.

I totally agree.

jimmywarting commented 3 years ago

I currently see one small issue without a more persistent permission model, and that is if you use background sync and/or background fetch to download things in the background. You have no way to ask for permission in a service worker when the app is closed...

twilson7755 commented 3 years ago

Just wanted to add that I completely agree with the original post ... we are developing a web based application and have a need to utilize this File System API, however, until such time that the permission is persisted, it is simply not a viable option ... the user having to re-confirm their permission every time the application is restarted is simply not acceptable.

@mkruisselbrink do you have any more specific information about when this year the permission persistency will be added?

carlosrafaelgn commented 3 years ago

@Jaifroid mentioned this issue in another issue I created, #288 , and I decided to share my thoughts here, not there ☺️

This situation reminds me of the J2ME-era of those Nokia feature phones and their JAR apps.

I had also created a media player back then, https://github.com/carlosrafaelgn/FPlayJ2ME (the app is older than the repo), and I, along with every other developer at that time, suffered with having to ask the user permission to access every single file, every time...

In the best case scenario, depending on the phone model, the user could temporarily allow access to all files once per session (it was better than asking every time, but it was still annoying).

Nokia had a workaround for it by showing an "always allow" option, which would give the app permission to access all files forever. Unfortunately, that option was only displayed for signed apps, and it was a pain (if possible at all) to have Nokia sign your app.

Even though I said "unfortunately" before, I understand the security implications of allowing access to all files at all times, and it was, indeed, very dangerous.

Android 11 is the living proof of that...

At first, Play Store would just alert the user "This app you are about to install wants to read your files. Install only if you agree with that".

That was clearly not enough, as Google changed Android's architecture in a second moment. Now the apps had to ask permission to read/write the files using a system dialog and users had to actively allow or disallow the access (forever).

Still not enough, because of developer abuses and naive users.

Which leads us to Android 11: https://developer.android.com/about/versions/11/privacy/storage

Now you cannot access the files, with a few exceptions:

Android 11 also has a way to allow apps to access all files, but I'm sure that will not be common: https://developer.android.com/training/data-storage/manage-all-files

I strongly believe the File System API should be inspired by Android's Safe Access Storage: once users open a file with your app/PWA, that file file can be accessed by the app/PWA forever, or at least for as long as IndexedDB (or other kind of storage) is not cleared.

Lioric commented 3 years ago

I strongly believe the File System API should be inspired by Android's Safe Access Storage

While I agree this should be the way (an app/page owned area with no access to upper directories/areas AND WITH permanent permissions), there is this:

or at least for as long as IndexedDB (or other kind of storage) is not cleared

then, we are back to square one again.

The issue here is that (from my needs and what I read from most of the other comments) we are mostly interested in a own area where application specific data can be stored WITH GUARANTEED persistence in the device.

After all, access to file system files (albeit in a clunky way) has been since the dawn of the internet browsers, what we are mostly interested (at least I know I am) is the capability of the browser not evicting the stored data based on the flavor of the day browser's version or OS

"permanent permissions" for the File System API or a guaranteed Persistent IndexedDB storage, either of those might be the solution

bradisbell commented 3 years ago

At least for my use cases, each and every one, I want persistent access to the general file system in a way that is compatible with other applications. For me, the entire point is to be able to read/write files that can actually be used elsewhere. Basic capability that has existed as long as filesystems have.

Isolated filesystem access with no method of requesting non-isolated access is needlessly restrictive for users. If users want to use their filesystem, they should be able to do so. The user agent should not be dictating to the user what they can and cannot do with their filesystem.

Please, let's move the discussion away from restricting users (in terms of scope and persistence of filesystem access) on to a discussion of how to enable the broadest access in a standardized way, with reasonable security defaults.

tejasvi commented 3 years ago

The read permission should be persisted if the current file contents are known to the origin. E.g. when origin is the last file modifier. The knowledge can be determined through access tokens generated using cryptographic hash of the file content. Recently released Blake3 provides GB/s order throughput. When origin is granted read access to a set of files, it duplicates them in IndexedDB to avoid having to ask permission again. Instead, it can store just the hash.

From security perspective, persistence of create permission in a folder is no different from the permission persistence of File System API and IndexedDB stored in an obscure (but not inaccessible) location.

Persistent write permission can be easily exploited. Instead I would prefer exposing the origin's sandboxed file system to the general OS (instead of unstable hacks) which covers 99% of the use case.

Jaifroid commented 3 years ago

@tejasvi On a project I contribute to, we need regular access to files of 90+ GB via the File System Access API. Having to calculate a hash each time such a file is accessed would add an enormous overhead... The simplest solution as far as I am concerned is to allow persistence for installed PWAs. This is very similar to the mobile app model: permissions are granted on install. Until that point, permissions are per-session (i.e. the current model), which is absolutely fine for most users most of the time.

tejasvi commented 3 years ago

@Jaifroid Unlike random websites, mobile applications have to comply with store policies. Installing from third party sources requires "unsafe" toggle deep in settings. If it is easy to request persistent permission, then it will be used gratuitously (and maliciously). Case in point: calculator apps requesting for call logs. Browsers can offer a similar toggle along with a regular warning as done with sideloaded extensions on chrome.

Jaifroid commented 3 years ago

We're talking about persistent permissions to an already picked file, not wide system-wide access. If the file has changed outside the app, it needs to be picked again. It's the same with Directory access (with this API) -- it gets blocked if the contents of the directory have changed. All we're asking for is that the permission to access the picked files or folders is persisted between sessions.

tejasvi commented 3 years ago

If the file has changed outside the app

Is there a better method other than checking the hash?

Jaifroid commented 3 years ago

This API doesn't rely on the filename for its (inter-session) permissions -- I can rename one file as another file outside the app, but from within the app the access remains to the original files despite their namechange. For all I know, something like what you say is already built in to the security model. So long as the user must explicitly pick the file or the folder, and since all executable files are blocked by the API at source, the risk of persisting permissions between sessions seems miniscule to me. But of course, I'm not against the kind of security layer you propose so long as it doesn't block speedy access to very large files.

carlosrafaelgn commented 3 years ago

Hi, @Lioric !

When I mentioned Android's Safe Access Storage, I didn't mean only the app's sandbox, but mainly the ability to access external files, like a downloaded document/audio/image, or pretty much anything originally created by another app (document/audio/image and so on).

Permanent access to private files is really useful, but does not cover all possible use cases, such as when the user:

While the API's current model suffices for the two scenarios above, it ruins the usability in apps like audio/video players where users can create/store playlists for a later time, because they would have to keep allowing access to the each file in the playlist, every session.

Even video creators/editors that allow users to create projects containing several files at once would suffer from the API's current model, given that the user would have to allow access to all source files every time when reopening a project (unless the editor copied all source files to its private sandbox, wasting a lot of storage space).

Wolsten commented 3 years ago

At least it would be great if permission could be granted automatically or on a one-off basis in a developer scenario. The simplest changes to an app during development currently require permissions to be requested again. I have started to use the API to get the API itself working, but the turnaround time for developing the full app doesn't look like it is going to be usable. I am using the verifyPermission suggestion (to avoid two requests for view and change permission) but this still needs to be triggered by a user action and I am guessing there is no way to simulate their acceptance in a development environment? I can of course make progress by using a mockup approach either on the client or a server, but that entails more work I was hoping to avoid. Any suggestions from others who have taken such an approach would be interesting to hear about. Thanks

CedricBonjour commented 3 years ago

Hi to all,

I'm in the process of writing an IDE like PWA. I can't imagine my potential users to keep using my app if they are prompted for each "Ctrl+S" (save) action per file per session. What are the current proposed solution that would grant those read/write permissions without being a painpoint to the user?

The solution I see is to have a single persistant permission prompt that can be triggered at install: "Opening a file with this app gives the app full read/write access to the said file untill the app/session is closed" Y/N

From there the read/write permissions don't have to be persistant accross sessions. The permissions are granted as the file is opened via the "open file picker" api or via the still beta "#file-handling-api" which enable the user to open the file in the app by double clicking on it from the os' filesystem
The permissions are thus given without any extra action/pain-point on the user side but are still restrictive enough for the app not to be a safety hazard.

Is this a viable solution and could it implemented in the current api?

If so :

If not, what am I missing?

Is there another place/thread I should post this idea in?

Wolsten commented 3 years ago

I'm in the process of writing an IDE like PWA. I can't imagine my potential users to keep using my app if they are prompted for each "Ctrl+S" (save) action per file per session. What are the current proposed solution that would grant those read/write permissions without being a painpoint to the user?

Hi @CedricBonjour

I stopped looking at this API after getting no feedback here and I couldn't find anywhere else. As far as I can remember it was possible to get one permission request per session by asking for permission to access a folder (@jaifroid confirms this having just rechecked the thread above). For me the problem was that refreshing during development forced a new request, thus hindering rapid prototyping.

twilson7755 commented 2 years ago

I am trying to find some sort of update for having the FileSystem API support some form of permission persistency ... from what I have seen, this seems to be a VERY common request so I am still holding out hope that something is being done to address it. Is there some other place that I should be monitoring for updates on this topic?

@mkruisselbrink you mentioned back in January that you guys will be looking into addressing this gap sometime this year, is there any update you can provide now that the year is almost up? This still remains the missing piece before we can provide a PWA based solution for our users.

Jaifroid commented 2 years ago

EDIT: I didn't realize I was replying on the File System Access thread! Silly answer below. There still is no full persistence, but it's pretty close with a single click needed to give permission to re-open a file.

@twilson7755 Your best bet is https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API . Unfortunately, this is only supported by Chromium browsers currently (Chrome, Edge, Samsung, Opera...), and only on desktop OS, not mobile afaik. But it's good. I use it in Kiwis JS PWA.

Jaifroid commented 2 years ago

To those saying above that the current API requires the user to give access each time they save a new file, I think you are forgetting that it's possible to give access to a picked directory. After this access is granted, any non-executable file can be saved in the directory, or opened from the directory. I have a directory full of ZIM archives, and I only have to give access to my app once by picking the directory. Thereafter (within the session), any file in that directory can be read. I should add that the directory handle can be serialized to IndexedDB, and retrieved on next launch of the app. This means the user can regain access to the whole directory by answering one simple permissions prompt (a single click). This is not too onerous. Not quite like a native app, but very close.

mkruisselbrink commented 2 years ago

We're still planning some work to reduce the frequency of permission prompts. I don't think that work will require or involve changes on the spec side; when and how to prompt for permissions is really more a product decision. As such I'm closing this issue. If there are specific problems/concerns around the permission/prompting behavior, feel free to file a chromium bug instead.

ddumont commented 2 years ago

@mkruisselbrink is there a tracking issue for the changes you are working on?

a-sully commented 2 years ago

There are Chromium bugs tracking all the various things we're working on, but I don't believe there's a meta-issue tracking everything we're currently working on. Having more persistent permissions is something we are actively working on, though.

(also, Marijn has mostly transitioned away from working on this API)

elringus commented 2 years ago

@mkruisselbrink is there a tracking issue for the changes you are working on?

I've found a couple related to the topic: