What’s shipped
| Component | Status | Notes |
|---|---|---|
| Docker Compose stack | ✅ | All services orchestrated with health checks |
| Caddy reverse proxy | ✅ | Subdomain routing for *.{org}.local |
| CoreDNS LAN DNS | ✅ | Resolves *.{org}.local on the local network |
Install script (install.sh) | ✅ | One-command install, idempotent, port conflict detection |
| Platform schema + migrations | ✅ | Drizzle-managed, versioned |
| HMAC internal signing | ✅ | SigV4-inspired, shared across all services |
| API Gateway | ✅ | API key resolution, HMAC forwarding, public file route |
| Blaze — database service | ✅ | Multi-tenant Postgres, RLS isolation |
| Vault — file storage service | ✅ | Upload, download, public/private per file, MIME detection |
| Orbit — deploy service | ✅ | Atomic bundle deploy, rollback |
| Console — admin dashboard | ✅ | App management, deployments, vault file browser, API keys |
@nublestation/cli | ✅ | nuble server, nuble deploy, nuble init, nuble status |
@nublestation/vault SDK | ✅ | upload, list, download, setPublic, delete |
| Service contract + HMAC docs | ✅ | Three trust paths documented with examples |
In progress
Identity — Auth Service
Sessions, API keys, and OIDC/SSO so users of clinic apps can authenticate once and be recognised across all apps on the same NubleStation install.
- Session management (Lucia v3)
- OIDC provider (
oidc-provider) — shared SSO across apps - API key issuance and revocation for end users (not just developers)
-
@nublestation/identitySDK —signIn(),signOut(),getSession()
@nublestation/blaze SDK
TypeScript client for querying app database tables.
-
createBlazeClient({ url, apiKey }) -
query,insert,update,deletewith typed builder - RLS enforced at the API layer — app A cannot see app B’s data
Planned features
NubleStore — App Marketplace
Pre-built app bundles that clinic admins can install in one click. Each store app is a static frontend that uses NubleStation services — no custom backend needed.
The install flow: Console → Browse Store → Install → App is live at {slug}.{org}.local
Under the hood, “install” is: create app row → fetch pre-built bundle from registry → deploy via Orbit. No new infrastructure required — it reuses every existing piece.
First candidate: Bucket — a file manager SPA that uses @nublestation/vault for storage.
ADR: docs/adr/013-nublestore-app-marketplace.md
Real-time — SSE subscriptions
Server-Sent Events backed by Postgres LISTEN/NOTIFY.
- Auto-generated triggers on tenant tables
@nublestation/blaze.subscribe()method- Console live-reload of deployments and file counts
Hardening
- Per-request quotas and
statement_timeout - Audit log viewer in Console
pg_dumpbackup script
Out of scope (permanent)
- Multi-machine clustering (Kubernetes, Docker Swarm)
- Internet-facing hosting (NubleStation is LAN-native by design)
- Server-side rendering for deployed apps (static SPAs only)
- S3-compatible storage API (local filesystem only)
- Mobile native SDKs
- WebSocket real-time in v1 (SSE covers the use cases)
Defense day milestone
- Fresh Ubuntu VM →
curl ... | bash→ console live in under 10 minutes - Admin creates app “tasks” →
tasks.{org}.localreserved - Developer deploys a task SPA → visible on any LAN device
- Unplug internet → everything still works
- Kill a container → Docker auto-restarts it
- Upload a file via SDK → appears in Console vault tab
Version 1.0.0 is tagged on defense day.