Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
SchemaPin enables cryptographic signing and verification of tool schemas to prevent tampering using ECDSA P-256, SHA-256, TOFU pinning, and .well-known key d...
SchemaPin enables cryptographic signing and verification of tool schemas to prevent tampering using ECDSA P-256, SHA-256, TOFU pinning, and .well-known key d...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Purpose: This guide helps AI assistants quickly integrate SchemaPin into applications for cryptographic tool schema verification. For Full Documentation: See the README, Technical Specification, and language-specific READMEs in each subdirectory.
SchemaPin prevents "MCP Rug Pull" attacks by enabling developers to cryptographically sign their tool schemas (ECDSA P-256 + SHA-256) and clients to verify schemas haven't been tampered with. It uses Trust-On-First-Use (TOFU) key pinning and RFC 8615 .well-known endpoints for public key discovery. Part of the ThirdKey trust stack: SchemaPin (tool integrity) โ AgentPin (agent identity) โ Symbiont (runtime)
pip install schemapin from schemapin.crypto import KeyManager, SignatureManager from schemapin.core import SchemaPinCore # Generate keys private_key, public_key = KeyManager.generate_keypair() # Sign a schema core = SchemaPinCore() canonical = core.canonicalize_schema(schema_dict) signature = SignatureManager.sign_schema(private_key, canonical) # Verify is_valid = SignatureManager.verify_signature(public_key, canonical, signature)
npm install schemapin import { KeyManager, SignatureManager, SchemaPinCore } from 'schemapin'; // Generate keys const { privateKey, publicKey } = KeyManager.generateKeypair(); // Sign a schema const core = new SchemaPinCore(); const canonical = core.canonicalizeSchema(schema); const signature = await SignatureManager.signSchema(privateKey, canonical); // Verify const isValid = await SignatureManager.verifySignature(publicKey, canonical, signature);
go get github.com/ThirdKeyAi/schemapin/go@v1.3.0 import ( "github.com/ThirdKeyAi/schemapin/go/pkg/core" "github.com/ThirdKeyAi/schemapin/go/pkg/crypto" ) // Generate keys km := crypto.NewKeyManager() privKey, pubKey, _ := km.GenerateKeypair() // Sign a schema spc := core.NewSchemaPinCore() canonical, _ := spc.CanonicalizeSchema(schema) sig, _ := crypto.NewSignatureManager().SignSchema(privKey, canonical) // Verify valid, _ := crypto.NewSignatureManager().VerifySignature(pubKey, canonical, sig)
[dependencies] schemapin = "1.3" use schemapin::crypto::{generate_key_pair, sign_data, verify_signature}; use schemapin::core::SchemaPinCore; // Generate keys let key_pair = generate_key_pair()?; // Sign let core = SchemaPinCore::new(); let canonical = core.canonicalize_schema(&schema)?; let signature = sign_data(&key_pair.private_key_pem, &canonical)?; // Verify let is_valid = verify_signature(&key_pair.public_key_pem, &canonical, &signature)?;
Schemas are canonicalized (deterministic JSON serialization with sorted keys) before hashing. This ensures identical schemas always produce the same hash regardless of key ordering.
Developers publish their public key at https://example.com/.well-known/schemapin.json: from schemapin.utils import create_well_known_response response = create_well_known_response( public_key_pem=public_key_pem, developer_name="Acme Corp", schema_version="1.2", revocation_endpoint="https://example.com/.well-known/schemapin-revocations.json" )
On first verification, the developer's public key fingerprint is pinned. Subsequent verifications reject different keys for the same domain โ detecting key substitution attacks.
Online (standard): workflow = SchemaVerificationWorkflow(pin_store) result = workflow.verify_schema(schema, signature, "https://example.com") Offline (v1.2.0 โ no HTTP required): from schemapin.verification import verify_schema_offline, KeyPinStore pin_store = KeyPinStore() result = verify_schema_offline( schema, signature_b64, domain, tool_id, discovery_data, revocation_doc, pin_store )
from schemapin.revocation import ( build_revocation_document, add_revoked_key, check_revocation, RevocationReason ) doc = build_revocation_document("example.com") add_revoked_key(doc, fingerprint, RevocationReason.KEY_COMPROMISE) check_revocation(doc, some_fingerprint) # raises if revoked
Pre-package discovery + revocation data for environments without internet: from schemapin.bundle import SchemaPinTrustBundle bundle = SchemaPinTrustBundle.from_json(bundle_json_str) discovery = bundle.find_discovery("example.com") revocation = bundle.find_revocation("example.com")
from schemapin.resolver import ( WellKnownResolver, # HTTP .well-known lookups LocalFileResolver, # Local JSON files TrustBundleResolver, # In-memory trust bundles ChainResolver, # First-match fallthrough ) # Chain: try bundle first, fall back to HTTP resolver = ChainResolver([ TrustBundleResolver.from_json(bundle_json), WellKnownResolver(timeout=10), ])
from schemapin.verification import verify_schema_with_resolver result = verify_schema_with_resolver( schema, signature_b64, domain, tool_id, resolver, pin_store )
Sign entire skill directories (e.g., a folder containing SKILL.md) with ECDSA P-256. Produces a .schemapin.sig manifest alongside the files, proving no file has been tampered with. Python: from schemapin.skill import sign_skill, verify_skill_offline # Sign a skill directory sig = sign_skill("./my-skill/", private_key_pem, "example.com") # Writes .schemapin.sig into ./my-skill/ # Verify offline from schemapin.verification import KeyPinStore result = verify_skill_offline("./my-skill/", discovery_data, sig, revocation_doc, KeyPinStore()) JavaScript: import { signSkill, verifySkillOffline } from 'schemapin/skill'; const sig = await signSkill('./my-skill/', privateKeyPem, 'example.com'); const result = verifySkillOffline('./my-skill/', discoveryData, sig, revDoc, pinStore); Go: import "github.com/ThirdKeyAi/schemapin/go/pkg/skill" sig, err := skill.SignSkill("./my-skill/", privateKeyPEM, "example.com", "", "") result := skill.VerifySkillOffline("./my-skill/", disc, sig, rev, pinStore, "") Rust: use schemapin::skill::{sign_skill, verify_skill_offline}; let sig = sign_skill("./my-skill/", &private_key_pem, "example.com", None, None)?; let result = verify_skill_offline("./my-skill/", &disc, Some(&sig), rev.as_ref(), Some(&pin_store), None);
{ "schemapin_version": "1.3", "skill_name": "my-skill", "skill_hash": "sha256:<root_hash>", "signature": "<base64_ecdsa_signature>", "signed_at": "2026-02-14T00:00:00Z", "domain": "example.com", "signer_kid": "sha256:<key_fingerprint>", "file_manifest": { "SKILL.md": "sha256:<file_hash>" } }
from schemapin.skill import detect_tampered_files, canonicalize_skill _, current_manifest = canonicalize_skill("./my-skill/") tampered = detect_tampered_files(current_manifest, sig.file_manifest) # tampered.modified, tampered.added, tampered.removed
Python CLI tools are included: # Generate a keypair schemapin-keygen --output-dir ./keys # Sign a schema schemapin-sign --key ./keys/private.pem --schema schema.json # Verify a signature schemapin-verify --key ./keys/public.pem --schema schema.json --signature sig.b64 Go CLI equivalents are also available (go install github.com/ThirdKeyAi/schemapin/go/cmd/...@v1.3.0).
Developer Client (AI Platform) โโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ 1. Generate ECDSA P-256 keypair 2. Publish public key at 3. Discover public key from /.well-known/schemapin.json /.well-known/schemapin.json 4. Sign tool schema 5. Verify signature (canonicalize โ SHA-256 (canonicalize โ SHA-256 โ ECDSA sign) โ ECDSA verify) 6. TOFU pin the key fingerprint 7. Check revocation status
OperationPythonJavaScriptGoRustGenerate keysKeyManager.generate_keypair()KeyManager.generateKeypair()km.GenerateKeypair()generate_key_pair()Sign schemaSignatureManager.sign_schema()SignatureManager.signSchema()sm.SignSchema()sign_data()Verify signatureSignatureManager.verify_signature()SignatureManager.verifySignature()sm.VerifySignature()verify_signature()CanonicalizeSchemaPinCore().canonicalize_schema()new SchemaPinCore().canonicalizeSchema()spc.CanonicalizeSchema()SchemaPinCore::new().canonicalize_schema()Discover keyPublicKeyDiscovery.fetch_well_known()PublicKeyDiscovery.fetchWellKnown()FetchWellKnown()WellKnownResolver (fetch feature)Offline verifyverify_schema_offline()verifySchemaOffline()VerifySchemaOffline()verify_schema_offline()Resolver verifyverify_schema_with_resolver()verifySchemaWithResolver()VerifySchemaWithResolver()verify_schema_with_resolver()Sign skill foldersign_skill()signSkill()skill.SignSkill()sign_skill()Verify skillverify_skill_offline()verifySkillOffline()skill.VerifySkillOffline()verify_skill_offline()Detect tamperingdetect_tampered_files()detectTamperedFiles()skill.DetectTamperedFiles()detect_tampered_files()
# Python cd python && python -m pytest tests/ -v # JavaScript cd javascript && npm test # Go cd go && go test ./... # Rust cd rust && cargo test
Always canonicalize before signing or verifying โ raw JSON comparison will fail Use offline verification when you have pre-fetched discovery data โ avoids HTTP calls during schema validation Trust bundles are ideal for CI/CD and air-gapped deployments ChainResolver lets you layer resolvers: bundle โ local files โ HTTP as fallback TOFU pinning means the first key seen for a domain is trusted โ warn users on key changes All languages use the same crypto โ ECDSA P-256 + SHA-256, so cross-language verification works Revocation checking should always be performed โ both simple lists and standalone documents SkillSigner signs entire directories โ ideal for SKILL.md folders uploaded to registries like ClaWHub .schemapin.sig is auto-excluded from hashing โ you can re-sign a directory without removing the old signature first
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.