File Access Control
for convex storage, is there a way to lock down stored files? like never allow access unless they have a signed url? I know the ids are like 32 characters long which is probably impossible to guess, but I'm curious is there was a "private bucket" type of approach
12 Replies
Hey!
This is actually why we don't expose the files by default. The most locked down version is gating the backing URL via an HTTP action: https://docs.convex.dev/file-storage/serve-files#serving-files-from-http-actions
Serving Files | Convex Developer Hub
Files stored in Convex can be served to your users by generating a URL pointing
in this manner you would _never_publicly expose the storage URL, and then you can use arbitrary control mechanisms in this HTTP action to gate access to file data
like authentication information + group membership + time expiry or whatever rules you want
@Jamie but when I hit /api/storage/STORAGE_ID, anyone can access the file; are you saying there is a way to disable this access?
gotcha. yes, this is predicated on this being long enough to be unguesseable, like UUID v4
and that's definitely sufficiently secure
b/c essentially you're talking about someone brute forcing this API to discover any files
since there's no way for them to target a specific file
so right now I just store the storageId on various tables when users upload files
do you think that's fine assuming I never leak the id to non-authorized users
(I just tagged the authorities on this at convex to weigh in so we get accurate answers to these questions)
the only other approach I could think of is have a table that maps some internal imageId -> convex storage id, but that would require doing some more joins / lookups on all my data
it probably would help protect ever leaking the storage id
okay, confirmed this
document ids are not reliable secrets
but they are okay to give out freely because they do not directly grant access to file data
including document ids in the
_storage
system table
file URLs are secrets, and they use an unguessable UUIDv4
so do not give out file URLs if you want to ensure security. use the http action method above
and then even if someone has a storage document id, you can still deny them the file data at any time
lmk if that makes sense. the key thing to avoid distributing is the file URL with the uuidv4 in it if you want full control over file accessYeah I’m not sure I follow because using the storage id, I’m able to hit the convex.dev/api/storage/StorageId and it seems to show the file. That url seems to be a direct public link to the files right?
Thanks for pointing this out! It's not intended that storage ids work with the /api/storage/ endpoint. We'll fix this up. Storage ids should have enough randomness to be unguessable, but we don't want to assume any client with a storage id can have access to the file.
Update in case someone is reading this thread. We no longer allow fetching a file using
/api/storage/:storage-id
. This was an undocumented behavior that was never meant to work. We do not allow this as of 7 days ago except for a handful of grandfathered instances we have reached out to. The proper way to generate an url to fetch a file is by using storage.getUrl(storage_id). See https://docs.convex.dev/api/interfaces/server.StorageReader#geturl for more details.Interface: StorageReader | Convex Developer Hub
server.StorageReader