BaryoDev / BaryoDev/barakoCMS

Files: public and private objects share one key layout, so no bucket policy or CDN can serve only public files

Open
#779 0 comments 0 reactions 0 assignees View on GitHub
enhancement module
Dominant language
C#
Stars
6
Forks
7
Avg merge
4h 42m
Merged PRs (30d)
307

Description

Public and private files share one key layout in object storage, so nothing in front of the bucket can serve only the public ones.

## Where

- `BarakoCMS.Files/Features/Upload/Endpoint.cs` builds every key as `{Guid.NewGuid():N}{ext}`, whether `isPublic` is true or false.
- `BarakoCMS.Files.S3/S3FileStorage.cs` sets `S3CannedACL.PublicRead` on a public upload only when `UsePublicReadAcl` is true, and returns a public URL only when `PublicBaseUrl` is set.
- `GET /api/public/files/{id}` refuses a private file, then redirects to the public URL if there is one, and otherwise reads the object and streams it.

## Why it matters

Visibility lives in the database row and, optionally, in a per-object ACL. Most S3-compatible stores ignore object ACLs (Cloudflare R2, SeaweedFS, Garage), and AWS buckets created today have ACLs disabled by default. The remaining ways to give public files a direct URL all act on the whole bucket or a key prefix:

- a bucket policy granting `s3:GetObject`
- a CDN such as CloudFront with origin access, or an R2 public bucket

With one flat layout, any of those exposes private files to anyone who has a key. Keys are random, so this is not guessable today, but a key reaching a log, a referrer or an export is enough, and "private" should not depend on that.

So the only safe setting right now is what #774 documents: `UsePublicReadAcl=false`, no `PublicBaseUrl`, and every public file streamed through the API, which gives up the CDN URL the module exists to provide.

## Proposal

Put visibility in the key: `public/{guid}{ext}` and `private/{guid}{ext}`. A bucket policy or CDN origin can then be scoped to `public/*` and nothing else.

- New uploads use the prefix. Existing objects keep their stored key, since `StorageKey` is already read from the row, so no migration is required for reads.
- Changing a file's visibility after upload does not exist today; if it is added, it must move the object between prefixes.
- Document the scoped policy for AWS S3 and the CloudFront origin setup in the Files.S3 README.

## Done when

- A test uploads one public and one private file and asserts their keys start with `public/` and `private/`.
- The README shows a bucket policy on `public/*` only, and says that without the prefix no bucket-wide public access is safe.

Contributor guide

Open the contributing guide

Research direction

Start with BarakoCMS.Files/Features/Upload/Endpoint.cs and BarakoCMS.Files.S3/S3FileStorage.cs, then inspect the GET /api/public/files/{id} path and the Files.S3 README. Add coverage for public and private key prefixes, and document an AWS policy and CloudFront setup scoped to public/*; done means existing stored keys still read and the README explains why bucket-wide access is unsafe.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, csharp
Domain
backend, cloud, documentation, security, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.