Skip to main content

Skill Development Guide

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

This guide shows how to write, sign, publish, load, version and retire a skill. It is for developers with the developer or tenant_admin role; changing the status of a skill needs tenant_admin or security_officer.

Concept​

A skill is a set of instructions (its SKILL.md) and an optional entrypoint that an agent loads at run time. The Skill Registry stores the manifest, the content and its SHA-256 digest; the Skill Loader hands the skill to an agent only when the digest matches, the signature is verified, the agent lists the skill in spec.skills and the agent was granted every scope of the skill. A skill is data for the model: it never replaces a permission check.

The statuses are draft, approved, restricted, deprecated and blocked. A verified skill becomes approved at registration; an unverified one stays draft.

Manifest fields​

The manifest follows contracts/v1/skill-manifest.schema.json.

FieldTypeRequiredDescription
apiVersion, kindstringyesenterprise-ai.io/v1 and Skill.
metadata.name, metadata.version, metadata.ownerstringyesDNS like name, semver version, accountable owner.
spec.descriptionstringyesWhen the agent should use the skill.
spec.instructionsstringyesThe SKILL.md content stored inline.
spec.entrypointstringnoCode entrypoint when the skill ships code.
spec.dependenciesarraynoEach item: ref, version, optional.
spec.permissionsobjectyesdata_classification_max (required), scopes, network (boolean), filesystem (none, read, write).
spec.artifactobjectnooci_ref or git_ref, and digest (sha256:<64 hex>), required for a Git or OCI artifact.
spec.signatureobjectnodigest (required), cosign_bundle, signer, issued_at.
spec.compatible_runtimesarraynoRuntimes the skill was tested with.

Create a skill​

A skill is described by a skill.yaml manifest (contracts/v1/skill-manifest.schema.json) and its SKILL.md; enterprise-ai create skill writes them and validates the manifest.

enterprise-ai create skill invoice-reader
enterprise-ai validate -f invoice-reader/skill.yaml

Steps​

  1. Create the skill. The command writes skill.yaml and SKILL.md, then validates the manifest against the v1 contract. In the portal: Developer Studio > Skill studio > New.

    enterprise-ai create skill invoice-reader

    Expected result: the two files are listed and the manifest is marked valid against skill-manifest.

    If it fails: exit code 1 with "exists" means the files are already there; add --force or pick another name.

  2. Write the instructions and the permissions. Describe in SKILL.md when to use the skill, its steps and the tools it relies on. Set spec.permissions.scopes and data_classification_max to what the skill really needs: the loader refuses it to an agent that was not granted these scopes.

    Expected result: SKILL.md and spec.instructions say the same thing.

    If it fails: an agent whose data_classification_max is above the one of the skill gets 403 skill_permission_denied at load time.

  3. Validate the manifest. Offline check against the contract. In the portal: Validate on the server.

    enterprise-ai validate -f invoice-reader/skill.yaml

    Expected result: exit code 0.

    If it fails: exit code 1 lists the invalid fields.

  4. Compute the digest and sign. publish skill computes the SHA-256 digest of the folder, writes it in spec.artifact.digest and spec.signature.digest, and with --sign signs with cosign sign-blob. Run it first with --dry-run to see the manifest that will be sent.

    enterprise-ai publish skill ./invoice-reader --sign --key cosign.key --dry-run

    cosign.key: your cosign key file or a KMS reference.

    Expected result: the digest sha256:... is printed, then the manifest in YAML.

    If it fails: a warning says that cosign is missing; install it or publish unsigned (the skill will stay draft and cannot be loaded).

  5. Publish. Without --dry-run the command calls POST /v1/skills. In the portal: Save as a new version.

    enterprise-ai publish skill ./invoice-reader --sign --key cosign.key

    Expected result: apply_status is created or updated, and verified is true.

    If it fails: 422 invalid_manifest with artifact.digest means a Git or OCI artifact without its digest.

  6. Verify the signature. POST /v1/skills/{name}/verify checks the digest and the signature of the stored version again. In the portal: Skill studio > skill > Test > Verify.

    Expected result: verified: true, with method and signer.

    If it fails: reason is digest_mismatch (content changed after signing) or the signature is missing.

  7. Grant the skill to an agent and load it. Add skill:invoice-reader@<version> to spec.skills of the agent, apply the agent, then the runtime calls GET /v1/skills/{name}/load with ?agent=<agent>.

    Expected result: the answer gives digest, signer, instructions, permissions and dependencies.

    If it fails: see the troubleshooting table; each refusal is audited as skill.load with its reason.

  8. Publish a new version. Raise metadata.version, sign and publish again. The stored version is replaced, its verification is run again, and a blocked skill stays blocked.

    Expected result: apply_status is updated.

    If it fails: run step 6 again and read reason.

  9. Restrict, deprecate or block. POST /v1/skills/{name}/status applies draft, restricted, deprecated or blocked at once; approved opens a promotion approval and answers 202, decided with POST /v1/approvals/{approval_id}/decide (Agents > Approvals inbox).

    client.skills.set_status("invoice-reader", "blocked", reason="prompt injection found")

    Expected result: the new status is returned; a blocked or deprecated skill is no longer loaded.

    If it fails: 400 invalid_request for an unknown status.

Sign and publish​

enterprise-ai publish skill checks the signature (cosign sign-blob with --sign) then calls POST /v1/skills; POST /v1/skills/{name}/verify checks the signature again and GET /v1/skills/{name}/load loads the verified skill.

enterprise-ai publish skill ./invoice-reader --sign --key cosign.key --dry-run

Verify from code​

An unsigned skill or one whose signature does not match is never loaded.

client.skills.verify("invoice-reader")

Troubleshooting​

SymptomCauseFix
404 skill_not_foundNo skill with this name in the tenant.Check the name with enterprise-ai get skills.
422 invalid_manifestContract error, or a Git or OCI artifact without artifact.digest.Validate the manifest; publish with enterprise-ai publish skill, which sets the digest.
403 skill_blockedThe skill is blocked or deprecated.Publish a fixed version and ask a tenant_admin to change the status.
409 skill_digest_mismatchThe stored content no longer matches its digest.Sign and publish the content again.
403 skill_unsignedThe signature is missing or not verified.Publish with --sign and a trusted key.
403 skill_not_grantedThe agent does not list the skill in spec.skills.Add the reference to the agent manifest and apply it.
403 skill_permission_deniedThe skill needs a scope the agent lacks, or the agent classification is above the skill one.Align spec.permissions of the skill and of the agent.
400 invalid_requestUnknown status in POST /v1/skills/{name}/status.Use draft, approved, restricted, deprecated or blocked.

Next steps​