NaZelo Trust — Evidence Contract (v0.1-draft)¶
The canonical, format-agnostic model of what NaZelo Trust proves. Wire formats (native bundle, in-toto, EAT, SCITT) are projections of this model. This document is the invariant; everything downstream — emitters, verifier, witness, admission policy — implements it.
It is a contract, not prose: an emitter that cannot fill a required field, or a class it cannot substantiate, MUST refuse to emit, not emit a weaker claim under a stronger name.
0. The one rule¶
Evidence attests only what a controlled boundary observed. An absence of a record is never evidence of absence in the system. Anything not understood is refused (fail-closed), and the refusal is itself observed evidence — not a gap. Assurance is declared and validated, never inferred.
Corollary: re-sealing data a system emitted about itself (a log, a trace, a decision-log) proves content integrity since sealing and nothing more. It never becomes proof of enforcement or of completeness. Doing so is the exact half-solution this contract exists to forbid.
1. Four non-fungible assurance classes¶
| Class | Definition | Proves | Does NOT prove |
|---|---|---|---|
| Imported | Data produced by a system about itself, then sealed. | The content is intact since the seal. | That the events are complete; that anything was enforced; that an absence is real. |
| Observed | A fact witnessed by a controlled boundary the workload does not control. | The boundary saw this. | That the boundary also blocks; posture; external durability. |
| Enforced | A fact witnessed by the component that authorizes/blocks. | The enforcer decided AND acted, and saw the result. | Durability against an operator who rewrites the record. |
| Attested | Enforced and a scoped posture attestation and an external witness. | Enforcement under a declared, attacked perimeter, anchored outside the host. | Anything outside the declared perimeter (root/kernel/hypervisor compromise). |
Non-fungibility rule. A lower class NEVER becomes a higher one by re-sealing,
aggregation, correlation, or the passage of time. assurance_class is validated
against the fields below, never asserted by the producer.
2. The canonical Assertion¶
Every assertion carries these fields. A missing required field ⇒ refuse to emit.
| Field | Meaning |
|---|---|
assertion_type + version |
e.g. egress.blocked/1, posture.isolation/1, policy.decision/1, certification.ghost/1. |
subject |
What it is about: {artifact_digest?, run_id, tenant, app}. |
source_identity |
Who observed/produced it: {component, key_id}. |
observation_mode |
How the fact was captured: imported | observed | enforced. (attested is not a capture mode — it is an assurance_class reached only via a scoped posture attestation + external witness; see §1.) |
assurance_class |
One of §1 — derived and checked, not declared. |
completeness_scope |
The population over which this is complete, in words a verifier can test (e.g. "all packets on veth0 during run"), or the explicit sentinel none (an Imported sample proves no absence). unknown is refused, never defaulted. |
enforcement_status |
enforced | observed-only | not-applicable. |
policy_digest |
The signed BIM/policy in force, or null + reason. |
artifact_digest |
The workload artifact, or null + reason. |
witness_status |
none | local-pin | external:<witness_id>. |
run_id |
Correlation key across all three engines (ADR-0005). |
sealed |
Chain seq / prev_hash + signature (integrity). |
Derivation of assurance_class (the validator, not the producer, decides):
- attested ⟺ enforcement_status=enforced ∧ a posture.isolation assertion is
present for the run ∧ witness_status=external:*.
- enforced ⟺ enforcement_status=enforced (witness local or none).
- observed ⟺ observation_mode=observed.
- imported ⟺ observation_mode=imported; completeness_scope is forced to
none regardless of what the producer claims.
3. Fail-closed rules¶
- Unknown ⇒ denied. An unparsed IP family, protocol, extension header or field is blocked, and the block is Observed/Enforced evidence — never an unmonitored gap. Coverage gaps are gaps in proof breadth, never in security.
completeness_scopeis mandatory and explicit. No default. A producer that cannot state its scope cannot emit.- Imported never carries absence. Its
completeness_scopeis alwaysnone. - Assurance is checked, not trusted. The verifier recomputes
assurance_classfrom the fields; a mismatch fails verification.
4. The certification → deployment binding¶
The Ghost/twin is worth exactly this and no more.
A Ghost-twin certification is an Enforced/Attested assertion whose subject
is the tuple (artifact_digest, policy_digest, posture_profile, backend).
Production admission MUST refuse to run unless a matching certification exists
covering all of: artifact_digest and policy_digest (BIM) and
posture_profile and (where the guarantee depends on it) backend. Binding
the binary digest alone is insufficient — test under policy A, deploy under
policy B is refused. This tuple binding is carried by in-toto (digest-bound
subjects).
The twin proves the behaviour of the tested binary under the tested policy. It says nothing about a different binary or a different policy — hence the refusal is the mechanism, not a label.
5. Projections (emitters)¶
The canonical core is the invariant. Emitters, in order of maturity to target:
- Native Litatoli bundle — chain + signatures.
- in-toto attestation, predicate
runtime-enforcement/vX— first interop rail; digest-bound subjects carry §4. - EAT (RFC 9711) profile
nazelo-posture/v1— posture as RATS claims, a defined profile, not ad-hoc claims. (RATS model: the value depends on the attester, its key protection and the verifier's policy — stated, not assumed.) Built (2026-08-18):nazelo_trust.eatprojects the statement into an EAT-as-JWT (EdDSA, same key as the chain);eat_nonceis the sealed chain head, so the token points back at the authoritative evidence. Emitted byrun --eat, checked byverify --eat(signature + claims match the statement). This is the clean base a later TRACE profile builds on. - SCITT — behind a Witness interface only (§6). The core never depends on the moving IETF draft; SCITT is an adapter to a real transparency service.
Verifier: standalone, verifies native + in-toto + EAT. A relying party verifies without our runtime. Verifier and public test vectors are published open; commercial value stays in NaZelo, the policies, the integrations and the managed trust service.
6. The witness¶
A witness is a replaceable trust anchor. It vouches, outside the host,
that a run's head existed — and the relying party chooses its anchor. Two
kinds implement the same Witness interface:
FileWitness(self-signed) — a self-hosted Ed25519 key co-signs{log_id, seq, head, observed_at, witness_key_id}. Third-party verifiable, but the key is the producer's own: it bounds when off-host, it does not make the anchor independent.RekorWitness(transparency-log) — an independent log (Rekor protocol; a customer's own PRIVATE/self-hosted instance, a staging, or the public log — only the URL changes) returns a receipt signed by its key, with a Merkle inclusion proof that the entry is really in the tree.verify_transparency_receiptchecks the Signed Entry Timestamp and the RFC 6962 proof against the log's key, not ours — this is what makes "external" mean "not us".ScittWitness(scitt) — a SCITT Transparency Service (draft-ietf-scitt-architecture-22) returns a COSE_Sign1 Receipt with an RFC 9162 inclusion proof (draft-ietf-cose-merkle-tree-proofs-18).verify_scitt_receiptapplies the proof to the leaf → root, then verifies the Receipt's COSE signature against the TS key. The standards-track anchor.TsaWitness(rfc3161-tsa) — an RFC 3161 Time-Stamp Authority returns a signed token vouching that the hash existed at a time it fixes.verify_tsa_receiptreads the digest/signature algorithms from the token and verifies the CMS signature. No inclusion (a TSA is not a log), but an auditor-recognised independent time, composable with a log.HttpLedgerWitness(internal-ledger) — the customer's own append-only registry (an HTTP service, not the localFileWitness). Each entry is hash-chained and signed by the registry's key;verify_ledger_receiptchecks the chain and the signature against that key. For a buyer who trusts only their own infrastructure.
Every network anchor logs only a commitment (sha256(head)); the relying
party supplies the key it trusts, so each customer picks its own registry.
Privacy by construction. Only a commitment — sha256(head) — is logged,
never attestation content. The log, public or not, learns nothing about what ran
or how; a party holding the original recomputes the hash and checks inclusion.
The relying party supplies the log key it trusts, mirroring "each customer picks
its own registry".
Without an external witness, the strongest attainable class is Enforced,
never Attested. The --expected-head pin is a local-pin — not an
inclusion proof.
7. Engine contributions → classes¶
| Engine | Assertions | Class it can reach |
|---|---|---|
| PimaTika | policy.decision (signed BIM, decision + reason) |
input to Enforced |
| NaZelo | egress.blocked, exec.sealed, posture.isolation — what the enforcer saw; posture scoped to the WORKLOAD (setup privileges declared separately, never conflated) |
Observed / Enforced |
| Litatoli | seal + chain (+ witness) | integrity; Attested only with an external witness |
8. Non-goals (honest scope, v0.1)¶
- Does not protect real PLCs. The credible first product is: independent proof that a vendor's software/agent, run in a simulated, governed critical environment, emitted no forbidden protocol operation — bound to deployment by §4. Production runtime enforcement comes after.
- Does not prove workload self-declarations.
workload.outputis at best an Imported record; it is excluded from Enforced/Attested and never treated as a result. - Out of model: root / kernel / hypervisor compromise. The declared perimeter
is stated in every
posture.isolationassertion, so a verifier judges the proof against a named boundary, not a slogan.
9. Internal measurement bench (NOT market validation)¶
Before any roadmap treats "activation" as the constraint, it must be measured. DORAduty is the first dogfooding bench for the evidence/compliance language. It measures: integration friction, artifact readability, independent verifiability, and compliance-scenario relevance. It does not demonstrate market demand — that requires an external relying party.
LottAssist (EuroMillions analysis) is an integration-ease bench only, not a
regulatory proxy: it carries no obligation to prove anything.
Status: v0.1-draft. This contract is frozen before emitters are built; emitters and the verifier implement it, not the reverse.