Sign and publish

How-toUpdated 3 min read
View as Markdown
On this page

How your package gets from your machine to market.opvs.ai.

What publish does

 your machine                                market.opvs.ai
 ────────────                                ──────────────
 1 validate manifest (same rules as server)
 2 load your ed25519 key → fingerprint
 3 pack → SHA-256 → sign the digest
 4 ─────────────────── POST /api/v1/bundles/upload-url ──▶ upload URL
 5 ─────────────────── PUT the tarball ─────────────────▶ bundle storage
 6 ─────────────────── POST /api/v1/registry/packages ──▶ verify signature
                                                          check certificate is active
                                                          validate manifest
                                                          run the security review
                                                          → published, or 422 + findings

You need

Step 1: dry run

export OPVS_SIGNING_KEY="<your base64url private key>"   # from your CI secret
opvs-skills publish ./my-package --dry-run --private-key @env:OPVS_SIGNING_KEY

No network call, no partner key. Green means the manifest is right and the bundle signs.

Step 2: publish

export OPVS_MARKETPLACE_ADMIN_KEY="<your partner key>"
opvs-skills publish ./my-package \
  --private-key @env:OPVS_SIGNING_KEY \
  --api-url https://market.opvs.ai

Flag

What

Notes

--private-key

your ed25519 signing key

a file path, an inline base64url string, or @env:NAME

--api-url

the registry

always pass https://market.opvs.ai. The CLI's own default points at a local development address.

--admin-key

your partner key

or set OPVS_MARKETPLACE_ADMIN_KEY

--dry-run

preflight only

validate and sign, no upload

On success the CLI prints the version, bundle_sha256, the bundle URL and your certificate fingerprint.

Step 3: check it is live

curl -s "https://market.opvs.ai/api/v1/registry/packages/@acme/leads" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['version'], d['status'], d['tier'], d['security_score'])"
# expect: your new version, published, the tier you declared, a score near 100

In CI

# GitHub Actions example
env:
  OPVS_MARKETPLACE_ADMIN_KEY: ${{ secrets.OPVS_PARTNER_KEY }}
  OPVS_SIGNING_KEY: ${{ secrets.OPVS_SIGNING_KEY }}
steps:
  - uses: actions/checkout@v4
  - run: npm install -g @opvs-ai/skills
  - run: opvs-skills publish ./my-package --private-key @env:OPVS_SIGNING_KEY --api-url https://market.opvs.ai

Things to know before you publish

  • A published version cannot be replaced. (vendor, name, version) is permanent. To change anything, bump the version. See Versions and trust tiers.

  • Publishing delivers. Workspaces that installed your package on a latest or range pin receive the new version automatically, within a day. Treat every publish as a release.

  • The tier is in the manifest. beta (the default) is visible to customers immediately; internal keeps a version hidden while you test.

Common refusals

Message (shortened)

Cause

Fix

extra fields not permitted

an unknown top-level key

remove or correct it

scope must match "@"+vendor

name and vendor disagree

make them agree

version must be valid SemVer

v1, 0.1

use 0.1.0

409 version … is already published

you republished a version

bump the version

must declare skills / inbound_events / peer_dependencies

empty package

declare at least one

provider_config requires base_url_env or upstream

missing

add one, even for guidance-only skills

entitlement.unknown

an unknown entitlement

use a known name or vendor.<you>.<surface>.<verb>

403

partner key missing, revoked or for another vendor

check the key and the scope

422 with findings

a blocking security-review finding

see Security review

Next

Security review.

Did this answer your question?