Skip to main content
Parmana states its authorization claims in docs/CLAIMS.md. This page reports an audit that tested five of them against the code, with executed tests, not code reading alone. The audit lives in the repository under proof-audit/ and reruns with one command.

The five claims

Claim 5 depends on where the chain head is stored. The verifier can check an anchored head, but Parmana does not yet publish that head to an external store. Until a deployment does, deleting the newest audit record is undetectable from the database alone.

What the audit found and what changed

The audit found these gaps. Each is fixed in the code and covered by a test.
  • The gateway did not check the decision outcome. An authorization signed for a non-approved decision would release. The outcome is now signed into the authorization, and the gateway refuses anything that is not APPROVED.
  • A caller holding the in-process gateway attestation could release without a valid authorization. The execution control now verifies the signature, expiry, decision outcome and content hash itself before any connector runs.
  • Test and development environments skipped governance by default. Setting NODE_ENV alone relaxed the approval-record check. Relaxation now needs an explicit PARMANA_ALLOW_UNGOVERNED_POLICY=true in test or development. The policy content hash is always required.
  • A published policy version could be rewritten in place. A different-content write is refused with 409, and this is checked before any approval record is written.
  • HubSpot’s signal verification fetch was not bound to a policy hash. It now binds to the hash of the policy the gateway checks.
  • Disabled caller authentication and sandbox approvals could run in production. Both are now refused when NODE_ENV=production.

Still open

These items are known and not yet fixed.
  • Audit head anchoring. The verifier accepts an anchored head. Deployments need to publish it to a store the database cannot rewrite. This is an operator step.
  • HubSpot’s verification read is self-asserted. The connector helper that signs its read asserts APPROVED itself. The read is now confined to one capability by its own key, so a leaked key can read a deal but not change one. Removing the self-assertion needs the verification to go through a runtime decision.
  • The attestation key shares a process with the release control. A holder of valid signed authorizations who runs code in the API process can call the control directly and skip the gateway. The control still verifies the signature, the outcome, the content hash and the nonce, so an unsigned or replayed authorization is refused. Closing it needs the control in a separate process.
  • Coverage. KMS signing is not yet run by the audit, and neither is a live external connector endpoint. A live external connector endpoint is not yet in the audit.

Run the audit

npm run build must run before the tests. The tests load the workspace packages from their built dist/ folders and the generated OpenAPI artifacts. Without the build, several unrelated test files fail with missing-module errors, so a failure there does not say anything about the audit. npm test runs the whole repository suite and needs the same build. The audit’s case results are written to proof-audit/results/, one JSON file per claim. Each case has a PASS or FAIL verdict, so you can see exactly which conditions were tested.