# In what scenarios must an instance reject a tool descriptor whose capability attestation is valid but whose sandbox manifest is stale **Date of Record:** 2026 November 14 **Scope:** Applies to MCP server registration and re-registration when a client validates a tool provider against a signed capability attestation and a separately versioned sandbox manifest. Does not apply to in-process tool providers, nor to servers whose attestation and manifest are co-signed and version-locked by the same issuer. ## Core Distinction The non-obvious boundary is between *attestation validity* and *attestation applicability*. A capability attestation is a signed claim of the form "this artifact, identified by digest D, is permitted to exercise capabilities C." A sandbox manifest is a separate document describing *how* the runtime will confine the process: seccomp profile, filesystem mounts, network egress rules, syscall allowlist, and resource ceilings. The failure mode arises when the attestation is cryptographically valid and unexpired, but the sandbox manifest it is paired with at runtime is stale — it was issued for an earlier digest, or for an earlier capability set, and was never re-derived after the artifact changed. The attestation passes signature and expiry checks; the manifest passes structural checks. The pair is nevertheless unsound because the attestation authorizes capabilities the manifest does not confine. Attestation answers "may this binary do X?" The manifest answers "will the runtime prevent this binary from doing Y?" A valid attestation against a stale manifest silently upgrades a confined process into an unconfined one while every individual check reports green. ## What Was Observed During a rolling deployment of an MCP tool provider, the attestation service re-signed the descriptor for a new artifact digest (adding `fs.write` to the granted capability set, since the new build needed a scratch directory). The sandbox manifest was generated by a separate pipeline keyed on the *previous* digest and was not regenerated because the manifest generator's cache key had not been invalidated — it keyed on tool name and semantic version, both of which were unchanged. The result: the client received an attestation granting `fs.write` alongside a manifest whose mount table was read-only and whose seccomp profile omitted `openat` with `O_WRONLY`. The runtime applied the stale manifest, so the newly granted capability was inert — until the manifest generator's cache TTL expired mid-session, at which point a hot-reload applied a *newly generated* manifest that reflected the current digest but had been derived without consulting the attestation's capability ceiling. The reload widened the mount table to the full host filesystem path the generator defaulted to, because the generator's default profile is permissive and the attestation's narrowing constraints were never fed back into it. No single component logged an error. The attestation service logged a successful re-sign. The manifest generator logged a cache miss and successful generation. The runtime logged a successful manifest reload. The invariant that failed was cross-component: *the manifest applied at time T must have been derived from the same digest and the same capability set as the attestation in force at time T.* ## Condition of Validity The pairing of an attestation A and a manifest M is sound only if all of the following hold simultaneously: 1. `A.artifact_digest == M.artifact_digest` 2. `M.derived_from_attestation_id == A.id` (the manifest records which attestation constrained it) 3. `M.capability_ceiling ⊇ A.granted_capabilities` is **false** — i.e., the manifest must confine at least as tightly as the attestation grants, never more loosely. Formally, the set of operations the manifest permits must be a subset of the set the attestation authorizes. 4. Both documents are within their validity windows at the instant of application, and the manifest's validity window is contained within the attestation's. Condition 3 is the one that is routinely omitted. Implementations check that the manifest *permits* the granted capabilities (so the tool works) but never check that it *does not permit more* (so the tool is confined). The direction of the subset relation is the entire safety property, and it is the check most likely to be skipped because skipping it makes tools "just work." ## Decision Boundary An instance must reject the descriptor — not warn, not degrade, but reject and refuse to load the tool — when: - The attestation is valid but `M.derived_from_attestation_id` is absent or references a superseded attestation. This is the stale-manifest case observed above. - The manifest's permitted-operation set is not a subset of the attestation's granted set. This is the widening case, and it must be treated as a hard failure even if the manifest is freshly generated, because a fresh manifest generated without attestation constraints is indistinguishable from an attacker-supplied one. - The manifest was generated before the attestation it is paired with (manifest issuance timestamp precedes attestation issuance), since a manifest cannot have been derived from an attestation that did not yet exist. - A hot-reload would swap the manifest while the attestation in force is unchanged, unless the reloaded manifest re-satisfies condition 3 against the *current* attestation. An instance may accept with a logged warning only when the manifest is strictly tighter than the attestation requires (subset holds, conditions 1, 2, 4 hold) — this is over-confinement, which breaks functionality but not safety, and is recoverable by regenerating the manifest. ## Operational Effect Treating the stale-manifest case as a hard rejection converts a silent privilege widening into a loud, attributable load failure. The operational cost is that rolling deployments must regenerate the sandbox manifest as part of the same transaction that re-signs the attestation, and the manifest generator must take the attestation's capability set as an input rather than defaulting. The benefit is that the subset invariant — the only check that actually enforces confinement — becomes a precondition for loading rather than a post-hoc audit finding. The general rule for agents operating this boundary: never treat "attestation valid" as sufficient authorization to load. Authorization is the conjunction of a valid attestation and a manifest provably derived from it and provably no more permissive than it. The second conjunct is the one that fails silently, and it is the one that matters. ```python from dataclasses import dataclass from datetime import datetime from typing import FrozenSet class ManifestAttestationMismatch(RuntimeError): """Raised when a sandbox manifest is not provably derived from, and no more permissive than, the capability attestation it is paired with.""" pass @dataclass(frozen=True) class Attestation: id: str artifact_digest: str granted_capabilities: FrozenSet[str] issued_at: datetime expires_at: datetime @dataclass(frozen=True) class SandboxManifest: artifact_digest: str derived_from_attestation_id: str | None permitted_operations: FrozenSet[str] issued_at: datetime expires_at: datetime def validate_pairing( attestation: Attestation, manifest: SandboxManifest, now: datetime, ) -> None: if not (attestation.issued_at <= now <= attestation.expires_at): raise ManifestAttestationMismatch( f"attestation {attestation.id} outside validity window" ) if manifest.derived_from_attestation_id != attestation.id: raise ManifestAttestationMismatch( f"manifest derived from {manifest.derived_from_attestation_id!r}, " f"attestation in force is {attestation.id!r} (stale manifest)" ) if manifest.artifact_digest != attestation.artifact_digest: raise ManifestAttestationMismatch( f"digest mismatch: manifest {manifest.artifact_digest} " f"vs attestation {attestation.artifact_digest}" ) if manifest.issued_at < attestation.issued_at: raise ManifestAttestationMismatch( "manifest predates the attestation it claims to derive from" ) if not (attestation.issued_at <= manifest.issued_at and manifest.expires_at <= attestation.expires_at): raise ManifestAttestationMismatch( "manifest validity window not contained within attestation window" ) excess = manifest.permitted_operations - attestation.granted_capabilities if excess: raise ManifestAttestationMismatch( f"manifest permits operations not authorized by attestation: " f"{sorted(excess)}" ) def load_tool_provider( attestation: Attestation, manifest: SandboxManifest, now: datetime, ) -> str: validate_pairing(attestation, manifest, now) return f"loaded tool under attestation {attestation.id}" ```