What you will learn
- How the 6-step registration validation pipeline works
- The SkillManifest v1 schema and how to create a signed manifest
- Static scanner rules and what they detect
- API endpoints for registration, listing, and revocation
- A complete worked example of end-to-end registration
Overview
The Skill Registry manages the full lifecycle of skill manifests — from creation through registration, validation, and revocation. It ensures that only verified, integrity-checked, and statically scanned skills can execute against ISCL Core. Every skill that wants to interact with the ISCL API must first be registered. Registration runs a 6-step validation pipeline that checks schema conformance, cryptographic signature, file integrity, and static analysis before persisting the skill in a SQLite database.Revoked skills are soft-deleted and excluded from active listings but preserved for audit purposes.
| File | Purpose |
|---|---|
packages/registry/src/skill-registry-service.ts | 6-step registration pipeline, CRUD, SQLite persistence |
packages/registry/src/manifest-signer.ts | JCS canonicalization, keccak256 hashing, ECDSA sign/verify |
packages/registry/src/manifest-validator.ts | AJV schema validation against SkillManifestSchema |
packages/registry/src/file-hasher.ts | SHA-256 file hashing and verification |
packages/registry/src/static-scanner.ts | 5 pattern-based scan rules with severity levels |
packages/core/src/api/routes/skills.ts | Fastify API routes for skill registration |
SkillManifest v1 schema
Every skill package includes aSkillManifest JSON document describing its identity, permissions, sandbox constraints, and content-addressed files.
The JSON Schema uses
additionalProperties: false on all objects. No undocumented fields are accepted. AJV runs in strict mode with all errors reported.Creating a manifest
Define skill metadata
Choose a unique name (lowercase alphanumeric with hyphens), declare the publisher identity, and specify the permissions your skill requires:
Hash all skill files
Compute the SHA-256 hash of every source file in your skill package. Hashes must be lowercase hex strings (64 characters, no
0x prefix):Sign the manifest
Signing uses three operations in sequence:The
- Remove the
signaturefield from the manifest object - JCS canonicalize the remaining object (RFC 8785 — deterministic JSON serialization)
- keccak256 hash the canonical JSON bytes
- ECDSA sign the hash with the publisher’s private key
signManifest() function handles the full pipeline: it strips the signature field, JCS-canonicalizes the rest, computes keccak256, and signs using viem/accounts.Registration pipeline
When you submit a manifest toPOST /v1/skills/register, the SkillRegistryService runs a 6-step validation pipeline. Every step must pass for registration to succeed. Failure at any step short-circuits the pipeline and returns an error response.
Schema validation
SkillManifestSchema using AJV in strict mode with allErrors: true. Checks required fields, types, patterns, value ranges, and rejects any additionalProperties.On failure: Returns schema_validation_failed with an array of validationErrors (each containing path and message).Signature verification
- Remove the
signaturefield from the manifest - JCS-canonicalize the remaining object
- Compute
keccak256of the canonical JSON - Recover the signer address from the signature using
viem.recoverAddress() - Compare recovered address to
manifest.publisher.address(case-insensitive)
signature_verification_failed. This means the manifest was either tampered with after signing or signed with a different key.File hash verification
basePath), computes its SHA-256 hash, and compares against the hash declared in the manifest. Files that cannot be read are also treated as mismatches.On failure: Returns file_hash_mismatch with a hashMismatches array listing the paths that failed verification.Static analysis
error severity. Warnings are reported but do not block registration.On failure: Returns static_scan_failed with a scanFindings array containing each finding’s file, line number, rule ID, severity, and message.Duplicate check
status = 'active' only).On failure: Returns duplicate_skill with HTTP 409 Conflict.Static scanner rules
The static scanner runs 5 pattern-based rules against every source file. Each rule has one or more regex patterns and a severity level.| Rule ID | Severity | Patterns Detected | Description |
|---|---|---|---|
dynamic_eval | error | eval(), new Function() | Dynamic code execution — allows arbitrary code injection |
child_process | error | child_process, exec(), spawn(), execFile(), execSync(), spawnSync() | Process spawning — could escape sandbox |
network_access | error | fetch(), require('http'), http., https., net., dgram., WebSocket, XMLHttpRequest | Unauthorized network access — skills must not make direct network calls |
fs_write | warning | writeFileSync, writeFile, mkdirSync, unlinkSync, rmSync | Filesystem writes — reported but does not block registration |
obfuscation | warning | Hex escape sequences (\x chains), atob(), Buffer.from(..., 'base64') | Potentially obfuscated code — reported for manual review |
Registration errors
| Error Code | HTTP Status | Condition | How to Fix |
|---|---|---|---|
schema_validation_failed | 400 | Manifest does not conform to SkillManifest v1 schema | Check validationErrors in the response for specific field issues |
signature_verification_failed | 400 | ECDSA signature does not match publisher.address | Re-sign with the correct private key matching publisher.address |
file_hash_mismatch | 400 | SHA-256 of one or more files does not match manifest entries | Re-hash files and update files array, or re-sign after changes |
static_scan_failed | 400 | Source files contain error-severity patterns | Remove flagged patterns (see scanFindings for file, line, and rule) |
duplicate_skill | 409 | A skill with the same name is already active | Revoke the existing skill first, then re-register |
All registration failures are audit-logged as
skill_registration_failed events with the skill name and error reason.API endpoints
POST /v1/skills/register
Register a new skill manifest. Runs the full 6-step validation pipeline. Request body:GET /v1/skills
List all active (non-revoked) skills ordered by registration time.GET /v1/skills/:name
Get a single skill by name. Returns the fullRegisteredSkill record including the stored manifest and registration metadata. Returns 404 with { "error": "skill_not_found" } if the skill does not exist.
DELETE /v1/skills/:name
Revoke a skill (soft delete). Setsstatus to "revoked" and records the revoked_at timestamp. The skill is excluded from GET /v1/skills listings but remains in the database for audit purposes.
404 if the skill does not exist or is already revoked. An audit event skill_revoked is logged with the skill name.
Skill lifecycle
- Created: A signed manifest JSON exists but has not been submitted to the registry.
- Active: The manifest passed all 6 validation steps and is stored in the database. Active skills appear in
GET /v1/skillsand can be executed by the sandbox runner. - Revoked: The skill was soft-deleted via
DELETE /v1/skills/:name. It no longer appears in active listings but its record persists in the database. A new skill with the same name can be registered after revocation.
Worked example
A complete end-to-end registration flow.Security considerations
The Skill Registry sits at the boundary between Domain A (untrusted agent skills) and Domain B (trusted core). Four mechanisms provide defense in depth:Signature Binding
The ECDSA signature ties the manifest to a specific publisher Ethereum address. Tampering with any field (including file hashes) invalidates the signature at Step 2.
Content Addressing
SHA-256 file hashes ensure that the exact code reviewed during registration is the code that runs in the sandbox. Any modification after registration is detectable.
Static Scanning
The 5-rule scanner catches common sandbox escape patterns (eval, process spawning, direct network access). This is a defense-in-depth measure — the sandbox itself also enforces isolation.
Audit Trail
All registration successes, failures, and revocations are logged to the append-only audit trace, correlated by skill name and manifest hash.
Next steps
- SkillManifest Schema — Full schema reference
- Sandbox Security — Container isolation model
- Trust Domains — How the registry fits in the trust model