> ## Documentation Index
> Fetch the complete documentation index at: https://docs.manthan.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# Bundle Verification

> Verify a policy bundle against the trust root

## What bundle verification checks

A policy bundle is the compiled, signed artifact that the runtime evaluates. Bundle verification confirms:

1. The bundle's `bundle_hash` matches the content of the bundle directory
2. The bundle manifest signature (`bundle.sig`) verifies against the trust root public key
3. The bundle was not modified after it was signed

***

## Bundle structure

A compiled policy bundle lives at `policies/{policyId}/{policyVersion}/`:

```
policies/
  claims-approval/
    1.0.0/
      policy.json              ← the policy rules (compiled form)
      bundle.manifest.json     ← content manifest with bundle_hash
      bundle.sig               ← Ed25519 signature over the manifest
```

***

## Using verifyBundle from @parmanasystems/core

```typescript theme={null}
import {
  verifyBundle,
  LocalVerifier,
} from "@parmanasystems/core";
import fs from "node:fs";
import path from "node:path";

const publicKey = fs.readFileSync("trust/root.pub", "utf8");
const verifier  = new LocalVerifier(publicKey);

const bundlePath = path.resolve("policies/claims-approval/1.0.0");

const result = verifyBundle(bundlePath, verifier);

console.log(result.valid);        // true
console.log(result.bundleHash);   // matches the bundleHash in attestations
console.log(result.policyId);     // "claims-approval"
console.log(result.version);      // "1.0.0"
```

***

## Matching bundle hash to attestation

Every attestation contains the `bundleHash` of the bundle that produced it. To verify that an attestation was produced from a specific bundle:

```typescript theme={null}
const result = verifyBundle(bundlePath, verifier);

if (attestation.bundleHash !== result.bundleHash) {
  throw new Error(
    "Attestation bundleHash does not match the bundle at " + bundlePath
  );
}

console.log("Bundle matches attestation");
```

***

## What the manifest contains

`bundle.manifest.json` example:

```json theme={null}
{
  "policyId": "claims-approval",
  "policyVersion": "1.0.0",
  "schemaVersion": "1.0.0",
  "bundle_hash": "sha256:abc123...",
  "files": [
    { "path": "policy.json", "hash": "sha256:def456..." }
  ],
  "compiledAt": "2024-01-10T08:00:00.000Z"
}
```

`bundle.sig` contains the Ed25519 signature over the canonical JSON serialization of the manifest.

***

## Expected result

A successful `verifyBundle` call returns:

```typescript theme={null}
{
  valid: true,
  bundleHash: "sha256:abc123...",
  policyId: "claims-approval",
  version: "1.0.0"
}
```

***

## Via the CLI

```bash theme={null}
npx @parmanasystems/verifier-cli verify-bundle \
  --bundle policies/claims-approval/1.0.0 \
  --public-key trust/root.pub
```

Expected output:

```
✓ Bundle signature verified
✓ Content hash matches
  policyId: claims-approval
  version:  1.0.0
  hash:     sha256:abc123...
```

***

## Troubleshooting

**`valid: false` — "signature verification failed"** The `bundle.sig` does not verify against `trust/root.pub`. Either the bundle was modified after signing, or the wrong public key is being used. Recompile and re-sign the bundle.

**`valid: false` — "content hash mismatch"** The `policy.json` or other bundle files were modified after the manifest was created. Recompile the bundle.

**Bundle loads but produces unexpected decisions** Bundle verification only confirms the bundle was not tampered with. If the policy rules produce unexpected outcomes, inspect `policy.json` and test using `POST /simulate`.
