| Internet-Draft | AAC model_attestation | October 2026 |
| Palanisamy & Mih | Expires 5 April 2027 | [Page] |
This document defines the model_attestation block of the Agent Action
Capsule (AAC) profile — referenced twice by the base profile but never
defined there — and, within it, the compute_attestation container that
already carries runtime extensions in the field: the model-serving
runtime, the agent's own execution environment (architectural pattern,
orchestration framework, sandbox confinement, invoked tool version), and
host hardware, together with model and weights claims. Every claim carries an explicitly declared
source; a verifier grades claims by how they were observed and never
infers a stronger grade than the evidence supports. Hardware or platform
attestation, when present, is cited by content-addressed reference to a
foreign attestation record and verified with that record's own verifier.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 5 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
An agent action recorded in an Agent Action Capsule (AAC) is executed by a
model running within a specific model-serving runtime, itself invoked by
an agent process in a specific execution environment, on host hardware.
Two capsules recording nominally identical actions can differ in what
actually happened depending on model checkpoint, quantization, sandbox
confinement, or the version of a tool package the agent invoked; without a
record of that environment, a forensic reviewer cannot tell a model-drift
event from a compromised tool from an unconfined sandbox. The base profile
[I-D.mih-scitt-agent-action-capsule] records the action, seals it under
canonicalization [RFC8785], and MAY register its Capsule ID as
independently transparent to a SCITT [RFC9943] Transparency Service; the
agent-domain checks defined by the base profile are verified independently
of that registration, by a Class 1 or Class 2 verifier, from the record's
own bytes. Its epoch mechanism records baseline configuration shifts
across actions. Although the base profile references a model_attestation
block, it does not supply a formal definition.¶
Two constraints matter. First, this extension is payload-extension-only:
model_attestation lives in the Capsule JSON like every other payload
member — the base profile's Section "Extensibility" states that all
Capsule extension points are in the Capsule JSON — and it does not touch
the Producer Envelope's protected header, which the base profile's
Section "Producer Envelope wire profile" holds closed to exactly three
entries (Section 3.1). Second, this extension MUST NOT change the base
profile's Class 1 or Class 2 verification model (Sections 6 and 8.2); a
verifier that does not implement it treats the block as informational
(Section 3). This extension also imposes no mandatory transport
dependency; it is silent on how a Capsule is delivered.¶
model_attestation is a bare top-level payload member name, not a
namespaced one. This follows from a fact specific to this field: the base
profile already refers to model_attestation by that exact bare name,
twice, without defining it (in its epoch-boundary Capsule section and in
its Security Considerations), so the name is already reserved by the base
profile itself rather than being minted here. This document supplies the
definition for a name the base profile already uses, rather than
introducing a new namespaced member.¶
This document defines the model_attestation block, generalizes it to
per-action use, and formalizes the model-serving runtime, agent execution
environment, and hardware facts producers observe — all within the
compute_attestation container (Section 4). The block is sealed
directly inside the Capsule payload and participates in derived
identifier generation (capsule_id).¶
The core design principle is honesty of source. A model name reported by the runtime is a claim; a weights digest computed over a loaded file is a stronger claim; a measurement signed by a hardware root of trust is stronger still. They represent distinct facts, and the record states which one it holds. A verifier that cannot resolve a claim to its stated source MUST report it as unresolved, MUST NOT report it as verified, and MUST NOT upgrade an unknown grade to a known one.¶
This block complements rather than replaces the base profile's epoch
machinery: it records per-action claims in force for an action while
remaining scoped to the active epoch and prevailing epoch-boundary
Capsule. model_id is RECOMMENDED, not REQUIRED, in
Section 3.1: the epoch-boundary Capsule already records the
model transition, and an extension MUST NOT out-mandate its base.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Capsule, Producer Envelope, epoch, epoch-boundary Capsule, epoch_id, derived identifier, typed digest reference, and data-admission tiers are used as defined in [I-D.mih-scitt-agent-action-capsule] and [I-D.mih-sokolov-scitt-payload-binding]. Attester, Verifier, and Evidence are used in the sense of [RFC9334] where foreign platform attestation is discussed.¶
A standardized vocabulary declaring how a claim's value was obtained: self_reported (asserted by executing software), provider_reported (returned by a remote model provider or serving API and preserved by the producer without alteration), os_reported (reported by the host operating system), computed (calculated by the producer from bytes it held), or attested (cryptographically bound inside a verifiable foreign attestation record). Additional labels MUST be namespaced.¶
Every source map in this document (at the model_attestation level and
within each compute_attestation sub-object) follows the same default: if
the map is omitted, or a field has no entry in it, a verifier MUST treat
that field's source as self_reported. This rule is stated once here and
applies wherever a source field appears below; it is not restated per
sub-object.¶
A Capsule payload MAY carry a member named model_attestation. The block
participates in the derived identifier like every payload member: it is
canonicalized under JCS [RFC8785] and covered by capsule_id. A verifier
that does not implement this extension MUST ignore it for verification and
MUST NOT fail a Capsule solely because it is present.¶
| Field | Type | Req | Meaning |
|---|---|---|---|
| model_id | string | RECOMMENDED | See Section 3.1. |
| provider | string | OPTIONAL | See Section 3.1. |
| model_revision | string | OPTIONAL | See Section 3.1. |
| weights_digest | object | OPTIONAL | See Section 3.1. |
| quantization | string | OPTIONAL | See Section 3.1. |
| decoding | object | OPTIONAL | See Section 3.1. |
| source | object | OPTIONAL | Field to source label mapping; see above for the omitted-entry default. |
| compute_attestation | object | OPTIONAL | Container for runtime/compute facts (Section 4). |
| epoch_consistency | string | OPTIONAL | consistent, inconsistent, or unknown (Section 6). |
These members define the core model assertions referenced by the base profile's epoch section. They MAY appear in any Capsule and SHOULD appear in every epoch-boundary Capsule.¶
| Field | Type | Req | Permitted Sources | Meaning |
|---|---|---|---|---|
| model_id | string | RECOMMENDED | self_reported, os_reported, attested | Model name as reported by the runtime. |
| provider | string | OPTIONAL | self_reported, attested | Model provider or serving system. |
| model_revision | string | OPTIONAL | self_reported, attested | Provider- or repo-assigned revision. |
| weights_digest | object | OPTIONAL | computed, attested |
{digest_alg, digest, scope} over loaded weights. |
| quantization | string | OPTIONAL | self_reported, computed, attested | Quantization label (e.g., Q4_K_M). |
| decoding | object | OPTIONAL | self_reported | Hyperparameters {temperature, top_p, seed}. |
For weights_digest, scope MUST be either file (digest over serialized
model bytes as loaded from storage) or tensors (digest over in-memory
tensor structures, admissible only under attested). A digest of a
reference string (e.g., a HuggingFace URI) MUST NOT be carried in
weights_digest; such identifiers belong in model_id.¶
A verifier MAY derive grades according to the following matrix, never
exceeding what source and accompanying evidence substantiate:¶
| Record Fact | Verifier May Report |
|---|---|
| model_id only | model: self-reported name |
| weights_digest (scope: file, computed) | model: file-identified (recomputable) |
| weights_digest (attested via Section 4.5) | model: attested at declared scope |
| quantization (self_reported) | quantization: claimed |
A verifier MUST NOT report "model attested" from model_id alone, and MUST NOT report "quantization verified" from any field in this block, as none of
these fields establish which underlying arithmetic was executed. Detection of
substituted models or quantizations is out of scope for this record and
belongs to redundancy or referee mechanisms at the system level.¶
compute_attestation groups environment observations into five
sub-objects: runtime (Section 4.1, the model-serving runtime),
agent_runtime (Section 4.2, the agent's own execution
environment), invocation (Section 4.3, what the model provider or
serving API reported about this call), hardware (Section 4.4), and
attestation_refs (Section 4.5), plus any namespaced member owned by another
specification (for example x-mesh-lifecycle-v1, host_binding).
runtime and agent_runtime are deliberately distinct: runtime
describes the process that served the model's inference (for example, a
local inference server or hosted serving stack); agent_runtime
describes the process that orchestrated the action — the agent loop, its
sandbox, and the tool it invoked — which may be a different process, on
different infrastructure, than the one that served the model. A verifier
MUST ignore members it does not recognize. A member MUST be absent rather
than null when its fact is unavailable.¶
| Field | Type | Req | Meaning |
|---|---|---|---|
| name | string | RECOMMENDED | Serving binary name and version. |
| runtime_digest | string | OPTIONAL | Digest of the serving binary as measured. |
| measurement_class | string | RECOMMENDED* | Class of measurement (*when digest present). |
| platform_integrity | object | OPTIONAL | OS integrity bits (e.g., SIP, Secure Boot). |
| source | object | OPTIONAL | Field to source label mapping; see above for the omitted-entry default. |
Standard measurement_class values include self_measured, os_measured,
tpm_measured, app_attested, mda_measured, and tee_measured. Field
status at the time of writing: self_measured and os_measured are
produced by shipping code; tee_measured has a record shape and verifier
with real Intel TDX vectors; tpm_measured, app_attested, and
mda_measured are named here so that the vocabulary is fixed before their
producers exist. Unknown classes MUST be treated as unrecognized, never
ordered above known classes; the classes are sibling roots of trust and the
ordering above is meaningful only within a single root.¶
Where runtime (Section 4.1) describes the process that served the model,
agent_runtime describes the process that orchestrated the action: the
agent loop or orchestration framework, the environment and confinement it
ran in, and the version of any tool package it invoked to perform this
specific action. This is the environment-blindness gap: two Capsules
recording the same nominal action can behave differently depending on
sandbox confinement or a tool package's version, and without this record a
forensic reviewer cannot distinguish a compromised tool from an unconfined
sandbox from a model-drift event.¶
| Field | Type | Req | Meaning |
|---|---|---|---|
| agent_type | string | OPTIONAL | The agent's architectural pattern (e.g., single_agent, multi_agent_orchestrator, react, plan_execute, supervisor_worker). |
| framework | string | OPTIONAL | Agent orchestration framework or agent-loop implementation, name and version (e.g., langchain 0.3.1, custom-agent-loop 1.4.0). |
| runtime_env | string | OPTIONAL | Execution environment the agent process ran in, name and version (e.g., python:3.11-slim, node:20-alpine). |
| sandbox_type | string | OPTIONAL | Confinement mechanism isolating the agent process (e.g., gvisor, firecracker, wasm, unconfined). |
| tool_version | string | OPTIONAL | Version or content digest of the tool package this action invoked, when the action involved a specific tool. |
| source | object | OPTIONAL | Field to source label mapping; see above for the omitted-entry default. |
agent_type names the architectural pattern the agent process implements
for this action, not the specific framework instance (that is
framework's job) or a claim about correctness. The seeded values above
are illustrative, not exhaustive or registry-governed: single_agent (one
model, one decision loop), multi_agent_orchestrator (a coordinating
process dispatching to one or more sub-agents for this action),
react (interleaved reasoning-and-acting loop), plan_execute (a
separate planning phase precedes execution), and supervisor_worker (a
supervisor process dispatches to worker processes it does not itself
execute as). A value outside this list follows the same namespacing
discipline as constraint id/check_type in the base profile's Section
"Namespacing convention": bare names are reserved for the values seeded
here, and a party introducing a new value MUST namespace it with a URI or
reverse-DNS prefix. A verifier treats an unrecognized agent_type value
as informational, never as a validation failure — this field is
descriptive metadata, not a graded claim, and carries no source-grading
matrix of its own beyond the standard self-reported default.¶
sandbox_type: "unconfined" is itself an informative claim, not an absent
field: a producer that knows its agent process runs unconfined SHOULD say
so rather than omit the field, since the omission and the honest
disclosure of no confinement are otherwise indistinguishable to a
verifier. As with every field in this document, sandbox_type and
framework are self-reported unless graded otherwise by source or
corroborated by an attestation_refs entry (Section 4.5); a verifier
MUST NOT infer actual confinement strength from the label alone;
gvisor and firecracker name mechanisms with different isolation
properties, and this document does not rank them.¶
Commercial and self-hosted model APIs commonly return invocation metadata in addition to the text or tool output. This sub-object preserves such provider or runtime facts without standardizing any provider-specific response object. Every value here is a claim about what the serving side reported for this call; none of it is a measurement of the serving environment, which is what Section 4.1 and Section 4.4 carry.¶
All fields below are OPTIONAL.¶
| Field | Type | Permitted Sources | Meaning |
|---|---|---|---|
| requested_model_id | string | self_reported | Model identifier the caller asked for. |
| resolved_model_id | string | provider_reported, self_reported, attested | Model identifier reported as actually serving the call. |
| service_class | string | provider_reported, self_reported | Provider or runtime processing tier. Values are provider-defined unless registered by another profile. |
| backend_fingerprint | string | provider_reported | Opaque provider-issued deployment or configuration identifier. A change-detection value, not a hardware attestation. |
| reasoning | object | provider_reported, self_reported | Declared reasoning configuration (mode, effort, summary policy). Raw chain-of-thought MUST NOT appear here. |
| usage | object | provider_reported, self_reported | Non-content counters: input, output, cached, and reasoning tokens. |
| finish_status | string | provider_reported, self_reported | Termination status: completed, incomplete, failed, or a provider-namespaced finish reason. |
| response_ref | object | provider_reported | Digest-only or pairwise reference to a provider response identifier, for later correlation. Raw provider request and response identifiers SHOULD NOT be disclosed across parties by default. |
| reasoning_state_ref | object | provider_reported | Typed reference or digest of an opaque provider-issued reasoning-continuity artifact, when one is returned. Treated as opaque; this document neither defines nor requires disclosure of internal reasoning. |
| source | object | — | Field to source label mapping; see Conventions for the omitted-entry default. |
reasoning MAY carry configuration metadata such as mode, effort,
summary, or a provider-namespaced equivalent. It MUST NOT carry hidden
chain-of-thought text, and a verifier MUST treat any text-valued member of
reasoning as a profile violation of the base profile's data-admission
tiers. A provider-issued opaque reasoning or thought signature MAY be
referenced through reasoning_state_ref when the producer needs to bind
the exact state token that was returned.¶
The field names describe semantics, not a vendor API. An adapter MAY
preserve additional provider fields under a provider-controlled namespace,
subject to the base profile's data-admission rules. resolved_model_id
complements, and never replaces, model_id at the model_attestation
level: the former is what the provider said it served on this call, the
latter is the identity the producer records for the epoch.¶
| Field | Type | Req | Meaning |
|---|---|---|---|
| platform | string | OPTIONAL | Platform enum (e.g., intel-tdx, amd-sev-snp, apple-silicon). |
| accelerator | string | OPTIONAL | Accelerator or GPU name as reported. |
| memory_bytes | integer | OPTIONAL | Unified or accelerator memory in bytes. |
| inventory | object | OPTIONAL | Coarse CPU/firmware topology details. |
| source | object | OPTIONAL | Field to source label mapping; see above for the omitted-entry default. Hardware is os_reported at best without a corroborating attestation_refs entry. |
Never-enters. Device serial numbers, platform UUIDs, MAC addresses, and
other stable device identifiers MUST NOT appear in hardware, in clear or
as a digest: they are stable identifiers of small effective entropy and
re-identify a person's machine (base profile, "Data-Admission Tiers"). A
producer that must later show "this was my machine" MAY carry a salted
digest of such an identifier under an explicitly opt-in, namespaced field
whose salt the producer retains; this document does not define that field.¶
This document defines no attestation format. Where hardware or platform
attestation exists, the Capsule cites it by a typed digest reference
[I-D.mih-sokolov-scitt-payload-binding] — {type, purpose, digest_alg,
digest} — where type resolves in the shared Artifact Type Registry to
the foreign record's declared digest context:¶
{
"type": "example.tdx-quote-v1",
"purpose": "hardware",
"digest_alg": "SHA-256",
"digest": "e3b0c442…b7852b855"
}
¶
Verification of a cited attestation record is performed by the verifier that record's issuer publishes, never by a re-implementation in this profile's verifier. The result feeds this block as follows:¶
If the cited record verifies and binds weights_digest, runtime_digest,
or platform measurement values equal to those carried here, the verifier
MAY report those fields at source attested, at the grade the foreign
verifier reports. A foreign verifier's intermediate grades MUST be
carried through, not collapsed to a boolean.¶
If the cited record does not verify, is absent, or binds different values, no field in this block is upgraded, and the verifier SHOULD report the citation as present-but-not-verified with the reason.¶
A cited record MUST be carried byte-identically; it is never re-minted or re-signed by the Capsule producer.¶
The following CDDL [RFC8610] grammar formally specifies the payload schema:¶
model-attestation-block = {
? "model_id" => tstr,
? "provider" => tstr,
? "model_revision" => tstr,
? "weights_digest" => weights-digest-claim,
? "quantization" => tstr,
? "decoding" => decoding-params,
? "source" => source-map,
? "compute_attestation" => compute-attestation-container,
? "epoch_consistency" => "consistent" / "inconsistent"
/ "unknown",
* tstr => any
}
source-label = "self_reported" / "provider_reported" / "os_reported"
/ "computed" / "attested" / tstr
source-map = {
* tstr => source-label
}
weights-digest-claim = {
"digest_alg" => tstr,
"digest" => tstr,
"scope" => "file" / "tensors" / tstr
}
decoding-params = {
? "temperature" => float / int,
? "top_p" => float / int,
? "seed" => int,
* tstr => any
}
compute-attestation-container = {
? "runtime" => runtime-claims,
? "agent_runtime" => agent-runtime-claims,
? "invocation" => invocation-claims,
? "hardware" => hardware-claims,
? "attestation_refs" => [* foreign-attestation-ref],
* tstr => any
}
runtime-claims = {
? "name" => tstr,
? "runtime_digest" => tstr,
? "measurement_class" => measurement-class-label,
? "platform_integrity" => { * tstr => any },
? "source" => source-map
}
agent-runtime-claims = {
? "agent_type" => tstr,
? "framework" => tstr,
? "runtime_env" => tstr,
? "sandbox_type" => tstr,
? "tool_version" => tstr,
? "source" => source-map
}
invocation-claims = {
? "requested_model_id" => tstr,
? "resolved_model_id" => tstr,
? "service_class" => tstr,
? "backend_fingerprint" => tstr,
? "reasoning" => { * tstr => tstr / int / float / bool },
? "usage" => { * tstr => uint },
? "finish_status" => tstr,
? "response_ref" => { * tstr => any },
? "reasoning_state_ref" => { * tstr => any },
? "source" => source-map
}
measurement-class-label = "self_measured" / "os_measured"
/ "tpm_measured" / "app_attested"
/ "mda_measured" / "tee_measured"
/ tstr
hardware-claims = {
? "platform" => tstr,
? "accelerator" => tstr,
? "memory_bytes" => uint,
? "inventory" => { * tstr => any },
? "source" => source-map
}
foreign-attestation-ref = {
"type" => tstr,
"purpose" => tstr,
"digest_alg" => tstr,
"digest" => tstr
}
¶
The base profile's epoch-boundary Capsule records a macroscopic
configuration shift across a registry or agent lifecycle. This block
records the configuration in force for one action. The two MUST NOT
contradict: a Capsule whose model_attestation names a model different
from the one the prevailing epoch-boundary Capsule opened is either a
producer defect or an unrecorded epoch change, and a verifier SHOULD
report epoch_consistency: inconsistent regardless of what the producer
stated. A producer that populates epoch_id SHOULD carry this block in
the epoch-boundary Capsule with source labels, so the transition is
commit-addressed as the base profile intends.¶
This extension adds no additional verification semantics beyond the base profile's Class 1 and Class 2 verifier checks (Sections 6 and 8.2 of [I-D.mih-scitt-agent-action-capsule]) on the sealed AAC record. When this extension is implemented, a verifier MAY apply the checks below.¶
Validate field shapes against Section 5 and the source map; a field
without a source entry is self_reported per Section 3.¶
For each entry in attestation_refs, resolve type per
[I-D.mih-sokolov-scitt-payload-binding]; if resolvable and the record
is available, invoke the issuer's verifier and record its result and
grade.¶
Derive per-field grades per Section 3.1, never exceeding the stated source and the foreign verifier's result.¶
Report epoch_consistency from the ledger context when available.¶
Report unknown measurement_class or source labels as unrecognized,
never as equal to or higher than a known class or label.¶
Treat agent_runtime fields (Section 4.2) as self-reported by
default and never infer confinement strength from sandbox_type's
value; this document ranks no sandbox mechanism against another.¶
Treat invocation fields (Section 4.3) labelled provider_reported
as the provider's claim preserved by the producer: a verifier MUST NOT
report a provider_reported value as computed or attested, and
MUST NOT report resolved_model_id as establishing model identity on
its own.¶
A local evidence store MAY preserve these fields as evidence about the execution environment. The source labels in this document describe how a specific field value was obtained and are intentionally narrower than a general evidence taxonomy. An implementation that maps them onto a wider taxonomy SHOULD do so without silently upgrading them, for example:¶
self_reported: a producer claim;¶
provider_reported: a claim returned by a remote provider or API and
preserved by the producer;¶
os_reported: an observation attributed to an operating-system source;¶
computed: a deterministic derivation over identified bytes; and¶
attested: a claim supported by a separately verified attestation
record.¶
Tool-call content, tool-call result content, prompt and context material, intentionally emitted rationale artifacts, human reports, semantic judgments, outcome adjudications, and regulatory obligation results are outside this block even when they concern the same action. They belong to separate records or extensions and may be linked by typed references.¶
All claims in this block outside of an independently validated
attestation_refs record are assertions made by the Capsule producer. The
function of this profile is not to make those claims true but to make them
specific, signed, and non-repudiable under the AAC verifier acceptance
path. A producer that later serves a different model than it claimed has
signed the discrepancy. Claims about which arithmetic ran (quantization,
precision) cannot be verified from any record the producer alone signs;
systems that need that assurance obtain it by redundancy or hardware
attestation, outside this document. The same honesty-of-source discipline
applies to agent_runtime (Section 4.2): sandbox_type:
"unconfined" is exactly as signed and non-repudiable as any other value,
which is what lets a forensic reviewer later distinguish an unconfined
sandbox that was disclosed from one that was silently omitted.¶
A verifier MUST NOT round up: an unknown measurement_class, an
unresolvable attestation_refs.type, or a source label it does not know
is reported as unrecognized, never treated as the highest grade the
verifier knows. This rule exists because the failure it prevents — a
forged grade string accepted by an old verifier — is otherwise cheap.¶
Every field in this block is subject to the base profile's data-admission tiers (clear-safe, digest-only, never-enters) and its default-deny posture: producers and adapters MUST classify each candidate field before admission, and MUST NOT admit a field merely because this document does not mention it.¶
model_id, provider, and decoding.seed are deployment or run
parameters and clear-safe: they describe the model and its configuration,
not a person. weights_digest and runtime_digest are digests of
software artifacts and carry no end-user privacy exposure on their own; a
producer MUST still ensure the artifact digested does not itself embed
tenant- or user-identifying material — a model fine-tuned on a single
tenant's private corpus is itself a sensitive artifact, and digesting it
does not launder that sensitivity, so model_id and weights_digest for
such a model are tier-appropriate to the tenant's own data, not
automatically clear-safe.¶
agent_runtime.agent_type, .framework, .runtime_env, and
.sandbox_type are ordinarily deployment constants and clear-safe.
agent_runtime.tool_version
is clear-safe only when the tool package identifier or digest does not
itself encode end-user or tenant-identifying information (for example, a
tenant-named internal tool, or a per-tenant container image tag); a
producer whose tool naming does so MUST treat the field as digest-only or
omit it. A producer for whom agent_type, framework, runtime_env, or
sandbox_type varies per end-user request or per tenant (for example,
per-tenant sandbox images keyed to a customer) MUST re-evaluate that
field's tier rather than relying on the clear-safe default stated here,
since a per-tenant value is then itself a tenant-correlation handle.¶
hardware.inventory is intentionally constrained to prevent device
fingerprinting: device serial numbers, MAC addresses, platform UUIDs, and
other persistent hardware identifiers MUST NOT appear in
compute_attestation, in clear or as a digest, per Section 4.4.¶
No field defined in this block is an end-user or session identifier at any tier; none should be added without also updating this section.¶
This section records the status of known implementations of this block at the time of posting, per [RFC7942]. It is to be removed before publication as an RFC.¶
Mesh-LLM capsule plugin (Apache-2.0, Rust and Python): a producer at the
inference boundary of a peer-to-peer model-serving network. It writes
compute_attestation.runtime with a SHA-256 digest of the serving binary
and a measurement_class of os_measured where the host operating system
can report it and self_measured otherwise, and records serving provenance
(serving node, requesting party, token usage, generation parameters) under
a namespaced member of compute_attestation. Quantization and hardware
facts the host does not expose are recorded as absent, never fabricated.
A name hash is recorded under a field name that says it is a name hash,
after an earlier field name that overclaimed a weights binding was renamed.
Its reference library reads model_attestation in its verifier, ledger,
disclosure, and viewer paths.¶
capsule-emit (Apache-2.0, Python): the reference emitter and verifier
treats model_attestation.compute_attestation as the extension container
for runtime and compute facts, and other extensions (for example the
OpenTelemetry correlation block of draft-palanisamy-scitt-aac-otel) are
placed there today.¶
This is a tier-2 (per-profile) extension in the sense of
[I-D.mih-agent-accountability-conformance]: it defines its own
semantics and must-fail cases on top of the tier-1 binding conformance
that [I-D.mih-sokolov-scitt-payload-binding] (CPB) defines for every AAC
payload member. This document is not itself a binding-layer artifact and
does not register a type in the CPB Artifact Type Registry; that
registry governs the type field of a typed digest reference — used here
only by attestation_refs entries (Section 4.5) — a different and
narrower thing than a named payload extension like model_attestation
itself.¶
As of this writing, the registry structure for tier-2 (per-profile) conformance artifacts is explicitly not yet specified — [I-D.mih-agent-accountability-conformance] states plainly that this is "TBD in a future revision." This document therefore cannot cite a settled registration procedure for itself, and does not assert one. What it does provide now, so that registration is a formality once the tier-2 registry exists rather than a rewrite, is the two-sided conformance-vector set that document's discipline (Section 5) requires of any record profile: positive vectors with pinned values, and must-fail vectors that a conformant implementation MUST refuse rather than merely mismatch.¶
Positive vector (MUST be accepted, and graded per Section 3.1
and Section 4.5 without exceeding the stated source):¶
{
"model_attestation": {
"model_id":
"bartowski/Hermes-2-Pro-Mistral-7B-GGUF:Q4_K_M",
"weights_digest": { "digest_alg": "SHA-256",
"digest": "1993f98e…", "scope": "file" },
"source": { "model_id": "self_reported",
"weights_digest": "computed" },
"compute_attestation": {
"runtime": { "name": "mesh-llm-host-runtime 0.76.0",
"measurement_class": "os_measured" },
"agent_runtime": { "agent_type": "react",
"sandbox_type": "gvisor",
"tool_version": "sha256:9b7412f8…" },
"attestation_refs": []
}
}
}
¶
MUST-FAIL vectors (a conformant verifier MUST NOT grade the field above what these rules permit):¶
// (a) weights_digest present with no "source" entry: MUST default
// to self_reported, MUST NOT be treated as "computed" or "attested".
{ "model_attestation": {
"weights_digest": { "digest_alg": "SHA-256",
"digest": "1993f98e…", "scope": "file" } } }
// (b) unrecognized measurement_class: MUST be reported as
// unrecognized, MUST NOT be treated as equal to or higher than any
// known class.
{ "model_attestation": { "compute_attestation": { "runtime": {
"name": "custom-runtime 1.0",
"measurement_class": "quantum_measured" } } } }
// (c) attestation_refs entry whose cited record does not verify: no
// field in the block may be upgraded to "attested" on account of the
// citation.
{ "model_attestation": {
"weights_digest": { "digest_alg": "SHA-256",
"digest": "1993f98e…", "scope": "file" },
"source": { "weights_digest": "attested" },
"compute_attestation": { "attestation_refs": [
{ "type": "example.invalid-attestation-v1",
"purpose": "hardware",
"digest_alg": "SHA-256", "digest": "0000…" } ] } } }
// (d) agent_runtime.tool_version present with no "source" entry:
// MUST default to self_reported, MUST NOT be treated as "computed".
{ "model_attestation": { "compute_attestation": { "agent_runtime": {
"tool_version": "sha256:9b7412f8…" } } } }
¶
This document has no IANA actions. model_attestation is a bare payload
member name seeded by the base profile itself (Section 3), not a
namespaced extension, so the base profile's namespacing convention does
not apply to the member name. Source labels and measurement classes are
closed vocabularies of this document (Conventions and Section 4.1); a
future revision may request IANA registries for either if independent
extensions appear. Registration of this document as a conforming tier-2
profile awaits the registry work noted in Section 12.¶
Revisions -04 and -05 of draft-mih-scitt-agent-action-capsule reference
model_attestation in their epoch-boundary section and their security
considerations without defining it, while producers and a registry entry
already use the block. This document supplies the definition (Section 3,
Section 3.1). The authors recommend that -06 of the base profile
(a) cite this document for the definition or fold Section 3 in, and (b)
name the two extension containers explicitly: namespaced top-level members
for correlation/provenance extensions, and
model_attestation.compute_attestation for runtime and compute
extensions. Until (b) lands, implementations place namespaced extensions
under model_attestation.compute_attestation as well (see Section 11).¶
The following is an example of a complete model_attestation object:¶
{
"model_attestation": {
"model_id":
"bartowski/Hermes-2-Pro-Mistral-7B-GGUF:Q4_K_M",
"provider": "mesh-llm",
"weights_digest": {
"digest_alg": "SHA-256",
"digest": "1993f98e…04724b12",
"scope": "file"
},
"quantization": "Q4_K_M",
"decoding": {
"temperature": 0.0,
"seed": 42
},
"source": {
"model_id": "self_reported",
"weights_digest": "computed",
"quantization": "self_reported"
},
"compute_attestation": {
"runtime": {
"name": "mesh-llm-host-runtime 0.76.0",
"runtime_digest": "c204ac76…4f23b723",
"measurement_class": "os_measured",
"platform_integrity": {
"sip_enabled": true
},
"source": {
"sip_enabled": "os_reported"
}
},
"agent_runtime": {
"agent_type": "react",
"framework": "custom-agent-loop 1.4.0",
"runtime_env": "python:3.11-slim",
"sandbox_type": "gvisor",
"tool_version": "sha256:9b7412f8…12345678",
"source": {
"agent_type": "self_reported",
"framework": "self_reported",
"runtime_env": "self_reported",
"sandbox_type": "os_reported",
"tool_version": "computed"
}
},
"invocation": {
"requested_model_id": "hermes-2-pro-7b",
"resolved_model_id":
"bartowski/Hermes-2-Pro-Mistral-7B-GGUF:Q4_K_M",
"usage": { "input_tokens": 412, "output_tokens": 88 },
"finish_status": "completed",
"source": {
"requested_model_id": "self_reported",
"resolved_model_id": "provider_reported",
"usage": "provider_reported",
"finish_status": "provider_reported"
}
},
"hardware": {
"platform": "apple-silicon",
"accelerator": "Apple M4 Max",
"memory_bytes": 28991029248,
"source": {
"platform": "os_reported",
"accelerator": "os_reported",
"memory_bytes": "os_reported"
}
},
"attestation_refs": []
},
"epoch_consistency": "consistent"
}
}
¶
The authors thank the maintainers of the Mesh-LLM capsule plugin, whose
shipping runtime measurements fixed the first two measurement classes,
and the reviewers of the RATS architecture whose grading discipline
Section 4.5 follows.¶