Documentation

Build with trust

Everything you need to install, verify, and understand agent skills. Security scanning, cryptographic signing, and full transparency.

Vett builds trust through a verifiable pipeline. Every skill goes through the same process: fetch from source, analyze for threats, sign the artifact, store immutably, and verify on install. Here's how each step works.

The Pipeline

From source URL to verified installation in six steps.

SourceFetchAnalyzeSignStoreVerify
1
Fetch from source
Vett fetches skill files from their source repository. We support GitHub and direct HTTP URLs. For Git sources, we resolve the ref to a specific commit SHA to ensure reproducibility—even if the branch is later force-pushed.
2
Build manifest
All skill files are bundled into a canonical JSON manifest. This includes the entry point (usually SKILL.md), any supporting files, and extracted metadata like version and description. The manifest format is versioned for forward compatibility.
3
Analyze for threats
The manifest is analyzed using LLM-based security auditing. We detect permission requirements (filesystem, network, environment), flag suspicious patterns, and assign an overall risk level.
4
Sign the artifact
The manifest bytes are hashed (SHA-256) and signed with our ECDSA P-256 private key via Sigstore. The signature is recorded in Rekor's public transparency log, creating an unforgeable, publicly auditable proof that we scanned this exact content.
5
Store immutably
The signed manifest is uploaded to content-addressed storage. The storage key is the hash itself—if someone tries to upload different content with the same hash, it would fail cryptographically. Once stored, the artifact cannot be modified.
6
Verify on install
When you install a skill, the CLI downloads the manifest, recomputes the hash, and verifies the signature against our public key. Only if both checks pass does the CLI write any files to disk. You get exactly what we scanned.

Fetching Skills

Vett supports multiple source types, each with specific handling to ensure we capture the exact state of the skill at a point in time.

GitHub

Uses the GitHub API to recursively list and fetch files. Resolves branch/tag refs to commit SHAs. Respects GITHUB_TOKEN for rate limits.

HTTP

Direct URL fetch for standalone skills. Attempts to fetch SKILL.md from the directory. No git provenance available.

Git Provenance

For Git-based sources, we record:

gitRefThe branch or tag name (e.g., "main", "v2.1.0")
commitShaThe resolved commit SHA at fetch time
No force-push risk
Because we record the commit SHA, even if someone force-pushes over the branch, we have proof of exactly what we fetched. The stored artifact is immutable.

Manifest Format

The manifest is the canonical representation of a skill. It's a JSON document containing all skill files and metadata.

manifest.json
1{
2  "schemaVersion": 1,
3  "entryPoint": "SKILL.md",
4  "files": [
5    {
6      "path": "SKILL.md",
7      "content": "---\nname: memory\nversion: 1.0.0\n---\n\n# Memory Skill\n\nPersistent memory...",
8      "contentType": "text/markdown"
9    },
10    {
11      "path": "templates/memory.md",
12      "content": "# Memory Log\n\n{{entries}}",
13      "contentType": "text/markdown"
14    }
15  ]
16}

SKILL.md Format

The entry point is typically a SKILL.md file with YAML frontmatter containing metadata:

SKILL.md
1---
2name: memory
3description: Persistent memory across sessions
4version: 1.0.0
5license: MIT
6compatibility: Claude Code
7metadata:
8  author: anthropics
9allowed-tools: Read Write
10---
11
12# Memory Skill
13
14This skill provides persistent memory by maintaining a markdown log file...
nameSkill name (required)
descriptionShort description (required)
versionSemantic version (optional, extracted from frontmatter or metadata)
allowed-toolsSpace-delimited list of tools the skill uses

Security Analysis

Every manifest is analyzed using LLM-based security auditing. The full manifest is sent to a paranoid security auditor with instructions to flag everything suspicious. The model returns structured output:

analysis result
1{
2  "v": 1,
3  "risk": "medium",
4  "permissions": {
5    "filesystem": ["read", "write"],
6    "network": ["read"],
7    "env": ["read"]
8  },
9  "flags": [
10    {
11      "type": "arbitrary_network",
12      "evidence": "Makes HTTP requests to user-specified URLs",
13      "severity": "medium"
14    },
15    {
16      "type": "credential_access",
17      "evidence": "Reads API keys from environment for weather service",
18      "severity": "low"
19    }
20  ],
21  "summary": "Web scraping skill with network access. Reads env for API keys."
22}
Context matters
The LLM adjusts severity based on context. A skill reading its own API key islow, but reading other apps' secrets is high. A shell command for git is medium, but arbitrary user input to shell is critical.

Cryptographic Signing

Every manifest is signed using ECDSA P-256 via Sigstore. Signatures are recorded in Rekor, a public append-only transparency log used by npm, PyPI, and Kubernetes.

Signing Process

  1. 1. Serialize the manifest to canonical JSON bytes
  2. 2. Compute SHA-256 hash of the bytes
  3. 3. Sign the hash with our ECDSA P-256 private key
  4. 4. Record signature in the Rekor transparency log
  5. 5. Store the Sigstore bundle (signature + Rekor proof) alongside the manifest
sigstore bundle (simplified)
1{
2  "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.2",
3  "verificationMaterial": {
4    "publicKey": { "hint": "v1-ecdsa-2025-02-04" },
5    "tlogEntries": [{
6      "logIndex": "12345678",
7      "inclusionProof": { ... }
8    }]
9  },
10  "messageSignature": {
11    "messageDigest": { "algorithm": "SHA2_256", "digest": "..." },
12    "signature": "MEUCIQDxT8..."
13  }
14}

Why Sigstore?

Public transparency

Every signature is recorded in Rekor. Anyone can verify when a manifest was signed.

Ecosystem standard

Same infrastructure used by npm, PyPI, and Kubernetes for supply chain security.

Strong cryptography

ECDSA P-256 provides 128-bit security—equivalent to 3072-bit RSA with smaller signatures.

Timestamp evidence

Rekor entries provide cryptographic proof of when signing occurred.

Content-Addressed Storage

Signed manifests are stored in Cloudflare R2 using content-addressed paths. The storage key is the SHA-256 hash of the manifest bytes.

storage structure
skills/
├── e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0...f6.json    # Manifest
├── a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6...f6.json    # Another version
└── ...

Immutability Guarantees

Content addressing

The file path IS the hash. You can't upload different content to the same path without the hash changing—which would make it a different path.

No overwrite

Once uploaded, artifacts are never modified. New versions get new hashes and new paths. Old versions remain available indefinitely.

Signed URLs

Downloads use short-lived signed URLs (60 seconds) to prevent hotlinking while maintaining CDN caching benefits.

Client-Side Verification

The CLI performs a multi-step verification before installing any files.

  1. 1.Load embedded ECDSA P-256 public key from the CLI binary
  2. 2.Download manifest from the artifact URL
  3. 3.Compute SHA-256 of the downloaded bytes
  4. 4.Compare hash against the expected value from metadata
  5. 5.Verify Sigstore bundle — check the ECDSA P-256 signature and validate the Rekor transparency log entry
  6. 6.Only if both pass: extract files to disk
What verification catches
  • Tampered artifacts (hash mismatch)
  • Forged signatures (verification failure)
  • Unknown signing keys (key not in registry)
  • CDN cache poisoning (hash mismatch)
  • Man-in-the-middle modifications (signature failure)