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.
What is cryptographically guaranteed
Every ExecutionAttestation carries an Ed25519 signature over a canonical JSON payload. The signing is performed in pipeline.ts stageSign and is the last step before the attestation is returned.
What IS signed
Every field in the attestation body is included in the canonical payload before signing:
| Field | What it commits to |
|---|
executionId | Unique operational identity of this execution event |
execution_fingerprint | SHA-256 of {policyId, policyVersion, signals} — binds decision to inputs |
policyId | Which policy was evaluated |
policyVersion | Which version of that policy |
schemaVersion | Which schema version was used |
runtimeVersion | Which runtime version executed the decision |
signalsHash | The execution_fingerprint as the canonical signal commitment |
decision | The actual decision: action, requires_override, reason |
execution_state | "completed", "blocked", or "pending_override" |
runtimeHash | SHA-256 of the canonical runtime manifest — binds to a specific build |
bundleHash | SHA-256 of the policy bundle — binds to a specific policy artifact |
manifestHash | SHA-256 of the bundle manifest file |
manifestSignature | Ed25519 signature over the bundle manifest |
trustRootVersion | Version of the trust root that signed the bundle |
signerKeyId | Identity of the key that signed the bundle |
evaluatorHash | SHA-256 of the evaluator schema declaration |
releaseManifestHash | SHA-256 of the release manifest — binds to a specific SDK release |
The canonical form is produced by canonicalizeAttestation() in execution-attestation.ts, which applies the PARMANA_ATTESTATION_V1 signing domain prefix before Ed25519 signing.
What is NOT signed
| Item | Reason |
|---|
| The signals themselves | Signals are committed via execution_fingerprint (their SHA-256 hash) |
| What the system does after the decision | Parmana governs decisions, not downstream execution |
| The identity of the API caller | Authentication is outside the governance scope |
| The timestamp of the call | Wall-clock time is non-deterministic and excluded from the sealed scope |
The signing chain
Every attestation is bound to a chain of hashes that links the trust root to the specific policy, runtime, and release that produced it:
Trust root key (Ed25519 PEM)
│
└─ signs → bundle.manifest.json
│ bundleHash — content hash of all policy files
│ manifestSignature — Ed25519 over manifest
│
└─ policy.json
│ policyId, policyVersion, rules, signalsSchema
│
Runtime manifest
│ runtimeHash — SHA-256 of { runtimeVersion, capabilities, supported_schemaVersions }
│ evaluatorHash — SHA-256 of { evaluator: "schema-v1", supported_schemaVersions }
│
Release manifest
│ releaseManifestHash — SHA-256 of the release-manifest.json
All of the above are included in the attestation body.
The entire body is signed with the same trust root key.
An independent verifier who has only the public key can confirm all of these links without access to any runtime or database.
Signing invariants
| Code | Invariant |
|---|
INV-008 | The governed field is always in signature scope and equals literal true |
INV-034 | Any verifier holding the correct public key can independently verify an attestation |
INV-035 | Verification is reproducible: same attestation + key produces identical outcome |
INV-037 | Signatures from different authority keys do not cross-verify — signing domains are isolated |
INV-038 | Cross-key verification failures are consistent: wrong-key always returns false |
INV-060 | Attestation verification is idempotent: same inputs always produce identical results |
META-001 | Every governed execution produces a signed, independently verifiable attestation |
Signature verification
verifyAttestation() from @parmanasystems/verifier reconstructs the exact canonical payload and verifies the Ed25519 signature:
import { verifyAttestation } from "@parmanasystems/core";
import { LocalVerifier } from "@parmanasystems/core";
const verifier = new LocalVerifier(publicKeyPem);
const result = verifyAttestation(attestation, verifier);
console.log(result.valid); // true or false
console.log(result.checks.signature_verified); // Ed25519 check
console.log(result.checks.runtime_verified); // runtimeHash check
console.log(result.checks.schema_compatible); // schemaVersion check
Verification requires only the public key and the attestation. No database, no runtime, no infrastructure access.
Signing domains
Each type of signed payload uses a different domain prefix, so a signature over one payload type cannot be mistaken for another:
| Domain | Used for |
|---|
PARMANA_ATTESTATION_V1 | ExecutionAttestation — produced by stageSign in pipeline.ts |
PARMANA_AUDIT_V1 | ExecutionIntegrityProof — produced by confirmExecution |
A signature over an audit payload cannot be verified as an attestation signature, and vice versa (INV-037).
What tamper-proof means
If any signed field in an ExecutionAttestation is altered after signing, the signature check fails:
| Field altered | Effect |
|---|
decision.action changed | Signature fails — the canonical payload no longer matches |
execution_fingerprint changed | Signature fails — the fingerprint is part of the signed body |
policyVersion changed | Signature fails |
bundleHash changed | Signature fails |
runtimeHash changed | Signature fails |
evaluatorHash changed | Signature fails |
| Any other signed field changed | Signature fails |
Any change to any signed field is detectable by any party holding the public key.
What tamper-proof does not mean
Tamper-proof means the record cannot be altered after signing. It does not mean:
| Claim | Reality |
|---|
| The input signals were accurate | Signals are self-reported by the caller |
| The downstream execution happened | Parmana attests decisions, not downstream effects |
| No other execution happened | Parmana does not observe downstream systems |
These limitations are intentional and are addressed by confirmExecution (for reporting downstream execution) and future signal provenance features (for verified inputs). See The Execution Gap for the honest positioning.
Use Cases
Independent IRDAI audit of insurance claim attestations
An IRDAI auditor receives a batch of motor insurance claim attestations from a regulated insurer. The auditor runs verifyAttestation on each record using only the insurer’s public key. Any record where result.checks.signature_verified is false indicates that the attestation body was altered after signing — the exact field that changed cannot be determined, but the tamper is detectable. The auditor does not need access to the insurer’s runtime, database, or infrastructure. INV-034 and INV-035 guarantee this check is reproducible and conclusive.
Proving a policy version governed a credit decision
An NBFC is challenged on a loan rejection: the borrower claims the decision was made using an outdated policy. The NBFC retrieves the attestation from its audit database. The bundleHash field in the attestation is the SHA-256 of the policy bundle used at evaluation time. The regulator independently recomputes the hash of the signed policy bundle on record and compares it to bundleHash. If they match, the attestation proves exactly which policy version governed the decision — tamper-evident, without relying on server logs.
Detecting cross-domain signature confusion
A security researcher attempts to use an ExecutionIntegrityProof signature (signed under PARMANA_AUDIT_V1) as if it were an ExecutionAttestation signature (signed under PARMANA_ATTESTATION_V1). INV-037 enforces signing domain isolation — the domain prefix is included in the canonical payload before signing, so the wrong-domain signature fails verification. INV-038 guarantees the failure is consistent: the same wrong-key or wrong-domain check always returns false, never an ambiguous result.
See also