Skip to content

About

Package registry for StartOS

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

StartOS Registry Logo

StartOS Registry on StartOS

Everything not listed in this document should behave the same as upstream StartOS Registry. If a feature, setting, or behavior is not mentioned here, the upstream documentation is accurate and fully applicable — see the Documentation section of instructions.md for links.

StartOS Registry is the server behind a StartOS marketplace: it indexes signed .s9pk packages and serves them to StartOS servers that add it. This package runs your own, administered entirely by public key — there is no account, no password, and no login anywhere in it.


Table of Contents


Image and Container Runtime

One image, published by Start9 as ghcr.io/start9labs/startos-registry:v<version> for each start-registry release. The package pins the tag of the release its version names.

Property Value
Image ghcr.io/start9labs/startos-registry (release tag pinned in the manifest)
Architectures Whatever the image publishes — the manifest declares no restriction
Command start-registryd
Subcontainer Purpose
startos-registry-sub The primary daemon — the one to attach to
get-info, set-info, add-admin, remove-admin, delete-key, list-packages Temporary; one per action, each running the start-registry CLI

Every subcontainer here is declared sharedRun: true, which lets the CLI-backed actions reach the daemon. They share the daemon's /run, so the start-registry CLI in a temporary container reaches the running start-registryd over its socket rather than over the network. These actions require the service to be running: with no daemon there is no socket to talk to. Configure Security Notifications writes the file model instead and needs no container.

Volume and Data Layout

Two volumes, one of which is mounted as a single file.

Volume Mount Point Purpose
main /var/lib/startos The package index, the uploaded .s9pk files, and the admin/signer records
config its config.yaml at /etc/startos/config.yaml, as a file The daemon's configuration

The main volume grows with whatever you publish — a registry hosting a handful of packages across several versions is measured in gigabytes. Its icons/ directory holds content-addressed package and dependency icons; it is persistent data, included in volume backups alongside the index. Upstream migrates inline icons, signature labels, and commitment tags on startup before binding the API port; the wrapper adds no migration.

File Models

One model, holding the daemon's whole configuration. Everything else the registry knows lives in its own store on the main volume, reachable only through the CLI.

File Volume Format Modelled Written by
config.yaml config YAML Yes — FileHelper.yaml Every init, and main
Key Ownership Notes
registry-listen Enforced The address the daemon binds inside its container
datadir Enforced The main volume's mount point
registry-hostname Derived Every non-local hostname the API interface publishes
tor-proxy Derived Tor's SOCKS address over the LXC bridge, written on every start
security-notifications User Whether to serve OS security-update announcements; defaults to false

registry-hostname is the one that matters operationally. The daemon reads the list once, at startup, and accepts a signed request — anything an administrator or signer sends — only when it was signed for a hostname on it. Init rebuilds the list from the addresses actually published and rewrites the file whenever the set changes, and main watches that one key, so a change restarts the service onto the new list. Add or remove an address and the registry restarts itself once, with nothing to run by hand.

A signed request to an address the interface does not publish fails with invalid request signature: not valid for any identity this server recognizes, while unsigned reads — registry info, the package index — keep working at the same address.

tor-proxy is always written, even with Tor absent. The bridge lookup carries a fallback port, so the address stays constant whether or not Tor is installed — which keeps a Tor install or uninstall from restarting the registry. With no Tor running, outbound requests through it simply get connection-refused, which the daemon tolerates.

The registry's name, icon, description, and administrators are not in this file. They live in the daemon's own store and are set through the actions.

security-notifications is controlled by Configure Security Notifications. Changing it restarts the daemon, which reads it only at startup. When enabled, the registry serves a WebSocket security feed at /os/security for clients that support it; when disabled, connections to that feed are refused. OS release security metadata remains stored and served independently of this setting.

The file model preserves unmodeled keys. For a registry serving StartWRT, startwrt: true can be set in config.yaml on the config volume; restart the service after changing it. No action exposes this upstream compatibility setting.

Dependencies

None declared. Tor is used if present — see tor-proxy above — but is deliberately not a dependency: the registry works without it, and declaring it would make an optional outbound path into an install-time requirement.

Network Access and Interfaces

One interface. It is what a StartOS server adds as a marketplace, and what a publisher pushes to.

Interface Id Type Port Description
Web API api api 5959 The web API of your custom registry

The port is bound on the api-multi MultiHost and is not masked.

Publishing an address here is how the registry becomes usable to anyone else, and it feeds registry-hostname directly. A registry only reachable on .local works, but only from the same LAN.

Installation and First-Run Flow

Install starts the daemon and raises two tasks. Nothing is generated and no credential is shown — this service has no accounts.

  1. Configure Registry — a name, and optionally an icon and a description. This is what StartOS servers display when they add your registry.
  2. Add Administrator — a label, a contact, and a PEM-encoded public key. That key is the whole of the authorization model: administration is proving possession of the matching private key, not logging in.

Both tasks require the service to be running, since both go through the CLI to the live daemon. Both are important: the registry serves an empty index perfectly well without them, it just has no identity and nobody who can administer it.

Actions

Five actions. Configure Registry, Add Administrator, Remove Administrator, and List Packages are only available while the service is running. Configure Security Notifications is available while running or stopped.

Configure Registry

Sets the registry's display name, icon, and description.

  • What it changes: the daemon's own store, via start-registry info set-name / set-icon / set-description.
  • Cost: seconds. No restart.
  • Repeat safety: idempotent, and the form is pre-filled from the live daemon rather than from a file.
  • The icon is a data URL or an http(s) URL, validated by pattern before it is accepted. Leaving it blank leaves the existing icon in place rather than clearing it.
  • The description is markdown, shown above the registry's services in the marketplace. Blank leaves the existing one in place.

Add Administrator

Registers a signer and grants it admin rights.

  • What it changes: the daemon's store — it adds a signer record with the label, contact, and public key, then grants that signer id admin.
  • Cost: seconds. No restart.
  • Repeat safety: each run adds a new administrator; it is not an edit. The daemon rejects a key already registered to a signer.
  • The contact is stored as a URL — an email becomes mailto:, a Matrix username becomes a matrix.to link.
  • The key must be a PEM public key, checked by pattern — the administrator's start-cli identity key, which start-cli pubkey prints. There is no key generation here: the private half is yours and never touches this server.

Remove Administrator

Revokes an administrator by removing their signer record.

  • What it changes: the daemon's store, via start-registry admin signer remove, which drops the signer and every authorization it holds.
  • Cost: seconds. No restart.
  • Repeat safety: idempotent per administrator; the dropdown is built from the live list and starts with nothing selected.
  • Nothing stops you removing the last one. Do that and no key can administer the registry any more — recovery means the CLI inside the container.

List Packages

Shows how many packages the registry hosts and their names, alphabetically, one per line.

  • What it changes: nothing. It reads start-registry package index from the live daemon and formats it.
  • Cost: seconds. No restart. The index carries icon references and descriptions, so the read grows with the registry.
  • Repeat safety: read-only.
  • Each name is the title of the package's newest version. A package whose versions have all been removed is left out.
  • It is an overview, not the index. Versions, architectures, package ids, download URLs, signers, and categories are not shown. start-cli registry package index from an administrator's workstation has all of those, and the marketplace lists a registry's packages with search and categories.

Configure Security Notifications

Enables or disables announcements of OS security updates to compatible clients. Disabled by default.

  • What it changes: security-notifications in config.yaml; a change restarts the running service automatically.
  • Cost: a brief restart. While stopped, the setting takes effect on the next start.
  • Repeat safety: idempotent; saving the current value does not restart the service.
  • Scope: controls the /os/security WebSocket feed, not the security flag on published OS releases. A reverse proxy must forward this path with WebSocket upgrades for subscribers to use it.

Tasks

Two tasks, both raised at install.

Task Severity Raised when Cleared when
Configure Registry important At install The action runs
Add Administrator important At install The action runs

important rather than critical because the daemon runs and serves regardless. What is missing without them is identity and the ability to publish, not function.

Health Checks

One check, on the only daemon.

Check Displayed Method
primary "Web API" Port 5959 is listening

The daemon binds quickly, so a failure means it did not start — most often a config.yaml value it rejects, which it names in the service logs. Actions failing while this check is green is a different symptom: those go through the shared /run socket rather than the port, so a CLI error points at the daemon's store or the argument it was given, not at reachability.

Backups and Restore

Both volumes are copied wholesale — sdk.Backups.ofVolumes('config', 'main'). No dump step and nothing excluded.

  • Included: every published .s9pk, the whole index, the administrator and signer records, and config.yaml.
  • Size: this is the large one. The backup is as big as everything you have ever published and not removed.
  • Restore: complete, and no task is raised — the name, icon, and administrators come back with the store. If the restored server publishes different addresses, init rewrites registry-hostname from the live set on the first start.

Limitations and Differences

  1. Administration is by public key only. No accounts, no passwords, no web login — the private key is yours to keep.
  2. Removing the last administrator locks you out of everything the actions do; nothing warns you first.
  3. The CLI-backed actions need the service running, because they reach the daemon over a shared socket rather than a network port. Configure Security Notifications works while stopped too.
  4. The manifest declares no architecture restriction, so which architectures work is whatever the published image covers.
  5. Categories are not configurable here yet — the Configure Registry action sets name, icon, and description only.
  6. Tor is not a dependency, and a tor-proxy value is written whether or not Tor is installed.
  7. Changing the Web API interface's addresses restarts the service. The daemon cannot reload its hostname list, so a restart is how a new address starts accepting signed requests.
  8. OS security-update announcements are opt-in. Configure Security Notifications controls the feed and restarts the service when changed.

Quick Reference for AI Consumers

package_id: startos-registry
image: ghcr.io/start9labs/startos-registry # release tag pinned in the manifest
architectures: as published by the image # the manifest declares no restriction
subcontainers:
  - startos-registry-sub # the running daemon
  - get-info # temporary; one per action, all sharedRun: true
  - set-info
  - add-admin
  - remove-admin
  - delete-key
  - list-packages
volumes:
  main: /var/lib/startos
  config: its config.yaml at /etc/startos/config.yaml (file mount)
file_models:
  - config.yaml
startos_managed_env_vars: []
dependencies: [] # tor is used when present but not declared
interfaces:
  api: { type: api, port: 5959 }
actions:
  - config # only-running
  - add-admin # only-running
  - remove-admin # only-running
  - list-packages # only-running, read-only
  - security-notifications # any status; restarts on change
tasks:
  - { action: config, severity: important }
  - { action: add-admin, severity: important }
health_checks:
  - primary # displayed "Web API"

About

Package registry for StartOS

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages