Skip to content
Back to skills

Skill Sign

ASecurity

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 没被改过.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentspythonrustgobashnodegitsecurity

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 9 files and shows the line behind each finding

Scanned September 23, 2026

npx -y skills add Songhonglei/build-better-skills --skill skill-sign --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Skill Sign?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Skill Sign
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/songhonglei-skill-sign/badge)](https://www.skillsdirectory.com/skills/songhonglei-skill-sign)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: skill-sign
description: >
  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-sign

- **Version**: 1.0.3
- **License**: MIT
- **Author**: Evan Song · [github.com/Songhonglei](https://github.com/Songhonglei)
- **Repository**: https://github.com/Songhonglei/build-better-skills/tree/main/skills/skill-sign
- **Part of**: [`build-better-skills`](https://github.com/Songhonglei/build-better-skills) suite — see [Stages](https://github.com/Songhonglei/build-better-skills#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 install` needed.
- 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)

```bash
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)

```bash
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):

```bash
python3 scripts/verify.py /path/to/skill
```

**Trust-verify** (proves both integrity AND author identity):

```bash
# 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

```json
{
  "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-key` is 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.hazmat`
  if you need that — sign.key format is interoperable.

## Workflow for publishing on a skill hub

1. Run `scripts/init.py` (one-time)
2. Run `scripts/sign.py my-skill --version 1.0.0`
3. Commit `sign.key` along with the skill, publish.
4. In your skill's README, include:
   `Signed with: ed25519:abc123...` (from `export_public.py --skill-md`)
5. Recipients trust your key once (from your verified GitHub profile),
   then `verify.py --trust-key` every release.

## Scripts

- `scripts/init.py` — Generate Ed25519 keypair
- `scripts/sign.py` — Sign a skill directory
- `scripts/verify.py` — Verify signed skill
- `scripts/export_public.py` — Print public key for sharing
- `scripts/_lib.py` — Shared helpers (file walking, hashing, encoding)
- `scripts/_vendor/ed25519_rfc8032.py` — RFC 8032 reference Ed25519 (public domain)

Files in this skill

  • LICENSE1 KB
  • README.md4.4 KB
  • SKILL.md6.1 KB
  • scripts/_lib.py8.1 KB
  • scripts/_vendor/ed25519_rfc8032.py18.8 KB
  • scripts/export_public.py1.6 KB
  • scripts/init.py3.1 KB
  • scripts/sign.py5.5 KB
  • scripts/verify.py7.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.