Upload files from CLI, download them on Android. All via pre-signed S3 URLs through a backend broker.
CLI ──> Backend API ──> S3 (presigned PUT)
──> SQLite (metadata)
Android ──> Backend API ──> S3 (presigned GET)
The S3 bucket stays private. Android never holds AWS credentials. All uploads/downloads use short-lived pre-signed URLs generated by the backend.
cd backend
docker compose up --buildThis starts the API server on :8000 and MinIO (S3-compatible) on :9000.
Default API keys: dev-key-1 (user1), dev-key-2 (user2).
cd cli
go build -o push .
# Set config
./push config set --api-url=http://localhost:8000 --api-key=dev-key-1
# Upload a file
./push upload ~/Documents/report.pdf
# List files
./push ls
# Download
./push download <file-id> --out report.pdf- Open the
android/project in Android Studio - Build and run on device/emulator
- In Settings, enter the API URL (e.g.,
http://10.0.2.2:8000for emulator) and API key - File list shows uploaded files; tap to download
All endpoints require X-API-Key header.
| Method | Path | Description |
|---|---|---|
| POST | /v1/uploads/init |
Get presigned PUT URL for upload |
| POST | /v1/uploads/complete |
Mark upload as complete |
| GET | /v1/files |
List files (cursor pagination, search, sort) |
| GET | /v1/files/{id}/download |
Get presigned GET URL for download |
| DELETE | /v1/files/{id} |
Delete file |
| GET | /health |
Health check (no auth) |
# Init upload
curl -X POST http://localhost:8000/v1/uploads/init \
-H "X-API-Key: dev-key-1" \
-H "Content-Type: application/json" \
-d '{"filename":"test.txt","contentType":"text/plain","sizeBytes":13}'
# PUT to the presigned URL from response
curl -X PUT "<presignedPutUrl>" \
-H "Content-Type: text/plain" \
-d "Hello, world!"
# Complete upload
curl -X POST http://localhost:8000/v1/uploads/complete \
-H "X-API-Key: dev-key-1" \
-H "Content-Type: application/json" \
-d '{"fileId":"<fileId>","sizeBytes":13}'
# List files
curl http://localhost:8000/v1/files \
-H "X-API-Key: dev-key-1"| Env Var | Required | Description |
|---|---|---|
S3_BUCKET |
Yes | S3 bucket name |
AWS_REGION |
No | AWS region (default: us-east-1) |
AWS_ACCESS_KEY_ID |
Yes | AWS access key |
AWS_SECRET_ACCESS_KEY |
Yes | AWS secret key |
S3_ENDPOINT_URL |
No | S3-compatible endpoint (MinIO, R2) |
API_KEYS |
Yes | Comma-separated key:user pairs |
DATABASE_URL |
No | SQLite path (default: pushkit.db) |
LISTEN_ADDR |
No | Listen address (default: :8000) |
backend/ Go API server (Chi + SQLite + aws-sdk-go-v2)
cmd/server/ Entry point
internal/ API handlers, auth, DB, S3, models
Dockerfile
docker-compose.yml
cli/ Go CLI (Cobra)
cmd/ Command definitions
internal/ HTTP client, config, progress bar
android/ Kotlin + Jetpack Compose
app/ Android app module
# Backend
cd backend && go test ./...
# CLI
cd cli && go test ./...