Publishing is VCS-only: module versions are ingested from an approved GitHub repository when a semver tag is pushed. There is no direct tarball upload in this release.
Link a repository
Create a module and link a repository from the organization’s GitHub App installation:
POST /v1/registry/modulesCreation requires registry:write plus vcs:read, and an
Idempotency-Key like every state-changing v1 operation. The repository
must belong to an active installation of the same organization.
| Field | Constraint |
|---|---|
name |
Lowercase letters, digits, and interior hyphens; 1–64 characters |
system |
The provider target; lowercase letters and digits, 1–32 characters |
| Repository | One module per repository |
A module publishes the repository root. Module subdirectories and monorepos
of modules are not supported in v1, so each repository can back exactly one
module and tag webhooks route unambiguously. The repository link can be
replaced later with PUT /v1/registry/modules/{module_id}/source, which
additionally requires vcs:admin.
Publish by pushing tags
Pushing a semver tag to the linked repository publishes a version:
v1.2.3and1.2.3are both accepted; the stored version drops the optionalv;- prerelease tags such as
v2.0.0-rc.1are allowed; and - non-semver tags are ignored silently.
The signed GitHub webhook records the tag and the exact commit it pointed at, then a durable ingestion downloads the archive at that commit, validates it, and commits the version with its archive SHA-256. The version appears in the registry shortly after the push, with its repository, tag, commit SHA, and digest recorded permanently. If the tag moves between delivery and ingestion, the ingestion fails rather than publishing ambiguous bytes; re-tagging produces a new ingestion attempt.
Archives are subject to the platform archive limits: 100 MB compressed,
500 MB expanded, and 50,000 entries, with links and unsafe paths rejected. A
root README.md up to 1 MiB is stored and shown as plain preformatted text.
Ingestion history — including failure codes for rejected tags — is visible
on the module page and through
GET /v1/registry/modules/{module_id}/ingestions.
Sync tags
POST /v1/registry/modules/{module_id}/actions/syncSync lists the repository’s tags, filters to semver, and enqueues ingestions for versions that are not yet published, newest 50 per invocation. Use it to backfill existing tags when a repository is first linked, and to recover versions whose webhook delivery was missed.
Immutability
A published version never changes. Re-publishing an existing version with different bytes is rejected and recorded as an integrity-violation audit event; re-publishing with identical bytes converges idempotently without creating a new version. Consumers that pin a version therefore always receive the same digest-verified package.
Deprecate and restore
POST /v1/registry/module-versions/{version_id}/actions/deprecate
POST /v1/registry/module-versions/{version_id}/actions/restoreDeprecation takes a reason of up to 512 characters. A deprecated version keeps resolving for existing pins and stays in the version listing, but the dashboard and management API flag it with its reason. Restore returns the version to published. Individual versions cannot be deleted.
Delete a module
DELETE /v1/registry/modules/{module_id}Deletion removes the module and every version from discovery and download. It is audited with the version count. Stored packages are removed asynchronously after the rows are gone; there is no partial state in which a deleted module still resolves.
Permissions
| Permission | Grants | Default roles |
|---|---|---|
registry:read |
Browse, resolve, and download modules | All members; managed plan credentials |
registry:write |
Create, link, sync, deprecate, restore, delete | Owners and admins |
Audit events
Registry activity is recorded in the organization audit inventory:
registry.module.created,registry.module.source_updated, andregistry.module.deleted;registry.module.version_published,registry.module.version_deprecated, andregistry.module.version_restored;registry.module.version_downloaded, deduplicated per credential and version within one hour;registry.module.integrity_violation; andregistry.module.sync_requested.
Payloads carry public IDs, versions, and digests — never tokens or archive contents.
Related pages
- Module registry — addresses, consuming, and credentials
- GitHub source connections — the GitHub App installation
- Audit events
- v1 REST API — idempotency and request rules