KeyStore: File storage

KeyStore has been running in production for about a year now, storing thousands of property images for a real estate client's portfolio. It hasn't missed a beat.

Repository link: https://github.com/ReddyKousic/KeyStore

I had been using MinIO Community Edition for client projects for a while because it was self-hostable and the dashboard made it easy to manage everything without constantly relying on the CLI. In 2025, they removed most of the admin features from the community dashboard, including user management, access keys, bucket configuration, and policies. What remains is essentially just an object browser. To get those features back, you have to use AIStor, their commercial product, which starts at around $96,000 per year. At that point, it stopped fitting my workflow, since the dashboard was the main reason it worked well for smaller projects.

Instead of trying to work around those limitations or switching to something heavier, I decided to build my own solution. I did not need a full S3-compatible system or a complex storage layer. I just needed something simple and reliable for my use case: upload images, store them, and retrieve them when needed. So I built KeyStore and deployed it, and it has been handling production traffic ever since.

What it does

KeyStore is a lightweight HTTP file storage service written in Go, using only the standard library. You upload a file, you get a UUID back. You use that UUID to retrieve or delete it. That's the entire API.

POST   /upload          → { "uuid": "550e8400-..." }
GET    /files/{uuid}    → file
DELETE /delete/{uuid}

Upload and delete endpoints are protected by an X-API-Key header. Downloads are public. No S3 compatibility, no bucket abstractions, no IAM anything.

Obvious limitations

No replication. If the disk dies, the files are gone. There's no deduplication, no versioning, no access logs, and no way to list uploaded files through the API. Storage is just a flat directory of UUIDs on the filesystem. It also doesn't scale horizontally since there's no shared state between instances.

None of that was a requirement for what I needed. But you should know before you use it.

Live Images

Live image from a KeyStore instance in production.