OpenWOP openwop.dev

For pack authors

For pack authors.

You're packaging reusable workflow components — node implementations, agent definitions, or chained workflow templates — for other OpenWOP users to consume. This page covers the manifest shape, the signing recipe, the namespace tiers, and how to publish to the canonical registry.

A 73-second narrated film, with English captions. You have made a skill for agents, a pack, and want others to use it. They can know it is really yours because you sign it once with a private key only you hold, like sealing an envelope. The film shows the three shelves a pack can sit on (core, vendor, community), publishing by proposing the pack in public, and the check at install: the pack as you signed it is let in, and a copy with one thing changed is stopped. The small cards show real output from this page's signing recipe and a line from the live registry's discovery document; the proposal card is an illustration.

What a pack is

Hosts consume packs at install time, verify the signature against the publisher's public key, and register the declared types in their node catalog.

Read these first

Namespace tiers

Packs are partitioned into three tiers. The tier is part of the pack identifier; there's no implicit promotion.

core.*
OpenWOP-maintained; canonical baseline
vendor.*
Named vendor; the vendor's own Ed25519 key, listed in the registry's signingKeys[] with permittedNamespaces scoped to vendor.<org>.*
community.*
Open publishing via PR; the publisher's own Ed25519 key, listed in the registry's signingKeys[] with permittedNamespaces scoped to the publisher's community.<publisher>.* names

Sign your tarball

  1. 1Build a deterministic tarball containing your pack.json.
  2. 2Compute the SRI integrity of the tarball.
  3. 3Sign the RFC 8785 (JCS) canonical bytes of that pack.json with your Ed25519 private key — a detached 64-byte signature.
  4. 4Submit the .tgz + the .sig + a version manifest referencing both, with the SRI integrity matching the tarball.

Publish to the canonical registry

  1. 1Fork the repo.
  2. 2Add your pack tarball + signature + manifest under the appropriate namespace tier.
  3. 3Add a row to the registry index via the canonical generator script.
  4. 4Open a PR with the conventional commit prefix feat(registry):.

Common pitfalls

  1. Don't reuse a signing key across publishersEach community.<publisher>.* pack should use a publisher-scoped Ed25519 keypair.
  2. Pin your dependenciesPack-to-pack dependencies are resolved via lockfile; install-time integrity checks fail closed on version drift.
  3. Honor SR-1If your nodes touch secrets, follow the secret-redaction invariant — never put raw secrets in node outputs or event payloads.
  4. Bump majors honestlyA pack version bump that changes node input/output shapes is a breaking change; downstream workflows must be able to pin to the prior major.

The full guide

Everything on this page, in order, with every link.

What a pack is

An OpenWOP pack is a signed tarball containing:

  • A pack.json manifest declaring the pack name, version, and the types it exports.
  • One or more node implementations (runtime.language is javascript, python, go, wasm, wasm-component, or remote — an MCP server the host calls; see Node-pack runtimes).
  • Optional agent manifests (per RFC 0003).
  • A detached Ed25519 signature over the RFC 8785 canonical-JSON bytes of the pack.json inside the tarball (the v2 ed25519-canonical-json scheme).

Hosts consume packs at install time, verify the signature against the publisher's public key, and register the declared types in their node catalog. The host's pack-consumer reference implementation is at examples/hosts/postgres/src/pack-consumer.ts in openwop/openwop-examples. It shows the install-time security check: lockfile parse, SRI integrity, version-drift detection and Ed25519 signature verification.

Read these first

  • Node packs — pack format, manifest schema, dependency resolution, lockfile semantics, signing recipe.
  • Workflow chain packs — composing reusable multi-step workflow templates (RFC 0013).
  • Node-pack runtimes — the runtime languages a host may execute, the WASM ABI, and the MCP registry record for remote packs.
  • Host services — the advertised host.* service surfaces a node pack invokes through ctx.
  • Registry operations — submission, deprecation, yank, key rotation. The registry tree and signing rules are in Packs.
  • agent-manifest.schema.json — agent pack manifest shape (RFC 0003).

Namespace tiers

Packs are partitioned into three tiers. The tier is part of the pack identifier; there's no implicit promotion.

TierPublishing ruleSigning rootExample
core.*OpenWOP-maintained; canonical baselineopenwop-team-1 or openwop-registry-root (both permitted for core.openwop.*)core.openwop.http
vendor.*Named vendor; the vendor's own Ed25519 key, listed in the registry's signingKeys[] with permittedNamespaces scoped to vendor.<org>.*vendor-held keypairvendor.myndhyve.canvas
community.*Open publishing via PR; the publisher's own Ed25519 key, listed in the registry's signingKeys[] with permittedNamespaces scoped to the publisher's community.<publisher>.* namesper-publisher Ed25519 keypaircommunity.openwop-team.demo

Host-private deployments can additionally use private.* — these never enter the public registry.

Sign your tarball

v2 has one signing scheme (per Packs §"Signing"): signing on the version manifest is { keyId, scheme }, and scheme MUST be ed25519-canonical-json. The recipe is:

  1. Build a deterministic tarball containing your pack.json.
  2. Compute the SRI integrity of the tarball.
  3. Sign the RFC 8785 (JCS) canonical bytes of that pack.json with your Ed25519 private key — a detached 64-byte signature.
  4. Submit the .tgz + the .sig + a version manifest referencing both, with the SRI integrity matching the tarball.

A signature over the raw tarball bytes is not a v2 signature; a pack signed that way must be re-signed, not relabeled. A verifier checks the signature against the issuing registry's key for keyId and the pack name against that key's permittedNamespaces.

A reference workflow lives at scripts/build-pack-tarball.mjs in openwop/openwop-registry — you can mine it for the canonical command sequence.

Publish to the canonical registry

The reference registry at packs.openwop.dev has no write API by design. Publishing is via PR against openwop/openwop-registry:

  1. Fork the repo.
  2. Add your pack tarball + signature + manifest under the appropriate namespace tier.
  3. Add a row to the registry index via the canonical generator script.
  4. Open a PR with the conventional commit prefix feat(registry):.

The registry rebuilds on merge. Packs are served under registry/v2/packs/<name>/-/<version>.{json,sbom.json,sig,tgz}. Clients resolve every registry path through the endpoints in .well-known/openwop-registry.json instead of building one.

Publish to a private registry

You can stand up your own OpenWOP registry by serving the discovery doc + the pack URLs over HTTPS. The discovery document is .well-known/openwop-registry.json, defined at Packs §"The registry tree". Hosts that point at your registry will consume your packs identically to the canonical one.

Use cases: tenant-scoped private packs, air-gapped deployments, enterprise compliance ("our packs never leave our network").

Common pitfalls

  • Don't reuse a signing key across publishers. Each community.<publisher>.* pack should use a publisher-scoped Ed25519 keypair.
  • Pin your dependencies. Pack-to-pack dependencies are resolved via lockfile; install-time integrity checks fail closed on version drift.
  • Honor SR-1. If your nodes touch secrets, follow the secret-redaction invariant — never put raw secrets in node outputs or event payloads.
  • Bump majors honestly. A pack version bump that changes node input/output shapes is a breaking change; downstream workflows must be able to pin to the prior major.

Ship a pack.