← Ventures — GCStore Constellation
GCStore Hub — Level-2 Deep Dive
The GCStore Hub is the desktop client pre-installed on every machine Gabriel Capeletto LLC sells. It is the customer's on-device face of the store: it proves the machine's identity, shows the app catalog, installs entitled apps, hosts small in-hub apps, and receives post-sale offers as notifications. Its defining constraint is that it runs on hardware the company no longer controls, so it is untrusted by design — it renders state and collects signals, but never decides an entitlement on its own. Every gate it draws is a UX affordance over a decision the server already made.
Internal architecture
The Hub is a single Avalonia/.NET process (MVVM, system-tray resident) composed of a few cooperating subsystems:
- Device Identity. A Windows collector reads firmware signals (UUID, board, MAC, CPU, model) and, when present, the TPM endorsement key. A local scorer turns these into an identity assessment against a stored baseline. The key design decision: the TPM EK is a hardware-attestation tier, not just another weighted signal — a fused per-device key is hard to forge, so an EK match is dispositive on its own; the weighted sum of firmware strings (all rewritable) is only the fallback for machines without a usable TPM. All of it is explicitly advisory and destined to move server-side — the client scores only to decide when to re-bind, never to grant.
- Entitlement. The license key is the identity anchor. The Hub receives a signed entitlement lease and verifies it offline: a JWS Compact token (RFC 7515) signed with Ed25519/EdDSA (RFC 8037), checked over the exact
header.payload bytes against embedded trust anchors selected by key id — no network round-trip, no JSON canonicalization. A token signed by a key the client doesn't trust is treated as "must update", which keeps trust-anchor rotation a server concern.
- Catalog. The store vitrine is fetched from GCStore Core and is visible on every device, entitled or not — the lock icon and the buy-access offer are client-side UX only. A file cache plus observation/install state let the shelf render offline and track what's new, updatable, or installed. Rejected alternative: gating visibility by entitlement — that would have killed the sales hook (an unentitled machine seeing the full catalog locked is the pitch).
- Delivery / Installer. Performs the gated install. The Hub asks; the server withholds the package pointer and license until it independently confirms entitlement. A spoofed client that skips the local lock simply gets nothing to install.
- App-class runtime. The Hub is an app store, not a launcher of one app. It runs several app classes in-process: web (an in-hub web app — the GC Deals push inbox is one), and type:api (a descriptor-driven generic client). GC Deals surfaces offers pushed from the ERP as toasts and a read/unread inbox with per-item preview images.
- type:api client shell. For apps that talk to their own backend, the Hub brokers a short-lived scoped token from GCStore Core, fetches the app's public
/.well-known descriptor, and renders a generic UI from it — actions become typed forms, responses become tables/records/links. This means a new API-backed app ships no client code: it publishes a descriptor and the Hub draws the interface. (A Level-1 descriptor today — flat actions and typed fields; richer widgets are on the roadmap.)
- Self-update & startup. The installed fleet self-updates in place when it detects a new release (Velopack); a startup component registers the Hub to launch at Windows login so the store and its push channel are always resident.
The through-line: Identity feeds Entitlement, Entitlement unlocks the right-to-install that Catalog and Delivery act on, and the runtime hosts whatever the catalog delivers — with the server as the sole authority behind every one of those steps.
Interfaces
- ⇆ GCStore Core, REST + Ed25519 artifacts: send license key + hardware fingerprint (+ optional TPM) → receive a signed entitlement lease verified offline; fetch the full catalog manifest; request gated delivery (package pointer + license returned only when the server confirms entitlement); broker a scoped app token.
- ← offers push (core → fleet): announcements published in the ERP admin arrive as a web-type app (GC Deals) → toast + inbox.
- ⇆ third-party app backends (type:api): fetch the app's public descriptor with the brokered Bearer token, then execute the described actions against the app's API. The Hub trusts the descriptor for shape only; the app backend verifies the token offline.
- ← GitHub Releases: the self-update feed; tag-triggered GitHub Actions builds the release.
- ← Windows: firmware/TPM signals for identity, tray + run-at-login for the shell.
- ⇆ public contract repo: the boundary's source of truth — the Hub half of each contract (device authorization, delivery lifecycle, app types, type:api descriptor) is negotiated and versioned there, never in private backend internals.
Tech stack
C# / .NET 10, Windows desktop, Avalonia UI (MVVM via CommunityToolkit.Mvvm) · BouncyCastle for Ed25519/JWS lease verification · System.Management (WMI) for device-identity collection · Velopack for packaging and in-place self-update · GitHub Actions release pipeline, triggered on tag → GitHub Releases feed · public contract repo (Markdown + JSON Schema) as the boundary spec.
Status & roadmap
Production. Installed on every machine the company sells; device identity, offline lease verification, catalog, gated delivery, the GC Deals push inbox, and GitHub-Actions releases + self-update all run end-to-end today.
- Windows code-signing registration, to build SmartScreen reputation for frictionless fleet-wide distribution.
- type:api is expanding fast — the Level-1 descriptor shell already drives a live third-party app (GCruiter) end-to-end; next up are richer render widgets, a paginated table grid, and a standalone local token-vending channel for non-hub apps.
- Moving identity scoring server-side, so GCStore Core owns the trust decision end-to-end — the natural next step for the untrusted-client model.