Skip to main content

Plugin Development Guide

Version française : ../../fr/guides/plugin-development.md

This guide shows how to build, validate, sign, publish, install, upgrade and remove a plugin. It is for developers with the developer or tenant_admin role; installing in an environment needs tenant_admin and an approval.

Concept​

A manifest of kind Plugin (contracts/v1/plugin-manifest.schema.json) has two formats:

FormatWhat it isWhere it goes
packA complete Marketplace pack: agents, skills, prompts, MCP servers, connectors, policies, evaluations, tests and docs in English and French.Published to the Marketplace with enterprise-ai plugin publish, installed through POST /v1/marketplace/installations after a preflight and an approval. POST /v1/plugins refuses it with 422 pack_requires_marketplace.
oci_plugin (default)One signed OCI image with declared capabilities, run in a sandbox.Registered with POST /v1/plugins, installed with POST /v1/plugins/{name}/install.

A plugin goes through the statuses registered, installing, installed, failed, uninstalled and blocked.

Manifest fields​

FieldTypeRequiredDescription
apiVersion, kind, metadatayesenterprise-ai.io/v1, Plugin, name, version (semver), owner.
spec.descriptionstringyesWhat the plugin brings.
spec.capabilitiesarrayyesEach item: type (tool, connector, channel, model_adapter, evaluator, ui_extension, policy) and name.
spec.formatenumnooci_plugin or pack.
spec.artifactobjectoci_pluginoci_ref, digest (sha256:<64 hex>), media_type.
spec.signatureobjectoci_plugindigest, cosign_bundle, signer, issued_at.
spec.sandboxobjectoci_pluginruntime (gvisor, kata, wasm, none), network (deny_all, egress_allowlist, cluster_only), egress_allowlist, read_only_rootfs, limits.
spec.permissions, spec.min_platform_versionnoPermissions and minimum platform version of an OCI plugin.
spec.license, spec.licenseDeclarationstring, objectpackSPDX identifier; another licence than MIT or Apache-2.0 needs a declaration (spdx, reason).
spec.compatibilityobjectpackplatform and sdk ranges such as >=1.0.0 <2.0.0.
spec.requestedPermissionsarraypackscope, reason, sensitive, classification; the administrator grants a subset.
spec.dataProtectionobjectpackclassification_max, pii, residency.
spec.approvalsobjectpackinstall.quorum (1 to 10) and roles.
spec.docsobjectpackPaths of the en and fr docs.
spec.evaluations, spec.testsarraypackEvaluation suites (promptfoo, ragas, ...) and test suites (unit, integration, authz, security, opa).
spec.dependenciesarraynoname, version range, optional.
spec.configSchemaobjectnoJSON Schema of the installation configuration.
spec.domain, spec.namespace, spec.category, spec.publisher, spec.displayName, spec.security, spec.layout, spec.signedArtifact, spec.testFlagsnoCatalogue and security metadata of a pack.

Lifecycle​

enterprise-ai plugin covers create, validate, build, sign, publish and install of a Marketplace pack; the manifest follows contracts/v1/plugin-manifest.schema.json. Pack details are in the pack development guide.

enterprise-ai plugin create ./crm-pack --domain sales-crm --name crm-pack
enterprise-ai plugin validate ./crm-pack
enterprise-ai plugin build ./crm-pack --out dist
enterprise-ai plugin sign ./crm-pack --out dist --key cosign.key --signer acme
enterprise-ai plugin publish ./crm-pack --out dist --key cosign.key

build, sign and publish take the pack folder: the archive is rebuilt, reproducibly, in the --out folder (by default dist inside the pack).

Steps​

  1. Create the pack. The scaffold is runnable and passes every gate. In the portal, the manifest of an OCI plugin is written in Developer Studio > Plugin builder.

    enterprise-ai plugin create ./crm-pack --domain sales-crm --name crm-pack

    --domain: one of banking, cybersecurity, document-intelligence, finance, hr, it, legal, marketing, procurement, risk-compliance, sales-crm, support.

    Expected result: the created files are listed.

    If it fails: exit code 1 means the folder exists; add --force.

  2. Edit the manifest. Fill plugin.yaml: requested permissions with a reason each, data protection, approvals, compatibility. See the pack development guide for each folder.

    Expected result: every scope used by an agent, a skill or a tool of the pack is requested.

    If it fails: the next step lists the missing or unsafe permissions.

  3. Validate. The same checks run again on the Control Plane at publication and installation.

    enterprise-ai plugin validate ./crm-pack

    Expected result: the pack is reported valid with its name and version.

    If it fails: exit code 1 lists each error of the layout and of the manifest.

  4. Build and sign. build writes the reproducible archive, its SHA-256 digest and an SPDX SBOM. sign signs the archive digest and the digest of every SKILL.md, and writes the descriptor <name>-<version>.pack.json next to the archive.

    enterprise-ai plugin build ./crm-pack --out dist
    enterprise-ai plugin sign ./crm-pack --out dist --key cosign.key --signer acme

    acme: the publisher name registered in the Marketplace.

    Expected result: the digest, the signer and the number of signed skills are printed.

    If it fails: exit code 2 with "--key and --signer are required".

  5. Publish. publish runs the pack tests, the evaluations and the scan, stops on a failed gate, optionally pushes to an OCI registry with --oci, then calls POST /v1/marketplace/packages.

    enterprise-ai plugin publish ./crm-pack --out dist --key cosign.key --oci <harbor-host>/packs/crm-pack

    Expected result: the package version is returned by the Marketplace.

    If it fails: exit code 1 names the failed gate; an unsigned archive is refused before any call.

  6. Install. plugin install sends POST /v1/marketplace/installations: the preflight runs, then an approval marketplace.install is opened (quorum 2 when a sensitive permission is granted or in prod). Once approved, POST /v1/marketplace/installations/{installation_id}/apply creates the objects and runs a smoke test.

    enterprise-ai plugin install crm-pack --version 1.0.0 --env staging --grant crm.records.read

    Expected result: the approval id and the quorum are printed.

    If it fails: 403 permission_unsafe, 422 config_invalid, 422 permission_not_requested, 409 package_suspended or 422 preflight_failed.

  7. Register and install an OCI plugin. POST /v1/plugins verifies the signature of the image and records it; POST /v1/plugins/{name}/install renders the sandboxed deployment and its network policy. In the portal: Developer Studio > Plugin builder > Test > Read the status (GET /v1/plugins/{name}/status).

    Expected result: status installed, verified: true and the runtime_class of the sandbox.

    If it fails: 403 plugin_unsigned, 403 plugin_blocked, 422 invalid_manifest.

  8. Upgrade or roll back. Raise metadata.version, publish, then POST /v1/marketplace/installations/{installation_id}/upgrade; POST /v1/marketplace/installations/{installation_id}/rollback restores the previous version. An OCI plugin is updated with POST /v1/plugins while it is not installed.

    Expected result: the installation runs the new version after its approval and smoke test.

    If it fails: 409 installation_state, 409 rollback_unavailable, 422 smoke_failed (the current version stays), 409 plugin_installed for an OCI plugin still installed.

  9. Suspend or remove. POST /v1/marketplace/installations/{installation_id}/status suspends or resumes an installation; POST /v1/marketplace/installations/{installation_id}/uninstall removes every object it created. An OCI plugin is removed with POST /v1/plugins/{name}/uninstall.

    Expected result: status suspended or uninstalled.

    If it fails: 409 installation_state or 409 plugin_not_installed.

Installation​

POST /v1/plugins registers a plugin, POST /v1/plugins/{name}/install installs it; on the Marketplace side, POST /v1/marketplace/preflight checks capabilities and configuration before POST /v1/marketplace/installations. See the Marketplace guide.

client.plugins.install("sap-connector-pack")

Troubleshooting​

SymptomCauseFix
422 pack_requires_marketplaceA format: pack manifest was sent to POST /v1/plugins.Publish it with enterprise-ai plugin publish and install it from the Marketplace.
422 invalid_manifestOCI digest differs from artifact.digest, egress_allowlist missing, or invalid sandbox limits.Fix the field named in details.
403 plugin_unsignedThe signature of the image is not verified at install.Sign the image and register it again.
403 plugin_blockedThe plugin is blocked.Ask a security_officer why; publish a fixed version.
409 plugin_installedUpdate of an OCI plugin that is installed.Uninstall it first.
409 plugin_not_installedUninstall of a plugin that is not installed.Read GET /v1/plugins/{name}/status.
422 preflight_failedA preflight check failed.Run POST /v1/marketplace/preflight and read every check.
403 permission_unsafeThe pack requests an unsafe scope.Remove the scope from requestedPermissions.
422 smoke_failedThe smoke test failed after apply.The installation was rolled back; fix the pack and publish a new version.
409 marketplace_version_existsThe version is already published.Raise metadata.version.

Next steps​