Threat model
Seal is a defence against a specific class of supply‑chain risk: AI agent bundles whose files have changed since you last reviewed them. This page describes precisely what is in scope, what is out of scope, and the design choices that follow.
The threat surface
Section titled “The threat surface”AI agent bundles are external, untrusted inputs to agent behavior and tool use. Depending on the host, they may be interpreted, executed, or used to configure an agent that has its own sandbox and permission model. They can still steer code changes, tool calls, automation, and accessible data inside those boundaries.
Seal detects differences from the pinned contents, whether malicious or legitimate. The CLI reports those differences when invoked and applies policy to its exit code. Preventing an agent from loading a changed bundle requires a native integration in the load path.
In scope
Section titled “In scope”Supply‑chain compromise
Section titled “Supply‑chain compromise”A bundle author’s account is compromised and a malicious update is installed locally. If the approved lockfile is unchanged, Seal detects the difference when verification runs. A CI gate can stop subsequent pipeline steps; only a load-time integration can enforce the check at the moment an agent consumes the bundle.
Silent updates
Section titled “Silent updates”A legitimate update adds a hook, modifies a prompt, or changes a helper script. Seal reports the changed contents against the previous snapshot. New bundles are also detected when they match a configured discovery pattern. Paths outside discovery and existing sealed roots are outside the standalone CLI’s coverage.
Out of scope
Section titled “Out of scope”Malicious bundles at first install
Section titled “Malicious bundles at first install”Seal verifies that files have not changed since they were pinned. It does not assess whether a bundle is safe to install in the first place. First‑install review is the user’s responsibility.
Lockfile tampering
Section titled “Lockfile tampering”seal.json is the baseline verification trusts. An attacker who changes both a bundle and its recorded hashes can make verification pass. Protect changes to the lockfile, discovery patterns, policy, and verification workflow through repository review and access controls. Hashes do not record who approved a change or establish author identity.
Runtime behaviour
Section titled “Runtime behaviour”Seal verifies files at rest. It does not monitor what a bundle does during execution. A bundle that passes verification can still behave maliciously if its reviewed code was malicious to begin with.
External and transitive dependencies
Section titled “External and transitive dependencies”Consider a pinned helper script containing:
curl -fsSL https://example.com/install.sh | bashSeal checks the local script’s bytes. If the remote payload changes while that script stays identical, verification can still pass. Seal does not fetch the URL, inspect the script for dependencies, or traverse and pin the complete execution chain.
The same limit applies to remotely fetched prompts, runtime API responses, and files read from outside the sealed root. An entry covers regular files beneath its own root; an external file is only covered if another applicable entry seals it. Bundled dependencies inside that root are hashed, but that does not make execution hermetic.
Host and runtime dependencies
Section titled “Host and runtime dependencies”The agent runtime, /bin/sh, interpreter binaries, and system libraries are outside the sealed content root in Seal v1, unless a bundle vendors those files inside its own sealed root.
Fail-closed by default
Section titled “Fail-closed by default”For the standalone CLI:
- Default policy is
block. Mismatched or unverified bundles produce Blocked and exit1. Underwarn, they produce Warning and exit0. - Invalid or missing lockfile: verification stops and exits
2, regardless of policy. The CLI only reads the lockfile in its current working directory. - Removed bundles: deleting an entire sealed root produces Removed and does not block by itself. Deleting a file inside a still-present directory bundle produces Mismatch.
- Supervised pinning: changes require interactive confirmation. That prompt is a workflow safeguard; it does not prevent someone with write access from editing the lockfile directly.
Native integrations have additional obligations: verify immediately before loading and unconditionally suppress project-external extensions in sealed projects. The standalone CLI does not control an agent’s loading behavior or suppress its global plugins.
Time‑of‑check / time‑of‑use
Section titled “Time‑of‑check / time‑of‑use”An implementation MAY verify on session start to surface mismatches early, but session‑start verification alone is not sufficient. To provide time‑of‑check / time‑of‑use protection, an implementation MUST verify a bundle immediately before loading or executing any code, prompt, hook, script, template, tool definition, or other loadable resource from that bundle.
The standalone CLI checks a snapshot at the time it is invoked. A successful check does not protect against subsequent writes. Enforcement in the load path is up to each agent’s native integration. See for agent authors.
What “every change” means
Section titled “What “every change” means”False positives are noisy diffs on update. False negatives are missed compromises. Seal accepts the first to avoid the second:
- If a tracked file cannot be read during hashing (an OS error, a deleted file, a permissions glitch), the implementation MUST treat it as a Modified file rather than crashing.
- Symlinks and other non‑regular files are unsupported in v1. During
verify, encountering one classifies the bundle as Mismatch; duringpin, it aborts the operation. - Dependency directories like
node_modulesorvendorare tracked if they live inside the sealed root. Bundle authors who want clean diffs should not ship dependency directories.
This is intentional. A simple, fail‑closed rule beats a format‑specific exclusion list when the goal is integrity.