Drag a file to your menu bar. Get a link back.
https://github.com/reneweteling/loft-app/raw/main/docs/public/assets/ex-upload.mp4
- Drag and drop a file (or folder) onto the menu bar popover — folders are zipped on the fly
- Four TTL panes — Private, 1 Day, 30 Days, Public — each enforcing expiry via S3 lifecycle tags
- Multipart upload for large files (8 MB parts, 4 concurrent) so big transfers don't stall
- Custom S3 endpoints out of the box: Cloudflare R2, Backblaze B2, MinIO, DigitalOcean Spaces
git clone https://github.com/reneweteling/loft.git
cd loft
./scripts/build.sh
cp -R build/Loft.app /Applications/First launch: see First launch (macOS security) below.
Loft is ad-hoc signed with a local certificate, not Apple-notarized. Apple charges €99/year for a Developer ID and this is a tiny personal tool, so we skip that. The tradeoff: on the very first launch macOS will refuse to open the app and show this:
Click Done, then open System Settings → Privacy & Security. Scroll to the Security section — you'll see a line about Loft being blocked, with an Open Anyway button:
Click Open Anyway, confirm the follow-up prompt, and Loft launches. macOS remembers this choice for this copy of the app — you only do it once per install.
Terminal alternative:
xattr -dr com.apple.quarantine /Applications/Loft.app && open /Applications/Loft.appskips the System Settings detour.
- Create your bucket — follow
vault/20-Setup/Bucket Setup.mdfor lifecycle rules and CORS. - Create an IAM user with the minimal policy in
vault/20-Setup/IAM Policy.md. - Open Loft Settings (
⌘,) → S3 tab — enter Access Key ID, Secret Access Key, Region, Bucket, and (optionally) a custom endpoint.
| General | Panes | S3 | About |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
- macOS 14 (Sonoma) or later
- Xcode Command Line Tools
xcode-select --installPackage.swift SwiftPM manifest
Sources/Loft/ Application source (Swift 5.9 + SwiftUI)
scripts/
build.sh Builds and ad-hoc signs Loft.app
build/
Loft.app Output of build.sh (git-ignored)
vault/ Obsidian vault — setup guides and architecture notes
docs/ GitHub Pages site
The vault/ folder is an Obsidian vault with complete setup guides and architecture notes. Open it with Obsidian or read the Markdown files directly. The GitHub Pages site at reneweteling.github.io/loft has a quick-start overview.
Key pages:
vault/20-Setup/Bucket Setup.md— lifecycle rules and CORSvault/20-Setup/IAM Policy.md— minimal IAM policy JSONvault/10-Architecture/— design decisions and component overview
Gatekeeper blocks the app — strip quarantine and reopen:
xattr -dr com.apple.quarantine /Applications/Loft.appTest Connection fails — confirm the region matches the bucket, and that the IAM user has s3:GetBucketLocation and s3:ListBucket on the bucket ARN (not just objects).
Uploads fail silently — for multipart, the policy also needs s3:CreateMultipartUpload, s3:UploadPart, s3:CompleteMultipartUpload, and s3:AbortMultipartUpload. The policy template in vault/20-Setup/IAM Policy.md covers all of these.
René Weteling
Felobo B.V. · Tech Lead · Fullstack · Ruby · Elixir · TypeScript
weteling.com · github.com/reneweteling · rene@weteling.com
Copyright © 2026 Felobo B.V. All rights reserved.






