Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ Streamable HTTP; the v0.3 `guard` proxy adds deterministic runtime *result* insp

## [Unreleased]

### Artifact trust foundation

- Add opt-in Ed25519 verification for existing policy, runtime, adapter and
executable-bundle activation APIs, with an independently pinned public-key
configuration and explicit artifact-kind signer roles.
- Add `trust roots-digest`, `trust prepare` and `trust verify` for enrollment
inspection, unsigned canonical review/signing artifacts, and offline signature
checks. Human signing stays external; signature validity alone does not permit
effects. Durable receipts and live guard integration remain separate work.

### Release engineering

- Add a manual `verify-pypi` production OIDC exchange check in the existing release
Expand Down
9 changes: 8 additions & 1 deletion DOCUMENTATION_INDEX.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Documentation Index — mcp-warden

Last Updated: 2026-10-02
Last Updated: 2026-10-03

Master index of every document in this repository. The `docs/` files are the
**security contract and source of truth** for all algorithms; the three core docs
Expand Down Expand Up @@ -155,6 +155,7 @@ scope-honesty box and makes no compliance/regulatory claim.

| Doc | Defines |
|-----|---------|
| [`docs/ARTIFACT_TRUST.md`](docs/ARTIFACT_TRUST.md) | Opt-in Ed25519 implementation of DSE-716's external artifact verifier: explicit key/kind roles, independently pinned canonical roots, exact version/kind/key-bound signing frame, unsigned review preparation and offline signature verification. No private signing capability, durable receipts, live guard wiring or whole-kernel claim |
| [`docs/PIN_CHECK_DEMO.md`](docs/PIN_CHECK_DEMO.md) | Full end-to-end pin/check walkthrough, archived out of `README.md` on 2026-08-24 to hold the 500-line core-doc limit |
| [`docs/SPEC.md`](docs/SPEC.md) | **MCP Lock Format v1** — the vendor-neutral, self-contained format specification any tool can implement: on-disk `warden.lock` schema, RFC 8785 (JCS) canonicalization, SHA-256 `sha256:<hex>` hashing, `overall_digest` construction, the normative drift class + severity table, the optional per-tool inspection block, and a Conformance section (§12.1: passing `vectors/` **is** conformance) + worked example. `WARDEN_LOCK_SCHEMA.md` is the mcp-warden implementation of this format |
| [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) | **(v0.1)** Positioning, trust model (TOFU + `--approve`), assets/actors, the four threat classes (MCP-DRIFT / MCP-CAPSURF / MCP-SECRET / MCP-SUPPLY), explicit out-of-scope limits, deliberate cuts |
Expand All @@ -177,6 +178,7 @@ scope-honesty box and makes no compliance/regulatory claim.

| Plan | Purpose |
|---|---|
| [`docs/plans/2026-10-03-checkpoint-artifact-trust.md`](docs/plans/2026-10-03-checkpoint-artifact-trust.md) | First human-checkpoint development wave: opt-in signature verification and unsigned review tooling, with unpublished DSE-717 work preserved and live DSE-1076 integration still dependent on it |
| [`docs/plans/2026-07-18-agent-trust-kernel-design.md`](docs/plans/2026-07-18-agent-trust-kernel-design.md) | **Non-normative execution record.** Records the DSE-714 design decision and verification plan; binding requirements live in `docs/AGENT_TRUST_KERNEL.md` |
| [`docs/plans/2026-07-18-content-envelope-design.md`](docs/plans/2026-07-18-content-envelope-design.md) | **Non-normative DSE-715 execution record.** Records the reviewed strict-TDD plan; verified behavior is documented in `docs/CONTENT_ENVELOPE.md` |
| [`docs/plans/2026-07-19-pdp-pep-design.md`](docs/plans/2026-07-19-pdp-pep-design.md) | **Non-normative DSE-716 execution record.** Records the activated-snapshot, structural-PEP, TDD, and review plan; verified behavior is documented in `docs/POLICY_ENFORCEMENT.md` |
Expand Down Expand Up @@ -212,6 +214,11 @@ scope-honesty box and makes no compliance/regulatory claim.

## Source layout

`src/mcp_warden/artifact_payload.py`, `artifact_trust.py`, and `cli_trust.py` implement
the strict existing-artifact decoder, opt-in public-key verifier, and unsigned
review/signature CLI. Tests are `tests/test_artifact_trust.py`,
`test_cli_trust.py`, and `test_artifact_trust_integration.py`.

| Module | Responsibility | Spec anchor |
|--------|----------------|-------------|
| `src/mcp_warden/hashing.py` | `canon()` (RFC 8785) + `hash()` + field hashes | WARDEN_LOCK_SCHEMA §3 |
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mcp-warden

Last Updated: 2026-10-02
Last Updated: 2026-10-03

[![CI](https://github.com/DataScience-EngineeringExperts/mcp-warden/actions/workflows/integrity-gate.yml/badge.svg)](https://github.com/DataScience-EngineeringExperts/mcp-warden/actions/workflows/integrity-gate.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Expand All @@ -24,6 +24,13 @@ The [upgrade plan and checkpoint proposal](docs/plans/2026-10-02-tool-integrity-
maps prompts, retrieval, code execution, and serverless adapters to existing Agent
Trust Kernel work. Those broader checkpoints are proposals, not shipped guarantees.

The opt-in [artifact trust foundation](docs/ARTIFACT_TRUST.md) adds public-key
verification for the existing kernel activation APIs and `trust` CLI commands
to prepare unsigned review artifacts and verify external signatures. Keys and
signer roles require an independently protected root pin. This development
feature is not in the published 2.0.0 package; live checkpoint enforcement still
depends on DSE-717 evidence and DSE-1076 guard integration.

> ⚠️ **Install `mcp-warden-cli`, not `mcp-warden`.** The PyPI name `mcp-warden` is
> an **unrelated package by a different author** — it is not this project. The
> correct install is `pip install mcp-warden-cli` (the CLI command is still
Expand Down
9 changes: 8 additions & 1 deletion SYSTEM_CONTEXT_DIAGRAM.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mcp-warden — System Context Diagram

Last Updated: 2026-10-02
Last Updated: 2026-10-03

**CLI 2.0.0 / schema level 4** extends capture/lock/check to complete tool annotations and output
schemas, with structural output drift and Python/TypeScript parity. The existing
Expand Down Expand Up @@ -38,6 +38,11 @@ logic) plus a separate informational provenance section. It never prints raw
> branch), but it must still deliver durable signed evidence, fallback, rollback-resistant state,
> and the recovery latch. The current `guard` path is not represented as ATK-conformant.

> The opt-in [artifact verifier](docs/ARTIFACT_TRUST.md) implements DSE-716's external
> signature port using pinned Ed25519 public keys and explicit artifact-kind roles.
> `trust prepare` emits unsigned review/signing bytes; `trust verify` checks signatures
> only. Human signing remains external and the root pin must be host-protected.

> `conclave` (the 4-model adversarial council referenced in `docs/THREAT_MODEL.md`)
> is a **dev-time design reviewer** that shaped this contract. It is **NOT** a
> runtime dependency and is never invoked by `pin`/`check`/`policy`.
Expand Down Expand Up @@ -109,9 +114,11 @@ flowchart TB

envelope["Content Envelope V1\nDSE-715 · implemented evidence foundation\nNOT wired to guard · grants no authority"]
decision["Deterministic PDP/PEP V1\nDSE-716 · signed adapter/bundle gates + fixed corpus\nNOT wired to guard"]
artifactTrust["Opt-in Ed25519 artifact verifier\nartifact_trust.py · protected root pin + key roles\ntrust CLI: unsigned preparation / signature verification"]
evidence["Durable evidence + recovery state\nDSE-717 · IN PROGRESS\ncurrent default gate denies effects"]
atk -. "governs partial foundation" .-> envelope
envelope -. "required input" .-> decision
artifactTrust -. "external signature verification port" .-> decision
decision -. "requires production gate" .-> evidence

subgraph ci["CI pipeline (GitHub Actions / local)"]
Expand Down
60 changes: 60 additions & 0 deletions docs-site/artifact-trust.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Verify externally approved artifacts

The development branch adds public-key signature verification for Agent Trust
Kernel policy, runtime, adapter, and executable-bundle artifacts. This feature
is not included in the published **2.0.0** package. Install a reviewed Git commit
with the `artifact-trust` extra to use it.

It prepares unsigned review artifacts and verifies external Ed25519 signatures.
Live human-checkpoint enforcement still requires the durable evidence layer and
guard integration.

## Enroll public keys and signer roles

Configure the public keys and the artifact kinds each key may sign. Keep the
private signing capability in an independently governed external signer, outside
agent and tool access.

```bash
mcp-warden trust roots-digest public-roots.json
```

This prints a candidate root digest and signer identities for independent
enrollment review. Pin the reviewed digest through a protected host boundary.
An agent-controlled roots file and matching agent-controlled pin do not
establish trust.

## Prepare an unsigned review artifact

```bash
mcp-warden trust prepare policy policy-draft.json \
--signer "$ENROLLED_SIGNER_DIGEST" \
--canonical-out policy.canonical.json \
--signing-out policy.signing.bin
```

Review the canonical artifact together with its resolved grant/lease bindings.
Then have the external signer sign the exact prepared bytes. Preparation does
not approve the artifact or execute an action. Both output paths must be new.

## Verify the returned signature

```bash
mcp-warden trust verify policy policy.canonical.json \
--roots public-roots.json \
--roots-digest "$PROTECTED_ROOTS_DIGEST" \
--signer "$ENROLLED_SIGNER_DIGEST" \
--signature policy.sig
```

Success reports `signature-verified`. The variables here illustrate values
provided by the trusted host; writable environment variables alone are not a
protected boundary. The signature must be exactly 64 raw bytes.

Signature validity alone does not check current authority, expiry, revocation,
dependency measurements, or whether an action is allowed. Existing activation
and policy enforcement APIs remain responsible for those checks. The default
evidence gate continues to block effects pending durable evidence integration.

See the [artifact trust contract](https://github.com/DataScience-EngineeringExperts/mcp-warden/blob/main/docs/ARTIFACT_TRUST.md)
for the roots schema, exact signing frame, SDK usage and remaining dependencies.
6 changes: 4 additions & 2 deletions docs/AGENT_TRUST_KERNEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,10 @@ foundation harness with registration evidence, multiple serialized output-channe
non-optional versioned malformed-input corpus. The default evidence gate denies every otherwise
allowed effect.

This is still a partial implementation. It is not wired into the historical `guard`, supplies no
built-in production verifier or live protocol adapter, and does not implement DSE-717's durable
This is still a partial implementation. It is not wired into the historical `guard`. A separate
opt-in [artifact trust verifier](ARTIFACT_TRUST.md) implements the signature port using explicit
public-key/role roots and an independently protected digest pin. It supplies no live protocol
adapter and does not implement DSE-717's durable
signed receipts, independent fallback evidence, rollback-resistant state, or persistent recovery
latch. A custom evidence gate becomes TCB code and does not create an ATK-conformance claim. No
production effect or whole-kernel claim is valid until DSE-717 closes ATK-10 through ATK-12 and
Expand Down
160 changes: 160 additions & 0 deletions docs/ARTIFACT_TRUST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Public-key governance artifact trust

This opt-in verifier implements the existing DSE-716 `ArtifactVerifierV1` port
for externally signed policy, runtime, adapter, and executable-bundle artifacts.
It is a foundation for human checkpoints. It does not wire those checkpoints
into the historical `guard`, implement DSE-717's durable receipts or protected
state, or establish whole-kernel conformance.

## Trust and key custody

Install this development branch with the `artifact-trust` extra. The published
2.0.0 package does not include this feature. No signing command, private-key
loader, or key generator exists in the product. Use an independently governed
external signing service or signing station; keep its private signing capability
outside agent/tool access. The external signer must review the canonical
artifact and sign exactly the prepared frame, not merely a displayed summary.

The consumer explicitly configures raw Ed25519 public keys and the artifact
kinds each may sign. Governance and runtime signing roles should use separate
keys. In particular, a key allowed to sign reviewed policy or executable bundles
does not acquire permission to attest to runtime health or trusted time.

The consumer MUST obtain `expected_roots_digest` through a protected trusted
boundary independent of the roots file and artifact. The complete key AND role
configuration is pinned. Computing a digest from attacker-supplied roots and
immediately passing it as the pin does not establish trust. Replacing both roots
and pin defeats this local boundary; filesystem permissions and custody belong
to the embedding host. This verifier provides no protection against host/TCB or
authorized-admin compromise.

## Public roots format

```json
{
"schema_version": 1,
"keys": [
{
"public_key": "<64 lowercase hex characters encoding 32 raw public-key bytes>",
"artifact_kinds": ["adapter", "bundle", "policy"]
}
]
}
```

Replace the illustrative public-key placeholder with an enrolled public key.
Kinds are a nonempty, sorted, duplicate-free subset of `adapter`, `bundle`,
`policy`, `runtime`. Duplicate keys, unknown fields, unsupported schemas,
non-finite numbers, and duplicate JSON object keys are rejected. Roots are
bounded to 64 keys and 64 KiB. SDK records are immutable; verification snapshots
the public keys and allowed roles.

Let `H(domain, bytes)` be `sha256:` plus the lowercase hexadecimal SHA-256 of
`ASCII(domain) || 0x00 || bytes`.

- Signer identity: `H("mcp-warden/artifact-signature/v1/key-id", raw_public_key)`.
- Roots digest: `H("mcp-warden/artifact-signature/v1/roots", canonical_roots)`.
- Canonical roots: RFC 8785 JSON with `schema_version: 1`, keys sorted by signer
identity, public keys encoded as lowercase hex, and kinds sorted as above.

The signer identity identifies a key, not a verified human name. The operator's
external enrollment record binds that key to a human or service and its role.
Adding/removing a key or changing its roles changes the root pin. Root freshness,
rotation and revocation require independently governed configuration updates;
the verifier does not infer them from untrusted input.

## Signature format

Sign the exact byte concatenation:

```text
ASCII("mcp-warden/artifact-signature/v1") || 0x00 ||
ASCII(artifact_kind) || 0x00 || ASCII(signer_identity) || 0x00 ||
canonical_artifact_payload
```

Use Ed25519 and a raw detached 64-byte signature. The existing external port
selector remains `VerificationAlgorithmV1.EXTERNAL_V1`; this implementation
does not negotiate algorithms. There is no base64/hex/signature-envelope
autodetection. Kind, key identity and format version are signed to prevent
cross-role/context reuse. Signing raw artifact JSON without the frame is invalid.

The payload is the existing canonical serialization from
`canonical_policy_bytes`, `canonical_runtime_bytes`, `canonical_manifest_bytes`,
or `canonical_bundle_manifest_bytes`. Preparation accepts an unambiguous JSON
draft and validates the strict existing model. Verification requires exact
canonical bytes. Unknown artifact fields and schemas are rejected; schema
integers cannot be booleans. The global input cap is 512 KiB, with narrower
existing artifact caps retained.

## Offline CLI workflow

Enrollment inspection prints the candidate root digest and derived signer
identities. A trusted administrator independently reviews/enrolls the keys and
roles and pins this digest; the command itself does not approve enrollment.

```bash
mcp-warden trust roots-digest public-roots.json
mcp-warden trust prepare policy policy-draft.json \
--signer "$ENROLLED_SIGNER_DIGEST" \
--canonical-out policy.canonical.json --signing-out policy.signing.bin
```

The second command creates an **unsigned** canonical review artifact and exact
signing frame. Outputs must be new files. Input/output collisions and clobbering
are rejected; failures clean up newly created outputs. Review all resolved
grants/leases and their subject, input, action, argument, destination, policy and
version bindings before signing externally. A policy's digest-only grants are
not a substitute for that review package.

After the external signer returns `policy.sig`:

```bash
mcp-warden trust verify policy policy.canonical.json \
--roots public-roots.json --roots-digest "$PROTECTED_ROOTS_DIGEST" \
--signer "$ENROLLED_SIGNER_DIGEST" --signature policy.sig
```

`$PROTECTED_ROOTS_DIGEST` and `$ENROLLED_SIGNER_DIGEST` above are illustrative
values supplied by the trusted host; environment variables writable by the
agent do not create a protected boundary. Success emits `signature-verified`;
it is not an execution authorization. Failure exits 2 with a code-only error and
no raw artifact, signature, key file, or lower-layer exception text.

## SDK activation

```python
from mcp_warden.artifact_trust import Ed25519ArtifactVerifierV1, parse_roots
from mcp_warden.policy_decision import activate_policy

# The host supplies protected_roots_digest independently and bounds roots_bytes.
verifier = Ed25519ArtifactVerifierV1(
parse_roots(roots_bytes), expected_roots_digest=protected_roots_digest
)
active_policy = activate_policy(signed_policy_candidate, verifier=verifier)
```

The same verifier can be passed to `activate_runtime`, `activate_adapter`, and
`activate_executable_bundle`, with separately enrolled roles. Existing APIs
still require exact request/lease/policy matching and actual adapter, handler,
artifact and dependency evidence. Invalid signatures return false through the
verification port and fail activation. Missing optional crypto support fails
explicitly with `TRUST-CRYPTO-UNAVAILABLE`.

## Limits and next dependencies

A valid signature authenticates exact bytes under an enrolled key/role. It does
not establish that code/content is safe, authenticate every tool result, clear
taint, verify current executable measurements, or permit effects. It also does
not enforce expiry, trusted time, revocation or rollback floors by itself.
Existing PDP/PEP policy/runtime checks remain necessary; an expired artifact can
have a mathematically valid signature while being unusable for authorization.

The default evidence gate continues to permit nothing. DSE-717 must deliver
durable signed receipts, negative-decision fallback, rollback-resistant state
and recovery before DSE-1076 can connect the kernel to live `guard`. Its recorded
unpublished implementation must be recovered rather than duplicated.

Tests use ephemeral test-only private keys for all four real activation paths,
key/role/kind/payload substitution, invalid parsing/pins, dependency drift, and
proof that valid signatures cannot bypass the default evidence gate.
6 changes: 4 additions & 2 deletions docs/POLICY_ENFORCEMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ module markers are outside the supported API and are TCB compromise, not an auth
not silently upgraded and is not ATK-conformant.
- DSE-716 APIs are importable client-agnostic foundations, not a new CLI command or deployed
runtime adapter.
- No built-in production verifier, durable evidence gate, recovery store, or live protocol
adapter is selected by this ticket.
- DSE-716 itself selects no built-in verifier. The separate opt-in
[artifact trust foundation](ARTIFACT_TRUST.md) now implements its external verifier port
with pinned public keys and explicit signer roles; it supplies no durable evidence gate,
recovery store, or live protocol adapter.
- DSE-717 remains required before any whole-kernel or production effect claim.
Loading
Loading