In one line. smithmark issues signed, portable capability attestations for MCP servers and skills so that a policy engine can admit an agent's tools on verifiable evidence instead of name and reputation.
An MCP server can place a phone call, read your email, and push a commit. A skill is arbitrary instructions plus scripts loaded straight into a privileged context. Today both are installed the way container images were installed in 2015: pulled by name, trusted by reputation. Nothing in the ecosystem attests who built these artifacts, what they are capable of, or whether what they declare matches what their code can actually reach.
smithmark produces that missing evidence, and hands it to a gate that decides. It is the opening of Act II for a family of trust-as-code tools: the zero-trust supply-chain trilogy (forgeseal, svidmint, assayward) verifies containers and workloads; smithmark extends the same discipline to the tools the agents themselves wield.
Figure 1. Before: an agent installs an MCP server by name and runs it on trust. After: the same server carries a signed capability manifest, and a policy gate admits it on evidence.
Why this matters
- Agent tools are privileged code with no provenance layer. An MCP server declares a friendly tool list, then runs code that can reach the network, the filesystem, and the shell. Nothing binds the declaration to the artifact, and nothing signs either one. The maker is anonymous by default.
- The distribution layer is an unverified pointer today. The Model Context Protocol registry (
server.jsonschema2025-12-11) stores where to fetch a server, not a signed statement of what it is; security researchers describe this as an unverified pointer architecture open to supply-chain poisoning and "rug pull" capability mutation. A July 2026 MCP specification release candidate and independent academic work ("Attested Tool-Server Admission," arXiv 2026) are both circling the same gap. - The standards to close it already exist, unused for this artifact class. in-toto DSSE, Sigstore, SLSA, and CycloneDX (ratified as ECMA-424, 2nd Edition, December 2025) secure container and package supply chains today. No one had composed them into a portable capability attestation for agent tools. That composition is the whole idea.
🧭 If you only read this far: agent tools run with real-world reach and zero provenance; smithmark gives them a signed maker's mark that an existing policy gate can check before admission.
Terms in 30 seconds
Domain engineers: skip ahead to How it works.
- MCP server: a Model Context Protocol server: a process that exposes tools (functions with side effects) to an AI agent. Spec.
- Skill (SKILL.md bundle): a Markdown instruction file plus optional scripts and references, loaded into an agent's context to teach it a capability.
- Capability manifest: a signed, schema-validated declaration of what an artifact exposes and requires: tools, network egress, filesystem paths, exec, environment, and secrets.
- in-toto DSSE: Dead Simple Signing Envelope carrying an in-toto attestation Statement (v1); the portable, signature-agnostic wrapper smithmark signs. in-toto attestations.
- Sigstore (Fulcio + Rekor): keyless signing: a CI OIDC token is exchanged for a short-lived Fulcio certificate, and the signature is recorded in the public Rekor transparency log. sigstore.dev.
- SLSA: Supply-chain Levels for Software Artifacts; a build-provenance framework, levels L0 to L3. Current spec v1.2. slsa.dev.
- CycloneDX / ECMA-424: an OWASP bill-of-materials standard, spec 1.7 (October 2025), ratified as ECMA-424 2nd Edition (December 2025). cyclonedx.org.
- npm provenance: a Sigstore-backed SLSA statement npm attaches to a published package, proving which repository and workflow built it.
The problem, for engineers who don't live in this space
Think about how you install a Docker image. You pull some/image:latest, and unless you have gone out of your way, you have no idea who built it, from what source, or what it will do once it runs. That was the normal state of container distribution around 2015, before image signing, SBOMs, and admission controllers made "prove it before you run it" a routine expectation.
Agent tools are in that pre-provenance moment right now. Consider a real one: an MCP server that places phone calls and sends WhatsApp messages on your behalf, installed into a coding agent by name. It ships a tools.json that says, in effect, "I make calls." Its actual code opens sockets to several third-party APIs, reads local credential files, and can spawn subprocesses. Nothing checks that the friendly declaration matches the reachable behavior, and nothing proves the person who published it is the person who wrote it.
Why this is genuinely hard. The declaration and the artifact live in different places, signed by no one, checked by nothing, and the thing consuming them (an autonomous agent) is the least equipped party to judge trust in the moment it acts.
Figure 2. An agent tool travels from publish to install to run with no signed statement of authorship or capability at any hop.
What exists today (and the gap)
The near neighbors are real and worth naming. Each solves a slice; none composes the slices.
| Approach | MCP servers | Skills | Composes existing standards | Portable attestation for an external gate | Maker's mark separate from the gate |
|---|---|---|---|---|---|
| Enclawed | ❌ | ✅ | ❌ (bespoke root) | ❌ | ❌ (own runtime) |
| studiomeyer-io/mcp-server-attestation | ✅ | ❌ | ❌ (bespoke root) | ❌ | ❌ (first-use pin) |
| ETDI | ✅ | ❌ | ❌ (OAuth JWTs) | ❌ | ❌ (client-side) |
| Scanners (Snyk Agent Scan, ToolHive) | ✅ | ⚠️ | ❌ (inspect, do not sign) | ❌ | ❌ |
| MCP Registry | ✅ | ❌ | ❌ (curates) | ❌ | ❌ |
| npm provenance | ❌ | ❌ | ✅ | ✅ (build only) | ✅ |
| smithmark | ✅ | ✅ | ✅ | ✅ | ✅ |
The empty column that only the last row fills is a single, portable, signed capability attestation that spans both agent-tool artifact kinds, composes the existing supply-chain standards rather than minting a new trust root, and is produced independently of the policy engine that consumes it. Scanners inspect; registries curate; the near neighbors sign in silos; smithmark composes.
How it works
smithmark is a generator, signer, publisher, and verifier of attestations for agent artifacts, built as a pure deterministic core with all input and output pushed to adapters.
- Capability manifest: extracts an artifact's real surface (MCP tool listing, skill bundle contents) and records the declared tools, network egress, filesystem, exec, env, and secrets into a schema-validated document.
- Build provenance: composes a forgeseal dependency SBOM (CycloneDX) and SLSA-style provenance into the same statement, rather than reimplementing either.
- Capability lint: heuristic static detection of the gap between what the manifest declares and what the code appears able to reach.
- Verification: resolves an artifact, discovers its attestations, checks signatures and subject digests, and emits a machine-readable report that assayward consumes as policy evidence.
Figure 3. A pure core (manifest model, canonical digest, verification, lint) with discovery, composition, and CLI adapters around it; the signed predicate flows out to assayward.
The predicate
The manifest is wrapped as an in-toto Statement (v1) under a custom predicate type, https://in8.sh/attestation/agent-capability/v1, and signed as a DSSE envelope. Because the envelope is portable, the same attestation attaches wherever DSSE attaches: OCI referrers, a GitHub release asset, a Sigstore bundle. The subject is the published artifact, bound by digest.
Signing and discovery
Signing runs keyless in CI: the GitHub Actions OIDC token is exchanged for a short-lived Fulcio certificate, the statement is signed with it, and the signature is recorded in Rekor. Key-based offline signing is also supported. Discovery is dual-path: the native OCI referrers API where a registry supports it, and a deterministic reference mapping for npm and skill artifacts.
The gate is somebody else's job
smithmark verifies and reports; it never decides. Every allow, deny, or audit decision lives in assayward, which reads smithmark's report as evidence alongside forgeseal's attestations and svidmint's identities. The maker signs the mark; the gate rules on it.
Figure 4. Verification is fail-closed: a signed attestation whose declared surface holds up admits with an explainable report; anything unsigned, or with reach the manifest never declared, is denied or flagged rather than waved through.
The decisions that actually mattered
Compose the existing standards, do not mint a new trust root
The fork. The fastest way to ship signed capability manifests is to invent a manifest format and sign it with a project key. The near neighbors all did exactly that.
Options. A bespoke signing scheme and trust root, or a composition over Sigstore, npm provenance, SLSA, and CycloneDX.
Chosen. Composition. smithmark issues an in-toto DSSE predicate signed through Sigstore, sitting alongside npm provenance rather than replacing it, and projecting capability data into the CycloneDX property taxonomy.
Trade-off accepted. smithmark inherits the operational surface and failure modes of four upstream ecosystems instead of one it fully controls. That is the price of not asking the world to trust a brand-new root, and it is the right price.
A pure, deterministic core
The fork. Signing and discovery are inherently full of I/O. It is tempting to let that I/O soak through the whole codebase.
Options. A conventional service-shaped layout, or the same pure-core discipline the trilogy uses: no network, no clock except injected, no filesystem walks in the core.
Chosen. Pure core. Same evidence plus same time produces byte-identical output, which is what makes golden-file tests and a future WebAssembly or TypeScript port viable.
Trade-off accepted. More ceremony at the boundaries: bundle contents are read by an adapter and passed in, never walked by the core. The determinism is worth the ceremony.
Capability lint is advisory, and says so
The fork. A linter that flags undeclared capabilities could pretend to be a soundness checker.
Options. Claim sound static analysis, or ship an honest heuristic that flags obvious undeclared reach and admits it is host-unaware.
Chosen. Advisory. Lint flags every fetch() call site and every exec as "undeclared" regardless of the manifest, which means it produces findings on any real MCP server, including correctly declared ones.
Trade-off accepted. Lint is a discovery aid, not a drift signal, until a strict or host-aware successor ships. Saying that plainly is better than a false promise of proof.
Why this is new, and why it's significant
What's novel. smithmark is the first attestation framework to cover both MCP servers and skills with capability declarations issued as portable, signed attestations (in-toto DSSE) for an external policy engine to consume: it composes npm provenance, Sigstore, SLSA, and CycloneDX rather than replacing them or minting a bespoke trust root, and it closes the loop from publication (the maker's mark) to admission (assayward policy). Enclawed signs skill manifests for its own runtime; studiomeyer-io/mcp-server-attestation signs tool and spawn allowlists for MCP servers under trust on first use; ETDI binds OAuth-scoped tool definitions to a client-side policy check. None covers both artifact kinds, none composes the existing supply-chain standards, and none separates the maker's mark from the gate that consumes it.
Why it's significant to the field. The problem smithmark addresses is an actively named open problem, not a self-declared one. The MCP registry's lack of a signed provenance layer is documented in the July 2026 specification work and in independent academic literature on attested tool-server admission. smithmark's contribution is a working reference implementation plus two upstream standards drafts that version with it:
- A CycloneDX agent-capability taxonomy proposal, targeting Ecma TC54, to register an
in8:agent:capability:*property namespace against CycloneDX 1.7 / ECMA-424. - An MCP Registry provenance RFC, targeting
modelcontextprotocol/registry, adding an attestation-reference field and verify-on-publish toserver.json.
Standards and ecosystem alignment.
- in-toto attestation Statement v1, DSSE envelope.
- Sigstore keyless signing (Fulcio certificates, Rekor transparency log), proven in production (see below).
- SLSA v1.2 build provenance, composed via forgeseal, not reimplemented.
- CycloneDX 1.7, ratified as ECMA-424 2nd Edition (December 2025).
- MCP Registry
server.jsonschema2025-12-11.
📌 Honest scope. smithmark is not a scanner, a marketplace, or a policy engine, and its capability lint is heuristic, not sound: v0.1 promises detection of obvious undeclared capabilities, not proof of their absence. The novelty claim above was narrowed at a whitespace-sweep gate after named prior art (Enclawed, ETDI, studiomeyer-io) falsified the original blanket "first" wording; the surviving claim is the conjunction, both artifact kinds and composition and separation of mark from gate, which no swept item satisfies.
See it run
The two MCP servers in this portfolio, better-call-claude and dear-claude, now publish a keyless smithmark capability attestation on every release. Here is that attestation being verified with standard Sigstore tooling, no smithmark binary required.
# Verify the keyless capability attestation attached to a published release,
# using cosign, against the exact CI identity that produced it.
cosign verify-blob-attestation \
--bundle smithmark-attestation.sigstore.json \
--new-bundle-format \
--certificate-identity \
"https://github.com/sns45/better-call-claude/.github/workflows/smithmark-attest.yml@refs/tags/v3.1.3" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--type "https://in8.sh/attestation/agent-capability/v1" \
--check-claims=false
Verified OK # ← signature, Fulcio identity, and Rekor inclusion all check out
The signature is anchored in the public transparency log; anyone can pull the same entry back out by its index.
curl -s "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=2226008616" \
| jq '.[].verification | {inclusionProof: (.inclusionProof != null), signedEntryTimestamp: (.signedEntryTimestamp != null)}'
{ "inclusionProof": true, "signedEntryTimestamp": true } # ← independently in Rekor
The attestation's subject is the published npm tarball, bound by digest, and its predicate carries the declared capability surface. smithmark's own verify command runs this same keyless path natively and emits the machine-readable report assayward reads.
🔬 Go deeper. The keyless verification path, with Rekor inclusion and exact-identity enforcement, lives in
pkg/compose/verify_keyless_native.go.
What's next
The near-term step is submitting the two standards drafts to their venues (Ecma TC54 for the capability taxonomy, the MCP registry for the provenance RFC) while the reference implementation keeps proving them out; a verify-only TypeScript surface for browser and Worker runtimes follows. The larger arc is the one line this whole family turns on: the trilogy verifies the mark, and the mark verifies the agent's tools.
Appendix / references
- Repository: github.com/sns45/smithmark
- The zero-trust supply-chain trilogy this extends: forgeseal, svidmint, assayward
- Adopters carrying live attestations: better-call-claude, dear-claude
- Standards: in-toto attestations, Sigstore, SLSA v1.2, CycloneDX 1.7 / ECMA-424, MCP
- Prior art discussed: Enclawed, studiomeyer-io/mcp-server-attestation, ETDI; independent problem framing in "Attested Tool-Server Admission: A Security Extension to the Model Context Protocol" (arXiv, 2026)
- Discussion and issues: github.com/sns45/smithmark/issues