Skip to main content

Publishing API

This page documents the authenticated server API and the verified glxdev publisher flow. CLI commands below match glxdev 0.1.0 in the local development source; treat them as an unreleased preview and check glxdev version and glxdev help before use.

Publisher setup (CLI preview)

Set the Auth0 values shown by glxdev help and set GLIXO_PUBLISHER_ROOT_PUBKEY to the trusted raw base64 Ed25519 public key supplied by Glixo. This is a public verification key; the root private key is never passed to the CLI.

glxdev auth login
glxdev publisher key create
glxdev publisher key register
glxdev pack --project ./example-provider --output ./release
glxdev verify --project ./release
glxdev publisher certificate import --file ./publisher-certificate.json
glxdev publish --project ./release

The API has no certificate issue or retrieval route. A Glixo publisher operator issues a root-signed certificate out of band, bound to the registered publisher account and CLI public key. The import file has this shape:

{
  "cert": {
    "publisherId": "pub_example",
    "publicKey": "<raw Ed25519 public key, base64>",
    "gitUrl": "https://example.com/source",
    "issuedAt": "2026-09-24T00:00:00.000Z",
    "expiresAt": "2027-09-24T00:00:00.000Z"
  },
  "certSignature": "<Glixo root signature over canonicalPublisherCert(cert), base64>"
}

Send POST /v1/extensions/publish with a bearer token. The envelope contains the validated manifest, release channel, publisher signature, and inline package bytes. The API accepts dev, stable, beta, and canary channels.

Request and response

The manifest lists each artifact RID, SHA-256 digest, and source URL. For an inline upload, include one artifact payload for every manifest RID. The release signature covers the extension id, version, artifact RIDs and digests, and channel.

{
  "manifest": {
    "id": "com.example.provider",
    "name": "Example Provider",
    "version": "0.1.0",
    "channel": "stable",
    "runtime": { "kind": "wasm-component", "version": "glixo:llm/provider-compat@2.0.0" },
    "capabilities": ["diagnostics"],
    "requires": [],
    "permissions": ["http.client"],
    "components": [{ "id": "provider", "cell": "server", "runtime": "wasm-component", "world": "glixo:llm/provider-compat@2.0.0" }],
    "artifacts": [{ "rid": "any", "sha256": "<64 lowercase hex digest>", "url": "package.zip" }]
  },
  "channel": "stable",
  "signature": {
    "canonicalizationVersion": 1,
    "keyId": "ed25519:<32 lowercase hex characters>",
    "alg": "ed25519",
    "value": "<release signature, base64>",
    "cert": { "publisherId": "pub_example", "publicKey": "<base64>", "gitUrl": "https://example.com/source", "issuedAt": "2026-09-24T00:00:00.000Z", "expiresAt": "2027-09-24T00:00:00.000Z" },
    "certSignature": "<root signature, base64>"
  },
  "artifacts": [{ "rid": "any", "contentBase64": "<base64 of package.zip>", "contentType": "application/zip" }]
}

The handler decodes and hashes the exact uploaded bytes, checks them against the manifest digests, and caps total artifact bytes at 8 MiB. Base64 expands the request body, so an HTTP gateway may enforce a lower effective inline-upload limit.

Browser dashboard status: The dashboard can import a root-issued certificate for its non-exportable browser key and verifies the certificate signature, validity dates, publisher account, registered key, and active key status before enabling Sign & publish. Configure the public Ed25519 root key at build time as VITE_GLIXO_PUBLISHER_ROOT_PUBKEY (raw base64). The key is public and is embedded in the bundle; trust depends on the protected release build supplying the expected Glixo root and matching the API's GLIXO_PUBLISHER_ROOT_PUBKEY. This checkout does not set or wire the browser value into CI, so publishing stays disabled until the deployment owner provisions it as trusted build configuration. Certificate issuance stays out of band with a Glixo publisher operator.

A completed request returns HTTP 201 and the published catalog record. The response includes the normalized artifact URLs and publisher trust result:

{
  "ok": true,
  "id": "com.example.provider",
  "version": "0.1.0",
  "channel": "stable",
  "publicationId": "pub_<32 lowercase hex characters>",
  "publicationStatus": "complete",
  "catalogUrl": "https://api.glixo.dev/v1/extensions/com.example.provider",
  "artifacts": [{ "rid": "any", "url": "artifacts/com.example.provider/0.1.0/any.zip", "sha256": "<64 lowercase hex digest>", "size": 1234, "contentType": "application/zip" }],
  "publisherId": "pub_example",
  "signature": { "canonicalizationVersion": 1, "keyId": "ed25519:<32 lowercase hex characters>", "alg": "ed25519", "verified": true, "verification": "glixo_root_certificate_verified", "cert": { "publisherId": "pub_example", "publicKey": "<base64>", "gitUrl": "https://example.com/source", "issuedAt": "2026-09-24T00:00:00.000Z", "expiresAt": "2027-09-24T00:00:00.000Z" }, "certSignature": "<root signature, base64>" }
}

If publication finalization is pending, the handler returns HTTP 202 with publicationStatus: "finalizing" and a message explaining that catalog propagation will retry automatically. A repeat of the unchanged request resumes the existing publication.

Trust and revocation

The API verifies the certificate against GLIXO_PUBLISHER_ROOT_PUBKEY, checks publisher and active-key binding plus its validity window, and verifies the release signature. Missing root configuration or an invalid certificate fails closed. Catalog reads re-project trust from the stored certificate and signature; certificate expiry makes the entry non-installable.

Revoking a publisher key blocks new publications signed by that key. It does not retroactively revoke existing releases; those remain trustable under their certificate until it expires or the release is separately withdrawn through catalog policy. Do not upload protocol-v0 ZIPs or re-sign them as VNext.

Package permissions and account configuration are reviewed by the host; declarations do not grant authority. See Providers and host ownership for the supported Rust WASM LLM compat path.