The difference between upload and replace: uploading to a key that doesn’t exist uses the upload rule; uploading to one that does uses the replace rule. Use that to let people add files but not overwrite others’.
Design keys around rules
Put the owner first:<user id>/…. Then one custom rule protects the whole bucket:
Compare values…Use it as Who may upload new objects, replace, delete and read for a private bucket. In practice:$object.segments.0equals$auth.user_id
$object.segments.0 with $auth.org and use keys like <org slug>/….
Public, but not browsable
Public bucket lets anyone with a file’s address read it. Set Who may list objects to Signed-in users (or a role) and the bucket still can’t be enumerated: strangers can only see files whose address they hold.What a refusal looks like
The rule runs before the file is looked up, so a refusal never reveals whether a key exists.
Check a rule
Try something that must fail, signed in as an ordinary person:error.requestId and read which rule decided (Debugging rules).
Studio isn’t bound by the rules
Studio’s file browser acts with its own authority, so a bucket only your server may write to can still be filled from Studio.Rules on storage
More examples.
Bucket settings
Where rules are set.