Skill sign
A suite of skills to build better skills — from creation through install, audit, release, regression testing, and sediment.
npx -y skills add Songhonglei/build-better-skills --skill skill-signAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Cryptographically sign and verify AgentSkill directories using Ed25519 (RFC 8032). Publishers sign skills with a private key; recipients verify with a public key, proving the skill is unmodified AND authored by the trusted key holder. Pure Python — no pip install, no native dependencies. Use when you say sign skill, verify skill, ed25519 sign, verify skill authenticity, prove skill author, detect skill tampering, give skill a signature, 给 skill 签名, 验证 skill 是谁发的, 校验 skill 没被改过.
SKILL.md
6.1 KB, as published. Nobody here has run it
skill-sign
- Version: 1.0.3
- License: MIT
- Author: Evan Song · github.com/Songhonglei
- Repository: https://github.com/Songhonglei/build-better-skills/tree/main/skills/skill-sign
- Part of:
build-better-skillssuite — see Stages for the lifecycle map.
Cryptographically sign skill directories with Ed25519, so recipients can verify authenticity and detect tampering — even on machines that never met the author.
Why real signatures (not just hashes)
A plain SHA-256 of the skill detects accidental modification, but anyone can recompute the hash and re-publish under your name. Ed25519 signatures prove both integrity AND authorship — the verifier only needs your public key (safe to share), not your private one.
Dependencies
- Python ≥ 3.9 (stdlib only —
hashlib,json,base64,pathlib,argparse) - Vendored Ed25519 implementation:
scripts/_vendor/ed25519_rfc8032.py- Source: RFC 8032 Appendix A (public domain)
- This is NOT a pip package — it ships in this skill directory. No
pip installneeded.
- Environment variables read (all optional):
XDG_CONFIG_HOME,USER,USERNAME
Security model — read this first
| You can detect | Without --trust-key | With --trust-key <author's pubkey> |
|---|---|---|
| Accidental file modification after signing | ✅ | ✅ |
| sign.key metadata tampering | ✅ | ✅ |
| Attacker re-signing with their own key | ❌ — anyone can self-sign | ✅ — public key mismatch fails |
The trust-key channel is your responsibility. Get the author's public key from a known-good source (their official GitHub README, a key fingerprint posted in a verified blog, a key file delivered in-person, etc.). Once you have it, every future verify with that key is solid.
This is the same trust model as git commit -S, PGP-signed releases, and
Sigstore — and it has the same caveat: you must establish trust in the
public key out-of-band, once, through a channel you trust.
First-time setup (one-time per machine)
python3 scripts/init.py
Generates an Ed25519 keypair at:
~/.config/skill-sign/private.key— KEEP SECRET (chmod 600)~/.config/skill-sign/public.key— share freely~/.config/skill-sign/public.key.txt— same key as base64 text for copy-paste
🛡️ Back up private.key to a safe place (encrypted USB, password manager).
If lost, you cannot re-sign with the same identity.
Sign a skill (publisher)
python3 scripts/sign.py /path/to/your-skill --version 1.0.0
Writes sign.key inside the skill directory. Share the skill + sign.key
together. Publish your public key (from running scripts/export_public.py)
in a place recipients can trust (your GitHub README, etc.).
Verify a skill (recipient)
Self-verify (proves nothing was changed since signing, but NOT who signed it):
python3 scripts/verify.py /path/to/skill
Trust-verify (proves both integrity AND author identity):
# Option A: trusted key as inline string
python3 scripts/verify.py /path/to/skill \
--trust-key-string ed25519:abc123...
# Option B: trusted key from a file
python3 scripts/verify.py /path/to/skill \
--trust-key ~/.config/skill-sign/trusted/alice.pub
Exit codes: 0 = PASS, 1 = FAIL (tampered / untrusted), 2 = error.
sign.key format
{
"skill_name": "glic-check",
"version": "1.0.1",
"signed_by": "alice",
"signed_at": "2026-06-21T22:00:00+08:00",
"algorithm": "ed25519",
"public_key": "ed25519:<base64 32 bytes>",
"content_hash": "sha256:<hex>",
"signature": "<base64 64 bytes ed25519 signature>"
}
The signature covers a canonical (sorted-key) JSON of all the above
metadata fields (except signature itself). Any modification — to file
content or metadata — invalidates the signature.
What gets hashed
Included: all files under the skill directory (recursive, sorted by path).
Excluded: sign.key itself, .git/, __pycache__/, node_modules/,
*.pyc, *.pyo, *.bak, *.swp, .DS_Store, macOS ._* resource forks.
Limitations (v1.0)
- No key rotation:
--rotate-keyis reserved; for now, manual workflow (init --force → re-sign each skill) is required. - No revocation: if your private key is compromised, you must publish the new public key and tell recipients to re-trust it. No central registry.
- Pure-Python Ed25519 is slow & not side-channel hardened: ~5ms per
sign/verify. Fine for skill publishing (a few times per release); not
for high-frequency or hostile environments. Swap in
cryptography.hazmatif you need that — sign.key format is interoperable.
Workflow for publishing on a skill hub
- Run
scripts/init.py(one-time) - Run
scripts/sign.py my-skill --version 1.0.0 - Commit
sign.keyalong with the skill, publish. - In your skill's README, include:
Signed with: ed25519:abc123...(fromexport_public.py --skill-md) - Recipients trust your key once (from your verified GitHub profile),
then
verify.py --trust-keyevery release.
Scripts
scripts/init.py— Generate Ed25519 keypairscripts/sign.py— Sign a skill directoryscripts/verify.py— Verify signed skillscripts/export_public.py— Print public key for sharingscripts/_lib.py— Shared helpers (file walking, hashing, encoding)scripts/_vendor/ed25519_rfc8032.py— RFC 8032 reference Ed25519 (public domain)