Files
Juan DenisandClaude Opus 5 593dd11a8b docs(registries): write down the test for what earns a registry
"Should X be a registry too?" gets re-asked every few months, and the answer is
usually no. This records the rule and the per-catalog verdicts so the assessment
does not get redone from scratch.

A catalog earns a registry only when all three hold: it changes faster than the
panel releases, it is data rather than code (a new entry must work on an
existing panel with no code change), and someone outside the release cycle would
contribute to it. Extensions, themes and app templates pass. Seven other
catalogs were assessed and rejected, each with the reason -- server templates,
notification events, AI providers, DB tuning settings, sanitization profiles,
agent survey probes and build packs.

Also names the failure mode that makes a bad extraction expensive: panels that
have not upgraded read the registry forever, so an entry that needs new panel
code either gets ignored or renders as a broken item. That is what forces a
min_panel_version gate, and why serverkit-extensions has one and the other two
do not need one.

Records one open candidate rather than leaving it implicit. YARA rules pass all
three tests and have no update path -- 16 curated rules frozen at release time.
That got sharper this session: the image now builds without ClamAV by default,
and ClamAV was the component with a self-updating feed via freshclam, so YARA is
now the only malware detection in a default container. Operators can already
drop custom .yar files in CUSTOM_RULES_DIR; what is missing is a curated
upstream. Not built -- noted so the gap is deliberate.

Adds the templates registry and this doc to the README documentation table.
Every claim was checked against the code rather than written from memory: rule
counts (16 in both BUILTIN_RULES and webshells.yar), the CUSTOM_RULES_DIR
default, ARG INSTALL_CLAMAV=false, and that ServerTemplateService already
exposes create_template so its 12-entry library is a seed, not a catalog.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 14:53:17 -04:00

5.5 KiB

Registries

ServerKit publishes some of its catalogs as standalone repositories that panels read over the network, so entries can ship without a panel release. Three exist today:

Registry Repo Bundled in the panel?
Extensions serverkit-extensions builtins only; the rest install on demand
Themes serverkit-themes 17 bundled, gallery adds more
App templates serverkit-templates all 106 bundled, registry adds/updates

This document exists because "should X be a registry too?" is a question that otherwise gets re-asked every few months. Most of the time the answer is no.

The test

A catalog earns a registry only when all three hold:

  1. It changes faster than the panel releases. If new entries naturally arrive with the feature work that consumes them, a registry buys nothing.
  2. It is data, not code. A new entry must work on an existing panel with no code change. If using it requires a new service method, a new job kind, or a new UI surface, it is code wearing a catalog's clothes.
  3. Someone outside the release cycle would contribute. If only the maintainers will ever add entries, a directory in this repo is simpler and reviews the same way.

Fail any one, and extraction adds a network dependency, a second release process, and a version-skew surface in exchange for nothing.

The failure mode to avoid

The expensive mistake is extracting a catalog that fails test 2. Panels that have not upgraded keep reading the registry forever. Publish an entry that needs new panel code, and every old panel either ignores it (best case) or shows a broken item it cannot install (worst). At that point the registry needs its own min_panel_version gate — which is exactly why serverkit-extensions has one, and exactly the complexity you do not want unless the catalog earns it.

Why the three qualified

  • Extensions are independently versioned code artifacts with permissions and a min_panel_version gate. They are the archetype: third-party authored, released on their own cadence, installed at runtime.
  • Themes are pure token maps — data by construction, contributed by people who will never open a panel PR, and worthless if shipping one requires a release.
  • App templates are declarative Compose specs. New self-hosted apps appear constantly and each is ~2 KB of YAML that an existing panel already knows how to install. TemplateService has always resolved <repo_url>/index.json + <repo_url>/templates/<id>.yaml; the registry is just the other end of a contract the panel already had.

Note the pattern: bundled and registry are not exclusive. Templates and themes ship inside the panel and have a registry. The bundle is the offline floor — air-gapped installs, fresh installs with no network, and any day GitHub is unreachable — while the registry is the growth path. Only extensions lean on the registry as the primary source, because they are large and optional by nature.

What was assessed and rejected

Catalog Where Verdict
Server templates ServerTemplateService.TEMPLATE_LIBRARY No. 12 entries, stable, and operators already create their own via create_template() into the DB. The library is a seed, not a catalog.
Notification events app/notifications/catalog.py No. Fails test 2 — an event type is only real if panel code emits it. A registry entry with no emitter is a dead row.
AI providers ai_service.CURATED_PROVIDERS No. Each entry is bound to a Prompture driver; adding one without the driver produces a provider that cannot connect.
DB tuning settings db_config_tuner_service.CURATED_SETTINGS No. Fails test 3 — tuning knobs track the engines the panel supports, and only maintainers will touch them.
Sanitization profiles models/sanitization_profile.BUILTIN_PROFILES No. Consumed by code paths that must understand each profile.
Agent survey probes app/data/survey_probe_catalog.yaml No. A probe is only meaningful if the agent implements its kind, so it is gated by the agent's release, not the panel's.
Build packs buildpack_service No. Not a catalog at all — it generates Dockerfiles and compose from a build plan. That is code.

Open candidate: malware signatures

YARA rules are the one remaining catalog that passes all three tests, and they have no update path today.

YaraScanService.BUILTIN_RULES (16 curated rules, mirrored in yara_rules/webshells.yar) ships inside the panel and changes only when the panel is released. Webshell signatures are the textbook case for out-of-band updates — a new obfuscation family is worth pushing the day it is seen, not the next release.

This matters more than it used to. The container image now builds without ClamAV by default (ARG INSTALL_CLAMAV=false — see the Dockerfile), and ClamAV was the component with a self-updating signature feed via freshclam. In a default container, YARA is the only malware detection, and its rules are frozen at release time.

Operators can already drop custom .yar files into YaraScanService.CUSTOM_RULES_DIR (/var/serverkit/security/yara-custom, real yara CLI required), so the local extension point exists. What is missing is a curated upstream feed that updates itself.

Not built. Noted here so the decision is deliberate rather than forgotten.