Skip to content

Publish and pull an agentspace

Agentspaces can be packaged as OCI artifacts, signed with cosign, and promoted through environments the same way you promote container images. This guide walks through publishing an agentspace and pulling it into another runtime.

  • Install alquimia-core[registry].
  • Have access to an OCI registry (GHCR, Docker Hub, ECR, Harbor, or a private ORAS registry).
  • Optionally install cosign if you want signed artifacts.
  1. Create or load the agentspace locally.

    Terminal window
    alquimia registry create --name production
    alquimia registry agents add support-bot.json --namespace production

    As of alquimia-core 0.5.3, registry create no longer has a --namespace flag; -n / --namespace consistently means the agentspace name on every other command. As of alquimia-core 0.5.5, agentspace names must be valid OCI name components; consecutive separators are rejected.

  2. (Recommended) classify tools and topics before publishing.

    Unsigned, unclassified tools are denied under the default Zero Trust policy when the agentspace is pulled into a production runtime.

    Terminal window
    alquimia registry tools add filesystem-tools \
    --provider-id mcp \
    --connection-config '{"url": {"$secretRef": "FILESYSTEM_MCP_URL"}}'
    alquimia registry tools set-operation filesystem-tools "list_*" \
    --match glob --severity read-only --tier-grants reader,editor,operator
  3. Publish to the OCI registry.

    Terminal window
    export ALQUIMIA_OCI_REGISTRY_DEFAULT=ghcr.io
    export ALQUIMIA_OCI_NAMESPACE_AGENTSPACES=agents
    alquimia registry publish --namespace production --tag v1.0.0

    As of alquimia-core 0.5.3, the OCI path is derived from the deployment namespace (<registry>/<ALQUIMIA_OCI_NAMESPACE_AGENTSPACES>/<name>), not from agentspace metadata. The example above publishes to ghcr.io/acme/agents/production:v1.0.0 when the active Docker/OCI login is for ghcr.io/acme.

    Add --include-secrets to also publish secret metadata (key, scope, dtype, required). Secret values are never included. Add --force to take over a tag that was last published by someone else. As of alquimia-core 0.5.5, you can also use --target <repo_id> to push to a specific OCI repository, --include-agents <ids> to publish only selected agents, and --exclude-agents <ids> to omit selected agents. alquimia registry unpublish accepts --target as well.

    Publish to an alternate repository with --target, or publish only a subset of agents with --include-agents and --exclude-agents:

    Terminal window
    alquimia registry publish --namespace production --tag v1.0.0 \
    --target ghcr.io/acme/agents/production
    alquimia registry publish --namespace production --tag v1.0.0 \
    --include-agents onboarder,closer \
    --exclude-agents deprecated-bot

    When you publish a subset of agents, only those agents and the resources they reach (tools, topics, files, models, brains, parameters, and secrets) are included.

  4. Verify the manifest in the registry.

    Terminal window
    alquimia explore tags --repository ghcr.io/acme/agents/production

    With ALQUIMIA_OCI_INDEX_ENABLED=true, you can also browse the deployment catalog:

    Terminal window
    alquimia registry explore catalog --registry ghcr.io/acme
    alquimia registry explore entry ghcr.io/acme/agents/production:v1.0.0

If cosign is installed and ALQUIMIA_OCI_COSIGN_KEY is set, publish signs the artifact automatically. For keyless signing, set the certificate identity and issuer instead:

Terminal window
export ALQUIMIA_OCI_COSIGN_CERT_IDENTITY=alice@acme.com
export ALQUIMIA_OCI_COSIGN_CERT_OIDC_ISSUER=https://accounts.google.com

The signature is verified on every pull according to ALQUIMIA_OCI_SIGNATURE_POLICY:

PolicyBehaviour
required (default)Abort on missing or invalid signature
warnLog a warning and continue on failure
offSkip verification

On the target runtime:

  1. Authenticate to the registry if needed (oras login or docker login). ORAS and cosign read credentials from the Docker config ($DOCKER_CONFIG/config.json, default ~/.docker/config.json).

  2. Set the signature verification policy.

    Terminal window
    export ALQUIMIA_OCI_SIGNATURE_POLICY=required
    export ALQUIMIA_OCI_COSIGN_PUBKEY=/etc/alquimia/cosign.pub

    Verification uses ALQUIMIA_OCI_COSIGN_PUBKEY; ALQUIMIA_OCI_COSIGN_KEY is the signing key and only works as a fallback for KMS/env:// references. With required and no key or keyless identity configured, every pull fails. Use the exact lowercase value required: in alquimia-core ≤ 0.5.6 other spellings such as Required behave like warn.

  3. Pull the artifact.

    Terminal window
    alquimia registry fetch --namespace production \
    --target ghcr.io/acme/agents/production --tag v1.0.0

    fetch without --tag overwrites the workspace dist.json; with --tag it caches the versioned snapshot instead. Pulling rehydrates local knowledge bases from the file registrations contained in the artifact.

Run a specific version without overwriting the workspace

Section titled “Run a specific version without overwriting the workspace”

Introduced in alquimia-core 0.5.2, registry fetch pulls an OCI tag into a cached versioned snapshot instead of overwriting the workspace dist.json. You can then run agents from that snapshot directly.

  1. Fetch a versioned snapshot.

    Terminal window
    alquimia registry fetch --namespace production --tag v1.0.0

    Add --no-cache to force a fresh pull from OCI.

  2. List cached versions.

    Terminal window
    alquimia registry versions --namespace production
  3. Run an agent from the snapshot.

    Terminal window
    alquimia local exec production/support-bot:v1.0.0 "What is the refund policy?"
  4. Remove the cached snapshot when no longer needed.

    Terminal window
    alquimia registry flush-version --namespace production v1.0.0

    As of alquimia-core 0.5.5, flush-version also cleans up the <tag>/... blob copies created for the versioned snapshot.

This is useful for testing a release before promoting it, running older snapshots side-by-side, or reproducing a past inference result without changing the live workspace.

If ALQUIMIA_REGISTRY_KEY is set on the source runtime, the local TinyDB files stay encrypted. The OCI artifact itself is published as plaintext JSON so the target runtime does not need your AES key to consume it. The target runtime can encrypt its own local copy with a different key if desired.

A typical promotion flow looks like this:

dev agentspace ──publish──► ghcr.io/acme/agents/production:v1.0.0-dev
│
▼
staging agentspace ◄──fetch── validate / test
│
▼
production agentspace ◄──fetch── approve and tag v1.0.0

Use immutable tags for releases and keep a latest tag only for development. Record the OCI digest in your change-management system so audits can correlate a running agent to the exact artifact it came from.

Migrating artifacts published before 0.5.3

Section titled “Migrating artifacts published before 0.5.3”

Artifacts published before alquimia-core 0.5.3 lived at <registry>/<metadata-namespace>/<name>. To move one to the new deployment-owned namespace without changing its digest (and therefore without invalidating signatures or cached versions):

Terminal window
alquimia registry index migrate -n production

This copies the artifact with oras cp, runs cosign copy for any classic signature tag, updates the local agentspace’s target_repo_id, and never deletes the source. Verify with cosign verify at the destination, then run alquimia registry index reindex to advertise it in the namespace index.

SymptomCauseFix
signature verification failedCosign key mismatch or missing signatureVerify the correct public key or set policy to warn only in dev
manifest schema version mismatchArtifact was not produced by Alquimia PlatformCheck the registry repository and tag
unrecognized media typeLayer from a newer/older Alquimia Platform versionUpgrade or downgrade alquimia-core to match
publish refused: tag already exists with a different authorAnother agentspace shares the same nameUse a unique name, or pass --force if you are reclaiming the tag
explore catalog returns empty with required policyIndex entries are unsignedConfigure cosign signing or set ALQUIMIA_OCI_SIGNATURE_POLICY=warn
index attach failed warning after publishRegistry lacks native OCI 1.1 referrers supportUse a referrers-capable registry (zot/Harbor), or set ALQUIMIA_OCI_REFERRERS_FALLBACK=warn and accept the risk
oras push failed with stderr and target referenceORAS could not reach the registry or the push was rejectedCheck the target reference, registry credentials, and network reachability; the error includes the full oras stderr
pull refused: local registry is read-onlyWorker pod cannot writeRun pull against the master instance (PUT /registry/pull); do not switch workers to master mode, because only one master may write the registry