Mighty Registry¶
The Mighty package registry is a thin convention layered on GitHub
Releases. There is no central server: a registry is just a GitHub
repository (<owner>/<repo>) whose Releases host one tag per published
(package-name, version). This document covers:
- Storage convention
- Index discovery and caching
- Resolution semantics
- Multiple registries
- Authentication
- Publishing
- Hosting your own registry
- Security model
- Roadmap
Status. The registry transport shipped in v0.4. The official registry (
mighty-pkg/registry) is not yet created on GitHub — that belongs to the v0.5 cloud control plane. Until then, configure[registry].defaultto point at any GitHub repo that follows the storage convention below.
Storage convention¶
Each published version is one GitHub Release on the registry repository with:
| Field | Value |
|---|---|
| Tag | <package-name>-<version> (e.g. otel-0.1.0) |
| Asset 1 | <package-name>-<version>.tar.gz — gzipped tar of the source |
| Asset 2 | <package-name>-<version>.tar.gz.sha256 — sidecar (hex hash + filename) |
| Release body | Verbatim mighty.toml from the published version |
Package names may contain dashes; the tag parser splits on the last
dash before a digit, so my-lib-1.2.3 parses as (my-lib, 1.2.3).
The tarball expands into a single top-level <name>-<version>/
directory (matching the cargo / npm convention) with deterministic
ordering, mtime, uid, gid → identical bytes on every rebuild.
The sidecar file is a single line in the sha256sum -b shape:
mty pkg fetch accepts either the bare hex digest, the
sha256:<hex> form, or the full sha256sum line.
Index discovery and caching¶
mty-pkg discovers releases via the standard GitHub Releases REST
API:
Pagination is automatic (capped at 50 pages / 5000 releases per
registry). Each release whose tag_name parses into
(name, version) is catalogued; everything else is ignored.
The parsed catalogue is cached locally per package, under:
- TTL: 1 hour. After expiry the next operation that needs the
index revalidates via
If-Modified-Since(304 → bump the cache timestamp, keep the existing list). - Force refresh:
mty pkg update --refreshre-pulls every configured registry's index.
Resolution (mty pkg add, mty pkg update) is intentionally
offline-first: it only reads the on-disk cache, never the
network. This keeps add fast and reproducible. If you want the
latest available versions, update --refresh first.
Resolution semantics¶
For each registry dep:
- Walk the configured registries (default first, then each
extrasentry in order). - In each registry's cached index, find every release matching
nameand whose version satisfies the semver requirement. - Pick the highest matching version. Stop scanning further registries — first-listed wins on duplicates.
- If no registry has a match (no cache, empty index, package
missing), fall back to synthesising the version from the
requirement floor (
^0.3.2→0.3.2). The lockfile still pins the default registry's slug;mty pkg fetchwill then surface a clear "release not found" error if the package truly isn't there.
The lockfile records the chosen registry slug:
[[package]]
name = "otel"
version = "0.1.0"
source = "registry+gh://mighty-pkg/registry"
hash = "sha256:..."
Multiple registries¶
A package's mighty.toml may opt into additional registries:
[registry]
default = "mighty-pkg/registry" # the official one
extras = ["myorg/private-mighty-pkgs"] # additional registries
Lookup order is default, then extras in declared order. On
duplicate (name, version) across registries, first hit wins.
Omitting [registry] is equivalent to:
Authentication¶
Two layers exist:
-
API rate limits. Even for public registries, an unauthed GitHub token gets you 60 requests/hour; a personal access token (PAT) raises that to 5000/hour. Set
GITHUB_TOKENin your environment to use it across every registry. -
Private registries + publish. Per-registry tokens are stored at:
(Windows: %APPDATA%\mty\auth.toml). The file shape:
On Unix, auth.toml is written with mode 0600. The same
storage model as gh CLI's ~/.config/gh/hosts.yml.
Configure tokens with mty pkg login:
# token must be provided via env-var (v0.4 disables interactive prompts)
SDUST_PKG_LOGIN_TOKEN=ghp_xxxxx mty pkg login myorg/private-mighty-pkgs
Lookup precedence: the per-slug token in auth.toml first, then
GITHUB_TOKEN.
The required GitHub-token scopes:
| Operation | Minimum scope |
|---|---|
| Read public idx | none (unauthed) or any token (better rate limit) |
| Read private repo | repo |
| Publish | repo (creates releases + uploads assets) |
Publishing¶
publish always writes the local artefacts:
.mighty/publish/<name>-<version>.tar.gz.mighty/publish/<name>-<version>.tar.gz.sha256
When a token is available for the configured default registry, it proceeds to:
POST /repos/<owner>/<repo>/releaseswith the tag, manifest body,draft: false,prerelease: false.- Upload the tarball asset (Content-Type:
application/gzip). - Upload the sha256 sidecar (Content-Type:
text/plain).
On success, the new release URL is printed. On 401/403/404, the artefacts are still on disk and the user can drag them onto the release page manually.
Bundle exclusions¶
Files under these top-level paths are excluded from the tarball:
.git/target/.mighty/(your local cache lives here)
There is no package.include/exclude field yet — that's tracked as
a post-v0.5 enhancement.
Hosting your own registry¶
- Create a public or private GitHub repository, e.g.
myorg/our-mighty-pkgs. The repo's README + LICENSE are optional; the registry only cares about Releases. - For each package you want to publish, follow the storage
convention. The easiest path is
mty pkg publishfrom inside the package directory, after amty pkg login myorg/our-mighty-pkgs. - Point consumers at your registry:
That's it. No custom server, no DNS, no infra. GitHub handles storage, integrity (release tags + commit signatures), and bandwidth.
Security model¶
| Threat | Mitigation |
|---|---|
| Tarball tampered in transit | sha256 sidecar verified pre-extract |
| Tarball tampered post-fetch | mighty.lock pins sha256; subsequent fetches fail |
| Malicious tarball path-traversal | Extraction rejects .., root, and drive-prefix |
| Compromised registry repo | Use a private/owned registry; pin lock hashes |
| Leaked publish token | Per-slug tokens; revoke individually in GitHub UI |
| Compromised maintainer account | (post-v0.5: signed releases + co-maintainer review) |
The plaintext token file is the same tradeoff gh CLI and cargo
login make. On Unix the file is mode 0600. On Windows we rely on
NTFS user-profile ACLs.
Roadmap¶
Beyond v0.4:
- Yanked packages. A
yanked: truefield in the release body with a clear consumer-side warning. Lockfile pin still works, butpkg addskips yanked versions. - Security advisories. A separate
security/directory in the registry repo with one Markdown file per advisory;mty pkg auditcross-references it. - Signed releases. GitHub release artefacts have ETags but no built-in signing today; a sigstore + cosign pipeline would pre-sign the tarball and embed the signature next to the sidecar.
- Mirror support. A read-only mirror configured in addition to the default lets large orgs cache hot packages.
- Package include/exclude.
[package].includeand.excludeglobs to refine which files get tarred.
The cloud control plane will eventually create
hassard0/Mighty-pkg-registry (or similar) and seed it with the
stdlib.