Package Registries¶
Skill and plugin installs resolve through a pluggable multi-registry engine you control entirely from config.yaml — including running your own registry with one subcommand.
Quick start¶
# config.yaml
registries:
- id: main
type: http
base_url: https://registry.example.com
priority: 10
auth_headers:
Authorization: "Bearer sk_..."
signing_key: "3b6a27bc…" # hex ed25519 public key
- id: skills.sh
type: skillssh
base_url: https://skills.sh
priority: 50
- id: github
type: git
priority: 100
sy skill install some-skill # resolved via main → skills.sh → git
sy skill install vercel-labs/skills/find-skills # skills.sh id
sy skill install github.com/user/my-skill # addressed git source
With no registries: block at all, a bare git provider still resolves
addressed sources, so git installs work out of the box.
Resolution: priority and fallback¶
Registries are queried in ascending priority (lower first; ties keep
config order). Resolve returns the first hit; not found and transport
errors both fall through to the next registry, so one broken registry never
blocks installs from the others. Search aggregates every registry and
dedupes by slug, keeping the highest-priority result.
Unknown type: values are warned and skipped at boot — a typo never bricks
the gateway.
Built-in registry types¶
http — Soulacy package registry¶
Speaks the registry protocol:
| Endpoint | Returns |
|---|---|
GET {base}/v1/search?q={query} |
{"packages": […]} |
GET {base}/v1/packages/{slug} |
package metadata with checksum + source (404 = unknown) |
GET {pkg.source} |
the archive (tar.gz/zip), sha256-verified, ≤ 256 MiB |
auth_headers are sent verbatim on every request — use them for bearer
tokens against private registries. A sha256 checksum is required for
every archive; unverifiable archives are refused. Extraction goes through
the same hardened path as plugin installs (path-traversal and
decompression-bomb guards).
git — git hosts¶
Resolves addressed sources only: github.com/user/my-skill, full
https://… URLs, or git@… remotes. Plain slugs fall through to real
registries. Fetch is a shallow clone with .git stripped (120 s timeout);
integrity comes from the clone, so there is no checksum. Search returns
nothing — git hosts are not an index.
skillssh — skill directories¶
Speaks the skills.sh directory API: search, full file trees inline, and
partner security audits (GET /api/v1/skills/audit/{id}) that are surfaced
in the install consent prompt. Slugs are skills.sh ids
(owner/repo/skill). Soulacy's own
safety introspection still runs on every install.
See Skill Sources for the guided
sy registry probe/add flow to add any of these from a URL.
Package signatures (ed25519)¶
Registry operators sign the raw 32 bytes of each archive's sha256 digest with an ed25519 private key; packages carry the signature base64-encoded. Consumers pin the operator's 32-byte public key (hex-encoded) per registry:
Pin signing_key on every http registry you can
With signing_key set, every package from that registry must carry
a valid signature — unsigned or tampered packages are refused at fetch,
before extraction. Without it, integrity rests on the sha256 checksum
alone and the CLI marks signatures as UNVERIFIED in the install
output. Malformed keys fail at boot, not at first fetch.
Running your own registry¶
The reference server ships as a soulacy subcommand and needs no gateway
config:
soulacy registry keygen --out ~/.soulacy/registry-signing.key # prints the public key
soulacy registry serve --dir ./packages --addr 127.0.0.1:18790 \
--signing-key-file ~/.soulacy/registry-signing.key
Layout is a flat directory of archives:
packages/
my-skill-1.0.0.tar.gz # <slug>-<version>.tar.gz (also .tgz / .zip)
my-skill-1.1.0.tar.gz
my-skill.yaml # optional sidecar: description: metadata
- The newest version per slug (numeric dotted compare) is what resolve returns.
- Checksums are computed at index time; every package is signed when a key is configured.
- Archive serving is traversal-guarded — only indexed basenames are reachable.
Hand the printed public key to consumers as the signing_key for their
registry entry, then point them at it:
registries:
- id: team
type: http
base_url: http://127.0.0.1:18790
priority: 10
signing_key: "<public key from keygen>"
Custom registry providers¶
Flavored binaries can ship additional registry types (S3, IPFS, your
artifact store) by registering a factory with the SDK and selecting it via
type: in a registries: entry — see
Custom Distributions. The full provider
contract lives in the registry spec.