A Python implementation of the SchemaPin protocol for cryptographic schema integrity verification of AI tools.
SchemaPin provides cryptographic verification of AI tool schemas using ECDSA P-256 signatures and Trust-On-First-Use (TOFU) key pinning. This Python implementation serves as the reference implementation for the protocol.
- ECDSA P-256 Cryptography: Industry-standard elliptic curve signatures
- Schema Canonicalization: Deterministic JSON serialization for consistent hashing
- Public Key Discovery: Automatic retrieval from
.well-known/schemapin.jsonendpoints - Key Pinning: Trust-On-First-Use security model with SQLite storage
- High-Level Workflows: Simple APIs for both developers and clients
- Comprehensive Testing: Full test suite with security validation
# Install latest stable version
pip install schemapin
# Install with development dependencies
pip install schemapin[dev]
# Install with testing dependencies only
pip install schemapin[test]# Clone repository and install in development mode
git clone https://github.com/thirdkey/schemapin.git
cd schemapin/python
pip install -e .[dev]After installation, the following CLI tools will be available:
schemapin-keygen- Generate cryptographic key pairsschemapin-sign- Sign JSON schemasschemapin-verify- Verify signed schemas
SchemaPin provides three command-line tools for common operations:
Generate ECDSA or RSA key pairs with optional .well-known template:
# Generate ECDSA key pair with .well-known template
schemapin-keygen --type ecdsa --developer "Your Company" --well-known
# Generate RSA 4096-bit key pair
schemapin-keygen --type rsa --key-size 4096 --output-dir ./keys
# Generate keys in DER format
schemapin-keygen --type ecdsa --format der --prefix mykeysSign JSON schema files with private keys:
# Sign a single schema
schemapin-sign --key private.pem --schema schema.json --output signed.json
# Sign with metadata
schemapin-sign --key private.pem --schema schema.json --developer "Your Company" --version "1.0"
# Batch sign multiple schemas
schemapin-sign --key private.pem --batch ./schemas/ --output-dir ./signed/
# Sign from stdin
echo '{"type": "object"}' | schemapin-sign --key private.pem --stdinVerify signed schemas with public keys or discovery:
# Verify with public key
schemapin-verify --schema signed.json --public-key public.pem
# Verify with domain discovery and interactive pinning
schemapin-verify --schema signed.json --domain example.com --tool-id my-tool --interactive
# Batch verify with auto-pinning
schemapin-verify --batch ./signed/ --domain example.com --auto-pin
# Verify from stdin with JSON output
echo '{"schema": {...}, "signature": "..."}' | schemapin-verify --stdin --public-key public.pem --jsonRun the CLI examples script to see detailed usage patterns:
cd python/examples
python cli_usage_examples.pyfrom schemapin.utils import SchemaSigningWorkflow, create_well_known_response
from schemapin.crypto import KeyManager
# 1. Generate key pair
private_key, public_key = KeyManager.generate_keypair()
private_key_pem = KeyManager.export_private_key_pem(private_key)
public_key_pem = KeyManager.export_public_key_pem(public_key)
# 2. Sign your tool schema
schema = {
"name": "calculate_sum",
"description": "Calculates the sum of two numbers",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"}
},
"required": ["a", "b"]
}
}
signing_workflow = SchemaSigningWorkflow(private_key_pem)
signature = signing_workflow.sign_schema(schema)
# 3. Create .well-known response
well_known_response = create_well_known_response(
public_key_pem,
"Your Organization",
"contact@yourorg.com"
)
# Host well_known_response at https://yourdomain.com/.well-known/schemapin.jsonfrom schemapin.utils import SchemaVerificationWorkflow
verification_workflow = SchemaVerificationWorkflow()
# Verify schema with automatic key pinning
result = verification_workflow.verify_schema(
schema,
signature,
"yourdomain.com/calculate_sum",
"yourdomain.com",
auto_pin=True
)
if result['valid']:
print("✅ Schema signature is valid")
if result['first_use']:
print("🔑 Key pinned for future use")
else:
print("❌ Schema signature is invalid")
print("Error:", result['error'])canonicalize_schema(schema)- Convert schema to canonical string formathash_canonical(canonical)- SHA-256 hash of canonical stringcanonicalize_and_hash(schema)- Combined canonicalization and hashing
generate_keypair()- Generate new ECDSA P-256 key pairexport_private_key_pem(private_key)- Export private key to PEM formatexport_public_key_pem(public_key)- Export public key to PEM formatload_private_key_pem(pem_data)- Load private key from PEMload_public_key_pem(pem_data)- Load public key from PEM
sign_hash(hash_bytes, private_key)- Sign hash with private keyverify_signature(hash_bytes, signature, public_key)- Verify signaturesign_schema_hash(schema_hash, private_key)- Sign schema hashverify_schema_signature(schema_hash, signature, public_key)- Verify schema signature
fetch_well_known(domain)- Fetch .well-known/schemapin.jsonget_public_key_pem(domain)- Get public key from domainget_developer_info(domain)- Get developer information
pin_key(tool_id, public_key_pem, domain, developer_name)- Pin public keyget_pinned_key(tool_id)- Get pinned key for toolis_key_pinned(tool_id)- Check if key is pinnedlist_pinned_keys()- List all pinned keysremove_pinned_key(tool_id)- Remove pinned key
workflow = SchemaSigningWorkflow(private_key_pem)
signature = workflow.sign_schema(schema)workflow = SchemaVerificationWorkflow()
result = workflow.verify_schema(schema, signature, tool_id, domain, auto_pin)Run the included examples:
# Tool developer workflow
cd python/examples
python tool_developer.py
# Client verification workflow
python client_verification.pycd python
python -m pytest tests/ -v
# Run code quality checks
ruff check .
bandit -r . --exclude tests/- Python 3.8 or higher
- cryptography library for ECDSA operations
- requests library for HTTP operations
- sqlite3 (built-in) for key storage
- Private Key Security: Store private keys securely and never expose them
- HTTPS Required: Always use HTTPS for .well-known endpoint discovery
- Key Pinning: Review pinned keys periodically and verify authenticity
- Signature Verification: Always verify signatures before using tool schemas
This Python implementation is designed to be fully compatible with the JavaScript implementation:
- Identical schema canonicalization results
- Compatible ECDSA P-256 signatures
- Same .well-known endpoint format
- Interoperable key formats (PEM)
MIT License - see LICENSE file for details.
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
For issues and questions:
- GitHub Issues: SchemaPin Repository
- Documentation: See TECHNICAL_SPECIFICATION.md
- Examples: Check the
examples/directory