Skill integrity verification for AI agents. Implements ACRF-05 supply chain defense pattern.
Project description
acrf-skill-verify
Skill integrity verification for AI agents. Implements the ACRF-05 (Supply Chain Toxicity) defense pattern.
Part of the ACRF framework: https://github.com/kannasekar-alt/ACRF PyPI: https://pypi.org/project/acrf-skill-verify/ Presented at RSA Conference 2026.
Try it in your environment right now
No Docker. No setup. Just Python 3.10+.
Step 1 - Install:
pip install acrf-skill-verify
Step 2 - Build your trusted skill registry:
from acrf_skill_verify import SkillRegistry, hash_file
registry = SkillRegistry()
registry.register("customer-insights-mcp", hash_file("/skills/customer-insights-mcp"))
registry.register("email-mcp", hash_file("/skills/email-mcp"))
registry.block("malicious-skill-mcp")
registry.save("trusted_skills.json")
Step 3 - Verify before installing any skill:
from acrf_skill_verify import SkillRegistry, install_safe
registry = SkillRegistry.load("trusted_skills.json")
install_safe(
"customer-insights-mcp",
skill_content="/downloads/customer-insights-mcp",
registry=registry
)
If the skill content does not match the registered hash, install_safe raises SkillIntegrityError. Your application fails closed.
The problem this solves
AI agent skill registries are the new npm. Antiy CERT identified 1,184 malicious skills in agent registries in 2025. Skills are downloaded thousands of times before anyone notices they are exfiltrating data, harvesting credentials, or installing backdoors.
This is ACRF-05: supply chain toxicity.
acrf-skill-verify makes every skill installation tamper-evident. A skill whose hash does not match the registered version will not install.
CLI - manage the registry from the command line
Set your registry path once:
export ACRF_SKILL_REGISTRY=/etc/acrf/trusted_skills.json
Compute the hash of a skill (file or directory):
acrf-skill-verify hash /skills/customer-insights-mcp
Register a vetted skill:
acrf-skill-verify register customer-insights-mcp /skills/customer-insights-mcp
Block a known-malicious skill name:
acrf-skill-verify block free-gpt-mcp
Verify a skill before installation:
acrf-skill-verify verify customer-insights-mcp /downloads/customer-insights-mcp
Output when valid:
OK: customer-insights-mcp integrity verified
Output when tampered:
FAIL: customer-insights-mcp
Skill integrity check failed for customer-insights-mcp.
Expected: sha256:9f4a2b8c1e6d3f7a0b5c9e2d4...
Got: sha256:6343536004920d0fe642b02ca...
Skill may be tampered or malicious.
List the registry:
acrf-skill-verify list
How it works
- You register vetted skills by computing a SHA-256 hash of their content
- The registry persists to a JSON file (with both approved and blocklist)
- Before installing any skill, you call install_safe()
- install_safe recomputes the hash from the actual content
- If the hash matches the registered hash - skill is safe to install
- If the hash does not match - SkillIntegrityError is raised
- Skills on the blocklist are always rejected, regardless of hash
The defense is fail-closed. A tampered or unregistered skill never installs.
Works with any skill format
The library hashes:
- Single files (e.g. customer-insights-mcp.py)
- Whole directories (recursive, deterministic)
- Raw bytes (for skills loaded from network or memory)
Use whichever matches how your platform packages skills.
Real-world use
Wrap your skill installation pipeline with two lines:
from acrf_skill_verify import SkillRegistry, install_safe
import os
REGISTRY = SkillRegistry.load(os.environ["ACRF_SKILL_REGISTRY"])
def install_skill(skill_name, skill_path):
install_safe(skill_name, skill_path, REGISTRY)
# ... existing install logic only runs if verify succeeds
That is it. Every skill installation is now tamper-evident. A modified or unregistered skill will not install.
ACRF-05 control objectives addressed
SC-1 All agent skills vetted before use via cryptographic hash
SC-2 Approved skill inventory maintained
Out of scope (your infrastructure):
SC-3 Runtime monitoring detects unexpected network calls from installed skills
Runtime behavior monitoring belongs in your observability stack, not in a verification library.
What this library does NOT do
- It does not analyze skill code for malicious behavior (use static analysis)
- It does not sandbox skill execution (use containers or agent runtimes)
- It does not protect against the skill becoming malicious AFTER you trust it
It only ensures that the skill you install is byte-identical to the skill you registered. That is the ACRF-05 defense pattern.
Works with any Python AI agent framework
LangChain, CrewAI, AutoGen, MCP-based systems, custom agents. If you install third-party skills or plugins, you can use this library.
Authors
Ravi Karthick Sankara Narayanan Kanna Sekar
License
Apache 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acrf_skill_verify-0.1.0.tar.gz.
File metadata
- Download URL: acrf_skill_verify-0.1.0.tar.gz
- Upload date:
- Size: 9.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34b36df5f094a66e2246dcdd5671f58dec9a0c52f5625dc795ff4fca39159db4
|
|
| MD5 |
a12057a60a1fe41c7793d9a5cebf68fd
|
|
| BLAKE2b-256 |
ba5b66c3f39fe5d6ba5b7dab67de7e2bf23c2ab95ad4e6d3dc03c05957301efc
|
File details
Details for the file acrf_skill_verify-0.1.0-py3-none-any.whl.
File metadata
- Download URL: acrf_skill_verify-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ee043a32d679bad5af839eece255ed01657b7f1abf0cf4c33e9bf9adfd282a5
|
|
| MD5 |
0d25ffeb172c16dd64e0a8c13743e35a
|
|
| BLAKE2b-256 |
dcaaf65e982ac445904863060f41dffe88a910359337084630d2a0f484716227
|