11 KiB
Update Server - Implementation Strategy
1. Recommended stack
Backend
- Go 1.24+
- Router:
chiorgin - HTML templates for admin UI, or server-rendered pages first
- Database:
SQLite - ORM/query layer:
sqlc,bun,gorm, or plaindatabase/sql - Migrations:
golang-migrateorgoose - Auth:
- web admin via secure cookie session
- client API via bearer API key
My recommendation
For this project, a pragmatic Go stack would be:
chifor routing;database/sql+sqlcorbun;SQLitewithmodernc.org/sqliteormattn/go-sqlite3;- server-rendered HTML templates for admin pages;
goosefor migrations.
Why this stack:
- simple to deploy;
- less JS and frontend complexity;
- good fit for an internal admin panel;
- easier to keep maintainable for a small self-hosted tool.
2. Quick glossary
GUI
- graphical user interface;
- here it simply means the admin web panel in a browser.
chi
- a small and fast HTTP router for Go;
- this is not
CI; - it helps map routes like
/api/v1/projects/{id}to handlers.
CI
- continuous integration;
- automated checks that run on commits, for example tests, linting, or building Docker images.
server-rendered HTML
- the Go server itself generates HTML pages and returns them to the browser;
- this keeps the admin panel simpler than building a separate frontend app.
3. Architecture proposal
Suggested project structure:
/cmd/server
/internal/app
/internal/http
/internal/auth
/internal/projects
/internal/releases
/internal/apikeys
/internal/users
/internal/tags
/internal/storage
/internal/db
/internal/config
/web/templates
/web/static
/migrations
/data
Main modules
projects
- create/update/list/archive projects
- manage project tags
releases
- upload artifact
- compute checksum
- store metadata
- provide release lookup and download
apikeys
- generate secure random API keys
- hash and persist
- enforce permissions and project scope
tags
- CRUD for tags
- attach tags to projects
- resolve tag-based access rules
users
- admin authentication
- password hashing
- role checks
storage
- local filesystem storage abstraction
- future option to swap to S3-compatible storage
4. Suggested data model
Core tables:
usersprojectstagsproject_tagsreleasesapi_keysapi_key_project_accessapi_key_tag_accesssessionsif server-side sessions are used- optionally
audit_logs
Example relations
- one
projecthas manyreleases - one
useruploads manyreleases - one
projecthas many tags throughproject_tags - one
api_keycan reference many projects throughapi_key_project_access - one
api_keycan reference many tags throughapi_key_tag_access
Suggested key columns in api_keys:
scope_modewith values:all_projectsproject_allow_listproject_deny_listtag_allow_listtag_deny_list
5. Permission strategy
Recommended first implementation:
- API key has boolean flags:
can_downloadcan_uploadcan_deletecan_manage_projects
- API key has access mode:
all_projectsproject_allow_listproject_deny_listtag_allow_listtag_deny_list
- linked projects stored in
api_key_project_access - linked tags stored in
api_key_tag_access
Recommended evaluation rules:
all_projects: allow every active projectproject_allow_list: allow only linked projectsproject_deny_list: allow every active project except linked projectstag_allow_list: allow projects matching at least one linked tagtag_deny_list: allow every active project except projects matching blocked tags
Recommended constraint for v1:
- each key uses exactly one scope mode at a time.
This supports whitelist, blacklist, and future grouping without building a full RBAC engine upfront.
6. API design strategy
Split API into two logical areas:
Client API
Used by application clients:
- authenticate by bearer API key
- list accessible projects
- query latest release
- download release artifact
Admin API
Used by web UI and optionally automation:
- manage projects
- manage tags
- manage releases
- manage API keys
- manage users
Keep both under /api/v1, but separate middleware and handlers clearly.
7. File upload strategy
Recommended upload flow:
- admin uploads file;
- backend stores temporary stream;
- checksum is calculated;
- file is moved into final artifact path;
- release metadata is inserted into DB;
- transaction/state is finalized.
Important safeguards:
- limit file size;
- sanitize filenames;
- prevent path traversal;
- avoid duplicate version collisions unless explicitly replacing;
- validate project exists before storing;
- store uploads outside any static web root;
- never execute or unpack uploaded files.
8. Security checklist
- hash passwords with
bcryptorargon2id - hash API keys before storing
- show full API key only once
- secure cookies with
HttpOnly,Secure,SameSite - CSRF protection for admin forms
- upload size limits
- permission checks on every API endpoint
- request logging without leaking secrets
- rate limiting for login and API key endpoints
- store artifacts outside the web root
- serve downloads only after auth and permission checks
- set server timeouts: read, write, idle, header
- add security headers such as
Content-Security-Policy,X-Frame-Options,X-Content-Type-Options - terminate TLS at Caddy or Nginx
- optionally restrict admin UI by IP allow-list or VPN
- avoid shelling out to external tools for file processing
- keep dependencies updated and scan them periodically
9. Internet-facing deployment posture
If the server will be visible on the internet, this is the safe baseline:
- app listens only behind a reverse proxy;
- reverse proxy handles HTTPS certificates;
- admin UI uses strong password and optionally IP allow-list;
- SQLite file and artifacts live on a mounted persistent volume;
- no public directory listing for artifacts;
- uploads never become directly executable server-side content;
- logs and backups are stored separately from app code.
10. Development strategy
Recommended approach:
- develop locally on your Mac first;
- keep everything in one project directory;
- run the Go server natively for fast iteration;
- add Docker packaging once the core flows work locally;
- deploy to Proxmox only after the first end-to-end flow is stable.
Why local-first is better here:
- faster feedback loop;
- easier debugging;
- easier file upload testing;
- no need to fight remote networking while core logic is still changing.
Good compromise:
- write code locally on Mac;
- keep deployment target from day one in mind;
- periodically verify that the Docker image still builds.
11. Deployment strategy
Single container is realistic.
Recommended runtime layout:
- app binary in container
- reverse proxy in front of container
- mounted
/datavolume - SQLite DB in
/data/db.sqlite - artifacts in
/data/artifacts
Environment variables
APP_ADDRAPP_BASE_URLDATA_DIRSQLITE_PATHADMIN_EMAILADMIN_PASSWORDSESSION_SECRET
Recommended deployment target:
- Proxmox VM or LXC with Docker or Podman;
- app container plus reverse proxy;
- mounted volume for
/data; - regular backup of
/data.
12. Delivery phases
Phase 1 - Skeleton
- initialize Go module
- wire config
- HTTP server
- health endpoint
- migrations setup
- SQLite connection
- basic template rendering
Phase 2 - Auth and admin bootstrap
- user table
- create initial admin user
- login/logout
- session middleware
Phase 3 - Projects and releases
- projects CRUD
- project tags CRUD
- release upload
- release list/detail
- local artifact storage
Phase 4 - API keys and access control
- API key generation
- hashed storage
- project white-list and black-list
- tag-based schema and access checks
- permission middleware
Phase 5 - Client update API
- latest release endpoint
- release metadata endpoint
- download endpoint
- audit of last key usage
Phase 6 - Hardening
- validation
- CSRF
- logging
- soft deletes
- basic audit logs
- reverse proxy config
- rate limiting
- Docker image and compose setup
13. Agent execution plan
If multiple AI agents or contributors will implement this, split work by vertical ownership.
Agent 1 - Core platform
Owns:
- Go module setup
- config
- server bootstrap
- middleware skeleton
- Docker setup
Agent 2 - Data layer
Owns:
- migrations
- schema
- repositories/queries
- SQLite integration
- tags and access-rule tables
Agent 3 - Auth and users
Owns:
- admin login
- sessions
- password handling
- user management basics
Agent 4 - Projects and releases
Owns:
- project CRUD
- tag assignment to projects
- release upload flow
- artifact storage abstraction
- checksum logic
Agent 5 - API keys and client API
Owns:
- API key generation
- permission model
- whitelist/blacklist evaluation
- tag-based access evaluation
- client-facing release lookup and download endpoints
Agent 6 - Admin UI
Owns:
- HTML templates
- forms
- tables/pages for projects, releases, keys, users, tags
Agent 7 - Security and deployment hardening
Owns:
- secure headers
- rate limiting
- reverse proxy templates
- deployment hardening review
14. Recommended implementation order for agents
- Agent 1 sets up application skeleton and app wiring.
- Agent 2 defines schema and migrations.
- Agent 3 implements admin auth.
- Agent 4 implements projects, tags, and release storage.
- Agent 5 implements API key model and client endpoints.
- Agent 6 builds the admin UI on top of completed flows.
- Agent 7 hardens internet-facing deployment paths.
- Final pass integrates validation, tests, and Docker packaging.
15. Testing strategy
Unit tests
- version selection logic
- permission checks
- API key hashing/lookup
- checksum generation
- tag scope matching
Integration tests
- login flow
- create project
- attach tags to project
- upload release
- create API key
- fetch latest release via API key
- reject unauthorized project access
- reject blacklisted project or tag access
Manual sanity tests
- upload file from admin UI
- download via curl using bearer API key
- restart container and verify persistence
- verify admin login rate limits
- verify artifacts are not directly exposed by URL guessing
16. My recommendations on product scope
To avoid overbuilding too early, I would start with:
- SQLite
- local filesystem storage
- server-rendered admin UI
- one file per release
- one admin role first, but schema ready for more users
- one scope mode per key
- project whitelist and blacklist in v1
- project tags in schema from day one
This version will already be useful and can stay very small operationally.
17. Nice first concrete milestone
The first milestone should be:
"Admin can log in, create a tagged project, upload a versioned file, create an API key with project or tag-based access, and a client can download the latest file using that key."
If that works end-to-end, the rest can be layered on safely.