From 7b34b5dd136305b087d008585bf84943e19571e5 Mon Sep 17 00:00:00 2001 From: AgentStatus Date: Sun, 30 Aug 2026 19:49:40 -0700 Subject: [PATCH 1/3] Docs: optional TOA verify for runtime health / promote Adjacent delivery-evidence gate only. Not on the tools/call hot path. Signed-off-by: AgentStatus --- README.md | 1 + docs/README.md | 1 + docs/registry/heuristics.md | 3 +++ docs/toa-optional-runtime-gate.md | 41 +++++++++++++++++++++++++++++++ examples/toa-after-runtime.yml | 23 +++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 docs/toa-optional-runtime-gate.md create mode 100644 examples/toa-after-runtime.yml diff --git a/README.md b/README.md index 1ac01d2779..083610a6c8 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Deploy, run, and manage MCP servers locally or in a Kubernetes cluster with secu - Proxy remote MCP servers securely for unified management - Kubernetes Operator for fleet and resource management - Leverage OpenTelemetry and Prometheus for monitoring and audit logging +- Optional offline [TOA](https://github.com/Carmel-Labs-Inc/toa) verify before promote ([docs](docs/toa-optional-runtime-gate.md)) ### 💻 Interfaces diff --git a/docs/README.md b/docs/README.md index f65a1437f7..ee25211255 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,6 +38,7 @@ For information on the ToolHive Operator, see the - **[Runtime Implementation Guide](runtime-implementation-guide.md)** - Guide for implementing new container runtime support - **[Runtime Version Customization](runtime-version-customization.md)** - Customizing base images and packages for protocol-scheme builds - **[Remote MCP Authentication](remote-mcp-authentication.md)** - How ToolHive authenticates to remote MCP servers +- **[Optional TOA runtime gate](toa-optional-runtime-gate.md)** - Offline delivery-evidence verify before promote / runtime enable - **[Server API Documentation](server/README.md)** - How the OpenAPI docs for the `thv serve` REST API are generated and served ### Operator Documentation diff --git a/docs/registry/heuristics.md b/docs/registry/heuristics.md index 3dbb2ba318..b7eb76e561 100644 --- a/docs/registry/heuristics.md +++ b/docs/registry/heuristics.md @@ -17,6 +17,9 @@ This document defines the criteria for including MCP (Model Context Protocol) se - Pinned dependencies and GitHub Actions - Published Software Bill of Materials (SBOMs) +### Optional delivery evidence (not a registry inclusion requirement) +- Offline [Tool Outcome Attestation](https://github.com/Carmel-Labs-Inc/toa) (`toa/0.1`) verify before promote / runtime enable. Separate from Sigstore provenance. See [Optional TOA runtime gate](../toa-optional-runtime-gate.md). + ### Continuous Integration - Automated dependency updates (Dependabot, Renovate, etc.) - Automated security scanning diff --git a/docs/toa-optional-runtime-gate.md b/docs/toa-optional-runtime-gate.md new file mode 100644 index 0000000000..b6b27f39f9 --- /dev/null +++ b/docs/toa-optional-runtime-gate.md @@ -0,0 +1,41 @@ +# Optional TOA verify for runtime health / promote + +ToolHive runs MCP servers in isolated containers, applies identity and access +policy, and verifies software provenance (Sigstore / attestations) for registry +entries. That answers secure run and supply-chain trust. It does not prove that +a tool recently delivered a real result under an outside probe. + +[TOA](https://github.com/Carmel-Labs-Inc/toa) (`toa/0.1`) is an Apache-2.0 signed +JSON evidence format for MCP tool delivery (reach, invoke, functional, shape, +and related layers). It is not a wire protocol. It is not meant to run on every +live `tools/call`. + +## Suggested fit + +Optional, off by default. Before promoting a workload to a production group, or +as a CI check after `thv` run / health, require a recent attestation and verify +it offline with a pinned emitter public key. + +- Any party can emit if they sign the schema. +- AgentStatus is one optional emitter. +- No AgentStatus account is required to verify. + +```yaml + # After your ToolHive deploy / health checks. + - name: Verify tool delivery attestation + if: hashFiles('toa.json') != '' + run: | + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@345f24607919b5bdf143719b9ea062543cdfe88e#subdirectory=python" + toa-verify toa.json --require-layer functional=pass +``` + +Copy-paste workflow: [`examples/toa-after-runtime.yml`](../examples/toa-after-runtime.yml). + +## Out of scope + +- Replacing Sigstore provenance, Cedar authz, or the runtime hot path +- Signing every production `tools/call` +- Changing ToolHive runtime code + +Related: [Registry inclusion heuristics](registry/heuristics.md) (supply-chain) +vs TOA (delivery evidence). diff --git a/examples/toa-after-runtime.yml b/examples/toa-after-runtime.yml new file mode 100644 index 0000000000..5278d2bfe8 --- /dev/null +++ b/examples/toa-after-runtime.yml @@ -0,0 +1,23 @@ +# Example only. Copy into your org workflow as needed. +name: ToolHive runtime and optional TOA + +on: + workflow_dispatch: + pull_request: + paths: + - "examples/**" + - "toa.json" + +jobs: + toa: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # Your thv run / health / operator checks go here. + + - name: Verify tool delivery attestation + if: hashFiles('toa.json') != '' + run: | + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@345f24607919b5bdf143719b9ea062543cdfe88e#subdirectory=python" + toa-verify toa.json --require-layer functional=pass From 9550cd72921746bc765dceb0f56616f71d02ef74 Mon Sep 17 00:00:00 2001 From: AgentStatus Date: Sun, 30 Aug 2026 20:25:34 -0700 Subject: [PATCH 2/3] Docs: pin emitter and max-age on toa-verify examples Match toa-verify --require-emitter / --max-age 7d after Carmel-Labs-Inc/toa#1. Signed-off-by: AgentStatus --- docs/toa-optional-runtime-gate.md | 4 ++-- examples/toa-after-runtime.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/toa-optional-runtime-gate.md b/docs/toa-optional-runtime-gate.md index b6b27f39f9..ce633a545a 100644 --- a/docs/toa-optional-runtime-gate.md +++ b/docs/toa-optional-runtime-gate.md @@ -25,8 +25,8 @@ it offline with a pinned emitter public key. - name: Verify tool delivery attestation if: hashFiles('toa.json') != '' run: | - pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@345f24607919b5bdf143719b9ea062543cdfe88e#subdirectory=python" - toa-verify toa.json --require-layer functional=pass + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@5a1bf1cf6a15a4864ea809fe7b2a073f2cef4e22#subdirectory=python" + toa-verify toa.json --require-emitter agentstatus --require-layer functional=pass --max-age 7d ``` Copy-paste workflow: [`examples/toa-after-runtime.yml`](../examples/toa-after-runtime.yml). diff --git a/examples/toa-after-runtime.yml b/examples/toa-after-runtime.yml index 5278d2bfe8..116cd0febc 100644 --- a/examples/toa-after-runtime.yml +++ b/examples/toa-after-runtime.yml @@ -19,5 +19,5 @@ jobs: - name: Verify tool delivery attestation if: hashFiles('toa.json') != '' run: | - pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@345f24607919b5bdf143719b9ea062543cdfe88e#subdirectory=python" - toa-verify toa.json --require-layer functional=pass + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@5a1bf1cf6a15a4864ea809fe7b2a073f2cef4e22#subdirectory=python" + toa-verify toa.json --require-emitter agentstatus --require-layer functional=pass --max-age 7d From 0c961051d5943804ac8ee093d9edb342b81aef06 Mon Sep 17 00:00:00 2001 From: AgentStatus Date: Sun, 30 Aug 2026 20:29:49 -0700 Subject: [PATCH 3/3] Docs: pin toa-verify to packaged-key release Carmel-Labs-Inc/toa@99e2690fec24a5290d9542e58383a8bf753e8b74 ships keys/agentstatus-v1.json inside the python package (toa#2). Signed-off-by: AgentStatus --- docs/toa-optional-runtime-gate.md | 2 +- examples/toa-after-runtime.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/toa-optional-runtime-gate.md b/docs/toa-optional-runtime-gate.md index ce633a545a..e963ff17dd 100644 --- a/docs/toa-optional-runtime-gate.md +++ b/docs/toa-optional-runtime-gate.md @@ -25,7 +25,7 @@ it offline with a pinned emitter public key. - name: Verify tool delivery attestation if: hashFiles('toa.json') != '' run: | - pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@5a1bf1cf6a15a4864ea809fe7b2a073f2cef4e22#subdirectory=python" + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@99e2690fec24a5290d9542e58383a8bf753e8b74#subdirectory=python" toa-verify toa.json --require-emitter agentstatus --require-layer functional=pass --max-age 7d ``` diff --git a/examples/toa-after-runtime.yml b/examples/toa-after-runtime.yml index 116cd0febc..6bbe08f272 100644 --- a/examples/toa-after-runtime.yml +++ b/examples/toa-after-runtime.yml @@ -19,5 +19,5 @@ jobs: - name: Verify tool delivery attestation if: hashFiles('toa.json') != '' run: | - pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@5a1bf1cf6a15a4864ea809fe7b2a073f2cef4e22#subdirectory=python" + pip install "git+https://github.com/Carmel-Labs-Inc/toa.git@99e2690fec24a5290d9542e58383a8bf753e8b74#subdirectory=python" toa-verify toa.json --require-emitter agentstatus --require-layer functional=pass --max-age 7d