<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="std"
     docName="draft-ruvalcaba-nhe-audit-00"
     ipr="trust200902"
     submissionType="IETF"
     consensus="true"
     xml:lang="en"
     tocInclude="true" tocDepth="3" symRefs="true" sortRefs="true" version="3">

  <front>
    <title abbrev="NHE Audit">NHE Reasoning-Audit Log: A Tamper-Evident, Content-Optional Audit Chain for Autonomous Agents</title>
    <seriesInfo name="Internet-Draft" value="draft-ruvalcaba-nhe-audit-00"/>
    <author fullname="Cristian Xavier Ruvalcaba" initials="C.X." surname="Ruvalcaba">
      <organization>Saluca LLC</organization>
      <address><email>cristian@saluca.com</email></address>
    </author>
    <date year="2026" month="August" day="11"/>
    <area>Security</area>
    <workgroup>Individual Submission</workgroup>
    <keyword>audit</keyword>
    <keyword>tamper-evident log</keyword>
    <keyword>hash chain</keyword>
    <keyword>autonomous agent</keyword>
    <keyword>transparency</keyword>

    <abstract>
      <t>This document specifies a tamper-evident audit chain for the reasoning
      and actions of a Non-Human Entity (NHE). Each audited event --- a reasoning
      step obtained at the boundary to a model provider, or a tool invocation
      obtained at the execution boundary --- is recorded as an entry whose bound
      fields are hash-linked to its predecessor, so that any alteration, omission,
      or reordering is detectable by an independent verifier. The chain binds
      metadata (model, provider, subject identity, and reasoning scale) into the
      entry hash, and supports a prove-without-exposing mode in which a verifier
      confirms that an event occurred, with the attested metadata, without the
      event's content being disclosed. Content storage is optional and its
      retention is configurable independently of the chain, so content may be
      redacted without destroying the chain's integrity. The entry data model and
      canonical serialization are specified here; the wire and proof-export
      encodings are deferred to the next revision.</t>
    </abstract>
  </front>

  <middle>

    <section numbered="true"><name>Introduction</name>
      <t>A persistent autonomous agent takes consequential actions and reasons its
      way to them. After the fact, an authorized party needs a record of what the
      agent reasoned and did, whose integrity does not depend on trusting the agent
      that produced it. A plain log does not provide that: the producer can rewrite
      it. This document specifies a tamper-evident audit chain that does, and that
      does so without forcing disclosure of the reasoning content itself.</t>
      <t>Two properties distinguish this from a generic hash-chained log
      (structurally, the audit chain is a close relative of transparency logs such
      as Certificate Transparency <xref target="RFC9162"/>). First, it is
      <strong>cross-layer</strong>: it captures reasoning at the boundary to a
      model provider and tool invocations at the execution boundary, normalized
      into one continuity-preserving chain. Second, it is
      <strong>content-optional with proof-without-exposing</strong>: the entry
      binds the reasoning's identity, provenance, and scale so a verifier can
      confirm "this subject produced reasoning of this provenance and magnitude,
      leading to this action" without the reasoning text ever crossing to the
      verifier.</t>
    </section>

    <section numbered="true"><name>Relationship to the NHE Architecture</name>
      <t>This document specifies the Reasoning-and-Audit interface of
      <xref target="I-D.ruvalcaba-nhe-arch"/> and is the concrete realization of
      that model's <strong>inspectability</strong> invariant: an authorized party
      can obtain a verifiable record whose integrity is independent of the NHE. The
      content-optional design is deliberate --- inspectability must not require
      surrendering the confidentiality of an agent's reasoning, or it will not be
      deployed. The audit chain's genesis is anchored to the subject's identity
      (<xref target="genesis"/>) as defined by the NHE identity interface
      <xref target="I-D.ruvalcaba-nhe-identity"/>, tying every record to a verified
      entity.</t>
    </section>

    <section numbered="true"><name>Terminology</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "MAY", and
      "OPTIONAL" are to be interpreted as described in BCP 14
      <xref target="RFC2119"/> <xref target="RFC8174"/>.</t>
      <dl>
        <dt>Audit chain:</dt><dd>The append-only, hash-linked sequence of audit
        entries for one subject.</dd>
        <dt>Subject:</dt><dd>The NHE whose reasoning and actions are audited,
        identified per <xref target="I-D.ruvalcaba-nhe-identity"/>.</dd>
        <dt>Reasoning entry:</dt><dd>An audit entry recording a reasoning step
        obtained at the boundary to a model provider.</dd>
        <dt>Action entry:</dt><dd>An audit entry recording a tool or command
        invocation obtained at the execution boundary.</dd>
        <dt>Proof-access scope:</dt><dd>Authorization to obtain proofs and metadata
        about entries, distinct from and weaker than the content-access scope.</dd>
        <dt>Content-access scope:</dt><dd>Authorization to obtain the stored
        content of an entry, where content is retained.</dd>
      </dl>
    </section>

    <section anchor="model" numbered="true"><name>Audit Chain Model</name>
      <section numbered="true"><name>Entry Structure</name>
        <t>Each entry binds, at minimum, the following fields into its entry hash.
        A verifier recomputes the entry hash over the identical field set, so any
        single-field alteration breaks the chain:</t>
        <artwork type="ascii-art"><![CDATA[
  entry = {
    entry_index      : monotonic position in the chain (integer)
    request_id       : correlator for the audited transaction
    timestamp        : RFC 3339 UTC, nanosecond precision
    subject_id       : identity of the audited NHE
    provider         : model/tool provider identifier (nullable)
    model            : model identifier (nullable)
    content_hash     : digest of the reasoning/action content
    token_count      : reasoning size in tokens (nullable)
    byte_count       : reasoning size in bytes (always present)
    tokenizer_id     : named, versioned tokenizer (nullable)
    capture_mode     : reasoning | action
    content_mode     : full | hash-only | none
    prev_hash        : link to the immediate predecessor
  }
  entry_hash = HASH( CANON(entry) )
]]></artwork>
        <t>Binding the provenance and scale fields (provider, model, token_count,
        byte_count) into the hash is essential: an audit that hashed only an
        opaque content digest would let an adversary alter "which model reasoned"
        or "how much reasoning occurred" without breaking the chain. byte_count is
        the always-present, deterministic scale attestation; token_count is
        present only when a provider-reported count or a named tokenizer makes it
        reproducible.</t>
      </section>

      <section numbered="true"><name>Canonical Serialization (CANON)</name>
        <t>CANON produces a deterministic preimage so that any verifier recomputes
        byte-identical input. Each field is encoded as an 8-octet big-endian length
        prefix followed by its octet payload; integers are encoded as fixed 8-octet
        big-endian values; timestamps are RFC 3339 UTC nanosecond strings. An
        absent optional field is encoded with a distinguished length sentinel of
        0xFFFFFFFFFFFFFFFF, which is distinct from a present empty value (length 0),
        so that a null and an empty string can never collide. Length-prefixing
        removes the concatenation ambiguity by which ("ab","c") and ("a","bc") would
        otherwise share a preimage.</t>
      </section>

      <section anchor="genesis" numbered="true"><name>Genesis, Linkage, and Verification</name>
        <t>The prev_hash of the genesis entry is defined as HASH(CANON(subject_id))
        --- the chain is anchored to the subject's identity, so an audit chain
        cannot be transplanted between subjects. For every non-genesis entry, the
        prev_hash MUST equal the entry hash of its immediate predecessor. Appends
        for a single subject MUST be serialized by a single writer (a queue or a
        compare-and-set on the chain head) so that linkage is well defined under
        concurrent events.</t>
        <artwork type="ascii-art"><![CDATA[
  [ genesis ]           [ entry 1 ]         [ entry 2 ]
  prev = H(subject) <-  prev = eh(0)  <-    prev = eh(1)
  eh(0)                 eh(1)               eh(2)
]]></artwork>
        <t>To verify a range, a verifier recomputes each entry hash from CANON over
        the entry's fields, confirms each non-genesis prev_hash equals the
        predecessor's recomputed entry hash, and special-cases the genesis
        (comparing prev_hash against HASH(CANON(subject_id)) when the range starts
        at index 0, or trusting a caller-provided anchor link otherwise). Each
        recomputation is O(1); range verification is O(n).</t>
      </section>
    </section>

    <section anchor="content" numbered="true"><name>Content Handling and Retention</name>
      <t>The content_mode field records, per entry, whether the reasoning or action
      content is stored in full, represented only by its content_hash, or not
      captured at all. Content retention is configurable independently of chain
      retention. Because the chain binds only the content_hash and the metadata,
      <strong>content may be deleted or redacted without breaking the chain</strong>:
      the entry continues to prove that an event with the attested provenance,
      scale, and identity occurred at its position, even after its content is gone.
      This separation is what lets an operator satisfy data-minimization or erasure
      obligations while preserving a verifiable audit.</t>
      <t>Where content is stored, it SHOULD be protected with an authenticated
      encryption scheme (for example AES-256-GCM) that binds the entry hash as
      additional authenticated data, so that ciphertext cannot be transplanted
      between entries. Implementations MUST preserve nonce uniqueness: under a
      long-lived per-subject key with random 96-bit nonces, the key MUST be rotated
      before the per-key record count approaches the birthday bound
      (<xref target="RFC5116"/> and NIST SP 800-38D), or a deterministic per-record
      nonce MUST be used.</t>
    </section>

    <section anchor="proof" numbered="true"><name>Prove-Without-Exposing</name>
      <t>A holder of the proof-access scope, without the content-access scope, can
      obtain a proof that a given entry exists in the chain at a given index with
      the attested metadata (subject, provider, model, scale, capture and content
      modes) and is correctly linked to its neighbors --- without receiving the
      entry's content. This is the property that makes inspectability deployable:
      an auditor confirms "the correct model was used, reasoning of the expected
      magnitude occurred, and it led to this action" while the reasoning text
      itself remains confidential. The proof-access scope and the content-access
      scope MUST be separately enforceable; granting proof access MUST NOT imply
      content access.</t>
    </section>

    <section anchor="crosslayer" numbered="true"><name>Cross-Layer Capture</name>
      <t>Reasoning entries are produced at the boundary between the subject and a
      model provider, extracting the reasoning trace from the provider's response
      according to a provider-specific procedure and normalizing heterogeneous
      provider formats into one chain. Action entries are produced at the execution
      boundary, capturing a tool or command invocation and its outcome. Both kinds
      share the entry structure and the single chain, so a verifier sees one
      continuity-preserving record that correlates reasoning with the actions it
      led to. An implementation MAY additionally maintain a local, identity-anchored
      copy of the chain so that a failure to append remotely is itself detectable
      on later reconciliation rather than silently lost.</t>
    </section>

    <section anchor="anomaly" numbered="true"><name>Complexity-Divergence Signal (Optional)</name>
      <t>An implementation MAY compute, over a trailing window of a subject's
      entries, a reasoning-complexity measure (token_count, or byte_count when
      tokens are absent) and an action-complexity measure (a defined function of an
      action's argument count, size, and sensitivity), and flag an entry whose
      standardized residual between the two exceeds a configurable multiple of the
      windowed standard deviation. A large divergence --- a consequential action
      preceded by little reasoning, or vice versa --- is a signal worth surfacing.
      This is an analysis over the chain, not a property of it, and is out of scope
      for interoperation beyond the fields the chain already binds.</t>
    </section>

    <section anchor="wire" numbered="true"><name>Wire and Proof Encoding (to be specified in -01)</name>
      <t>The entry data model, CANON, the identity-anchored genesis, and the
      verification procedure are fixed by this revision. The concrete encodings ---
      of entries on the wire, of the prove-without-exposing proof object, and of
      the encrypted-content envelope --- are deferred to the next revision,
      following the compact-binary approach of HCTP
      <xref target="I-D.ruvalcaba-hctp"/>.</t>
    </section>

    <section anchor="security" numbered="true"><name>Security Considerations</name>
      <t>The chain provides tamper-evidence, not authorship: an unkeyed hash chain
      proves internal linkage and that no entry was altered after the fact relative
      to its neighbors, but a party able to rebuild the whole chain can produce a
      consistent alternative. Authorship and non-repudiation require signing the
      chain head (or entries) under the subject's identity key
      <xref target="I-D.ruvalcaba-nhe-identity"/> and/or periodic external anchoring
      (for example publishing chain heads to a transparency log
      <xref target="RFC9162"/>); deployments needing to prove the log was not
      wholesale rewritten MUST do one of these. The genesis anchor to subject
      identity prevents cross-subject transplant and MUST be verified.</t>
      <t>Content, where stored, is the sensitive part; its confidentiality rests on
      the AEAD layer and on strict separation of the content-access and proof-access
      scopes (<xref target="proof"/>). A verifier MUST NOT be able to escalate from
      proof access to content access. Redaction of content MUST leave the bound
      content_hash and metadata intact so that verification still succeeds over the
      remaining entries; an implementation that deletes bound fields rather than
      only unbound content breaks verifiability and is non-conformant. Single-writer
      serialization (<xref target="genesis"/>) is security-relevant: concurrent
      appends without it can fork the chain. Finally, a failure to record MUST be
      treated as a security event, not an operational nuisance --- the local
      identity-anchored chain exists so that gaps are detectable rather than
      deniable.</t>
    </section>

    <section anchor="iana" numbered="true"><name>IANA Considerations</name>
      <t>A future revision will request registries for "NHE Audit Capture Modes"
      (reasoning, action), "NHE Audit Content Modes" (full, hash-only, none), and
      the hash and AEAD suites used by the chain, each under a Specification
      Required policy <xref target="RFC8126"/>. No IANA action is requested by this
      skeleton revision.</t>
    </section>
  </middle>

  <back>
    <references><name>Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front><title>Key words for use in RFCs to Indicate Requirement Levels</title>
        <author initials="S." surname="Bradner"/><date year="1997" month="March"/></front>
        <seriesInfo name="BCP" value="14"/><seriesInfo name="RFC" value="2119"/></reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front><title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
        <author initials="B." surname="Leiba"/><date year="2017" month="May"/></front>
        <seriesInfo name="BCP" value="14"/><seriesInfo name="RFC" value="8174"/></reference>
    </references>
    <references><name>Informative References</name>
      <reference anchor="I-D.ruvalcaba-nhe-arch">
        <front><title>An Architecture for Non-Human Entities (NHE)</title>
        <author initials="C.X." surname="Ruvalcaba"/><date year="2026" month="August"/></front>
        <seriesInfo name="Internet-Draft" value="draft-ruvalcaba-nhe-arch-00"/></reference>
      <reference anchor="I-D.ruvalcaba-nhe-identity">
        <front><title>NHE Identity</title>
        <author initials="C.X." surname="Ruvalcaba"/><date year="2026" month="August"/></front>
        <seriesInfo name="Internet-Draft" value="draft-ruvalcaba-nhe-identity-00"/></reference>
      <reference anchor="I-D.ruvalcaba-hctp">
        <front><title>The Hash-Chain Context Transfer Protocol (HCTP)</title>
        <author initials="C.X." surname="Ruvalcaba"/><date year="2026" month="August"/></front>
        <seriesInfo name="Internet-Draft" value="draft-ruvalcaba-hctp-00"/></reference>
      <reference anchor="RFC9162" target="https://www.rfc-editor.org/info/rfc9162">
        <front><title>Certificate Transparency Version 2.0</title>
        <author initials="B." surname="Laurie"/><author initials="E." surname="Messeri"/>
        <author initials="R." surname="Stradling"/><date year="2021" month="December"/></front>
        <seriesInfo name="RFC" value="9162"/></reference>
      <reference anchor="RFC5116" target="https://www.rfc-editor.org/info/rfc5116">
        <front><title>An Interface and Algorithms for Authenticated Encryption</title>
        <author initials="D." surname="McGrew"/><date year="2008" month="January"/></front>
        <seriesInfo name="RFC" value="5116"/></reference>
      <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/rfc8126">
        <front><title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
        <author initials="M." surname="Cotton"/><author initials="B." surname="Leiba"/>
        <author initials="T." surname="Narten"/><date year="2017" month="June"/></front>
        <seriesInfo name="BCP" value="26"/><seriesInfo name="RFC" value="8126"/></reference>
    </references>
  </back>
</rfc>
