Internet-Draft AAC OTel Extension October 2026
Palanisamy & Mih Expires 5 April 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-palanisamy-scitt-aac-otel-00
Published:
Intended Status:
Informational
Expires:
Authors:
G. Palanisamy
Independent
S. Mih
Action State Group, Inc.

OpenTelemetry Correlation Extension for Agent Action Capsules

Abstract

This document defines org.agentactioncapsule.otel, a namespaced payload extension for the Agent Action Capsule profile. The extension carries OpenTelemetry trace and span context alongside a sealed agent-action record so that the Capsule and the observability spans describing the same action can be joined after the fact. It maps the OpenTelemetry Generative AI semantic conventions onto Capsule fields where a mapping is well defined and states which OpenTelemetry values MUST NOT enter a Capsule at all. The extension does not alter Capsule verification: a verifier that does not implement it treats the block as informational.

Status of This Memo

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.

▲

Table of Contents

1. Introduction

Agent runtimes emit OpenTelemetry spans for tool calls, model invocations, and handoffs. The Agent Action Capsule profile [I-D.mih-scitt-agent-action-capsule] seals the corresponding record at the effect boundary, and a Class 1 verifier validates it before it is accepted as evidence. This extension makes the join explicit: the Capsule carries the trace and span identifiers associated with the action, and the span can carry the Capsule's derived identifier as an attribute. This extension MUST NOT change the base Class 1 or Class 2 verification model. A verifier that does not implement the extension MUST treat the block as informational and MUST ignore it for verification purposes.

Two constraints matter. First, this extension MUST NOT alter the Producer Envelope or the base profile's verification semantics. The protected header of a Capsule remains closed by the base profile ([I-D.mih-scitt-agent-action-capsule], Section "Extensibility"), and all fields defined here live in the Capsule payload under a namespaced key. Second, this extension MUST treat OpenTelemetry identifiers as correlation handles into systems that may hold end-user data. The base profile's admission tiers apply to each field. In particular, trace_id and span_id are clear-safe only when they are non-identifying within the producer's scope. A trace ID is a lookup key into logs, APM backends, and gateway records that may hold user data. This profile therefore defines a strict allow-list and an explicit digest-only alternative rather than treating an opaque identifier as harmless by default.

2. Conventions and Definitions

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, derived identifier, capsule_id, and the data-admission tiers (clear-safe, digest-only, never-enters) are used as defined in [I-D.mih-scitt-agent-action-capsule]. Trace ID, span ID, trace flags, and tracestate are used as defined in [W3C.TraceContext].

This document is written against revision -05 of the base profile. It addresses the observability gap between a sealed Capsule and the active OpenTelemetry trace and span without changing the Class 1 or Class 2 verification model of [I-D.mih-scitt-agent-action-capsule]. In particular, trace and span identifiers are correlation handles, not harmless opaque values; they therefore require explicit allow-listing and digest-only handling when they may reveal or index user-bearing data. This extension MUST NOT introduce a new mandatory identity claim: identity is represented in the base model as operator/developer context rather than an agent_id field. The extension remains payload-only and MUST NOT impose a mandatory transport or OAuth dependency. Any transaction-token guidance is informative and SHOULD-oriented so that the base profile remains transport- neutral.

3. The org.agentactioncapsule.otel Block

A Capsule MAY carry a top-level payload member named org.agentactioncapsule.otel. The member name is reverse-DNS namespaced. [I-D.mih-scitt-agent-action-capsule]'s Section "Namespacing convention" currently states this rule only for three producer-local vocabularies (constraint id/check_type, compliance.framework_tags, and assurance.sources[].kind); it does not yet generalize the bare-name/ namespaced-name split to top-level payload members; revision -05 left that section unchanged. This document adopts the same convention for its own member — bare names reserved for values the base profile seeds, new members namespaced — and the authors request that -06 generalize the rule explicitly.

Where the block lives. Until the base profile admits namespaced top-level members explicitly, the one payload container the base profile already treats as extensible is model_attestation.compute_attestation (see draft-palanisamy-scitt-aac-runtime). The reference emitter therefore places this block at model_attestation.compute_attestation["org.agentactioncapsule.otel"] today (see Section 8), with field names, tiers, and shape exactly as defined here. A producer MAY place the block at either path. A verifier that implements this extension MUST recognize the block at either path and MUST treat the two placements identically; only the JSON path differs.

The block participates in the derived identifier like every other payload member: it is canonicalized under JCS [RFC8785] and covered by capsule_id. A verifier that does not implement this extension MUST ignore the block for verification purposes and MUST NOT fail a Capsule because it is present.

Table 1
Field Type Req Tier Meaning
trace_id string (32 lowercase hex) REQUIRED clear-safe, conditional (see Section 6) The W3C trace ID of the span that observed the action.
span_id string (16 lowercase hex) REQUIRED clear-safe, conditional The W3C span ID of that span.
parent_span_id string (16 lowercase hex) OPTIONAL clear-safe, conditional Parent of span_id, when known to the producer.
trace_flags string (2 lowercase hex) OPTIONAL clear-safe W3C trace flags as sampled by the producer.
tracestate_digest string (64 lowercase hex) OPTIONAL digest-only SHA-256 over the tracestate header value as received. tracestate MUST NOT be carried in clear (vendor entries may carry identifiers).
span_name string OPTIONAL clear-safe, conditional The span's name, only when it is a fixed operation name and never user-derived.
resource object OPTIONAL see Section 3.1 A closed subset of OpenTelemetry resource attributes.
semconv object OPTIONAL see Section 3.2 GenAI semantic-convention attributes admitted by this document, plus semconv.source = the conventions repository and commit or release the names are drawn from.

Additional members under org.agentactioncapsule.otel MUST be namespaced (URI or reverse-DNS prefix). A verifier MUST ignore members it does not recognize.

3.1. Resource attributes

Only the following resource attributes MAY appear under resource, and only when their values are deployment constants rather than per-user or per-session values:

Table 2
Attribute Tier Note
service.name clear-safe Deployment-assigned.
service.version clear-safe  
service.namespace clear-safe  
deployment.environment.name clear-safe  
telemetry.sdk.name / telemetry.sdk.version clear-safe  

service.instance.id, host.name, host.id, container.id, and any attribute that identifies a machine or process instance are digest-only at most and SHOULD be omitted: they are stable identifiers with small effective entropy in most fleets, and the base profile's warning that hashing is not anonymization applies.

3.2. GenAI semantic conventions

The OpenTelemetry GenAI conventions [OTEL-GENAI] now live in their own repository (open-telemetry/semantic-conventions-genai; the pages in the main semantic-conventions repository redirect there as of v1.44.0). They are not yet stable, so semconv.source MUST name the repository and the commit or release the attribute names were taken from; this revision was written against commit 8c1b98a.

Where a Capsule already carries the same fact, this extension does not duplicate it; where the convention carries a fact the Capsule lacks, the attribute MAY be admitted under semconv at the tier shown. Attributes not listed are not admitted until a revision classifies them (allow-list stance).

Table 3
GenAI attribute Disposition; note / Capsule counterpart
gen_ai.provider.name clear-safe; (replaces the retired gen_ai.system) model_attestation.provider when present; do not carry in both
gen_ai.request.model / gen_ai.response.model clear-safe; model_attestation.model_id (RECOMMENDED there); do not carry in both
gen_ai.operation.name clear-safe; chat, execute_tool, invoke_agent, invoke_workflow, … — informs action_type mapping only
gen_ai.agent.id / gen_ai.agent.name / gen_ai.agent.version clear-safe; corresponds to the Capsule's developer; carry only if it adds a version the Capsule lacks
gen_ai.workflow.name clear-safe, conditional; fixed workflow names only; never user-derived
gen_ai.tool.name / gen_ai.tool.type clear-safe; tool identity, not arguments
gen_ai.tool.call.id clear-safe, conditional; joinable by the producer to the effect record; carry only if non-identifying
gen_ai.usage.input_tokens / output_tokens / reasoning.output_tokens / cache_*.input_tokens clear-safe; counts are not content
gen_ai.request.temperature, top_p, top_k, max_tokens, seed, stop_sequences, reasoning.level, choice.count clear-safe; decoding parameters; model_attestation.decoding when present
gen_ai.response.finish_reasons / gen_ai.response.status / gen_ai.output.type clear-safe
gen_ai.response.id / gen_ai.request.previous_response.id digest-only; provider-assigned ids are correlation handles into provider logs
gen_ai.data_source.id / gen_ai.memory.store.id clear-safe, conditional; only when a deployment constant naming a store, never a per-user store
gen_ai.prompt.name / gen_ai.prompt.version clear-safe, conditional; small value spaces; if a deployment treats prompt identity as sensitive, digest with a tenant-private salt — an unsalted digest of a small vocabulary is dictionary-recoverable
gen_ai.input.messages / gen_ai.output.messages / gen_ai.system_instructions never-enters; content; the Capsule commits content by digest through its effect record only
gen_ai.tool.call.arguments / gen_ai.tool.call.result / gen_ai.tool.definitions never-enters; content
gen_ai.memory.records / gen_ai.memory.query.text / gen_ai.retrieval.query.text / gen_ai.retrieval.documents never-enters; content
gen_ai.prompt.variable.* (incl. gen_ai.prompt.variable.user_name) never-enters; template variables carry user data by construction
gen_ai.conversation.id, mcp.session.id, session_id, enduser., user. never-enters; end-user or session identity; excluded, not digested
gen_ai.evaluation.* (name, result, score.*, explanation) out of scope; judgments about a run belong to the reasoning/judging extension, not to a correlation block; a Capsule's own verdict is in the base profile's disposition
gen_ai.client.* / gen_ai.server.* metrics, mcp.*.session.duration out of scope; metrics are not per-action facts

3.3. Relationship to evidence stores and evidence exchange

This extension is a correlation profile for a Capsule, not a general observability ingestion format and not an evidence-exchange protocol. A local evidence store MAY index the relationship between a Capsule and OpenTelemetry records without placing all OpenTelemetry metadata in the Capsule. Likewise, an evidence bundle MAY carry or selectively disclose the correlated OpenTelemetry record under its own authorization and disclosure rules.

The presence of this block therefore says only that the Capsule producer bound a correlation handle to the Capsule. It does not establish that every relevant span was captured, that the span is independent of the Capsule producer, or that the span's semantic interpretation is correct.

3.4. Capsules produced from exported telemetry

A Capsule MAY be produced after the fact from spans already exported to an observability backend, for example when an operator onboards an existing deployment by replaying its telemetry. Such a Capsule MUST carry the base profile's provenance_mode block with mode: "backfilled" ([I-D.mih-scitt-agent-action-capsule], Section "Provenance mode and backfilled records"), and the source_ref of that block SHOULD identify the exported span record the Capsule was derived from. The fields of org.agentactioncapsule.otel are then taken from the exported span rather than from a live context, and the same tiers and allow-list apply.

The base profile caps the time rung of a backfilled Capsule at what its provenance_mode supports. A backfilled Capsule that cites a span therefore records that the span existed when the replay ran; it does not record that the Capsule was sealed when the span was emitted. Verifiers and coverage reports MUST present replayed and contemporaneous Capsules separately.

4. The reverse join: Capsule identifier on the span

A producer that emits both a span and a Capsule for one action SHOULD set the span attribute aac.capsule_id to the Capsule's derived identifier once sealed, so that observability tooling can locate the sealed record from the trace. The attribute name is proposed for registration in the OpenTelemetry semantic-conventions registry.

The span attribute is advisory. A verifier MUST recompute capsule_id from the Capsule; a span attribute that disagrees with the recomputed value is a defect in the span, not in the Capsule.

5. Verification

This extension defines no verification behavior 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]). Specifically:

6. Privacy Considerations

The base profile's data-admission tiers govern every field in this block. This section states what the tiers mean for OpenTelemetry values because the intuition that an opaque identifier is harmless does not hold here.

Trace and span identifiers are correlation handles. A trace ID is clear-safe only when it is non-identifying on its own: it names an execution, not a person. But a trace ID is also a lookup key into every system that indexed the same trace — request logs, APM backends, gateway access logs — and some of those systems hold end-user data. Committing a trace ID in clear into a record that may later be disclosed to a third party therefore gives that party a key into systems the disclosure never covered. Producers MUST classify trace and span IDs as clear-safe only when the observability systems they index do not themselves hold end-user identity, or when disclosure of the Capsule is confined to parties that already hold access to those systems. Otherwise the IDs MUST be carried as digests, or a pairwise correlation identifier MUST be used instead.

What the block's fields must never be. Regardless of tier, no field of org.agentactioncapsule.otel MAY carry: prompt or completion content; message bodies; tool arguments or results; end-user identifiers or session identifiers, in clear or as a digest; OpenTelemetry baggage entries [OTEL-BAGGAGE]; tracestate in clear; or resource attributes that identify a natural person or a single device. Hashing is not anonymization for low-entropy values (base profile, "Data-Admission Tiers"); the digest-only tier is for content that must be provable later, not for identifiers that must be hidden.

Allow-list stance. Adapters implementing this extension SHOULD admit only the attributes enumerated in this document and default-deny all others, per the base profile's adapter allow-list pattern. New GenAI attributes added by later convention versions are not admitted until a revision of this document classifies them.

7. Security Considerations

The block is covered by the Capsule signature, the derived identifier, and the verifier acceptance path used to seal and accept the Capsule. It MUST NOT be altered without detection. It adds no authority: a span is the producer's own telemetry, and the join it enables is between two records from one party. Corroboration from a second party is provided by the base profile's assurance.cross_party_rung mechanism (Section 5.4.1 of [I-D.mih-scitt-agent-action-capsule]), not by this extension.

8. Implementation Status

This section records the status of known implementations of this extension at the time of posting, per [RFC7942]. It is to be removed before publication as an RFC.

capsule-emit (Apache-2.0, Python): ships an OpenTelemetry SDK SpanExporter that seals effect spans as Capsules and writes this block. It applies the allow-list in Section 3.2 as default-deny and carries trace_id, span_id, parent_span_id, and span_name as SHA-256 digests unless a deployment opts into clear values, taking the conservative branch of Section 6 by default. It places the block under model_attestation.compute_attestation as described in the block section. The exporter is accompanied by a leak test that runs the real block builder against a deliberately poisoned allow-list to show the leak, then against the real table to show none.

9. Conformance Vectors

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 typed digest references (for example, an attestation_refs entry in the runtime extension), a different and narrower thing than a named payload extension like this one.

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 MUST reproduce the same capsule_id under JCS [RFC8785] canonicalization as any other payload member):

{
  "org.agentactioncapsule.otel": {
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "span_id": "00f067aa0ba902b7",
    "trace_flags": "01",
    "resource": { "service.name": "support-agent" },
    "semconv": {
      "source": "open-telemetry/semantic-conventions-genai@8c1b98a",
      "gen_ai.provider.name": "local",
      "gen_ai.operation.name": "execute_tool"
    }
  }
}

MUST-FAIL vectors (a conformant implementation MUST reject the field, or MUST treat the block as informational-only per Section 3 and Section 6):

// (a) malformed trace_id: 31 hex characters, and mixed case.
{ "org.agentactioncapsule.otel": {
    "trace_id": "4BF92F3577b34da6a3ce929d0e0e473",
    "span_id": "00f067aa0ba902b7" } }

// (b) tracestate carried in clear; MUST be a digest or absent.
{ "org.agentactioncapsule.otel": {
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "span_id": "00f067aa0ba902b7",
    "tracestate": "congo=t61rcWkgMzE" } }

// (c) semconv member outside the allow-list in {{semconv}}.
{ "org.agentactioncapsule.otel": {
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "span_id": "00f067aa0ba902b7",
    "semconv": { "gen_ai.input.messages":
                 [{"role": "user", "content": "…"}] } } }

10. IANA Considerations

This document has no IANA actions. The org.agentactioncapsule.otel member name is a namespaced payload member per Section 3 and is not IANA-governed. Registration of this document as a conforming tier-2 profile awaits the registry work noted in Section 9; this document requests no IANA action for it. Registration of the aac.capsule_id span attribute is requested of the OpenTelemetry semantic-conventions registry, not IANA.

11. References

11.1. Normative References

[I-D.mih-scitt-agent-action-capsule]
Mih, S., "An Agent Action Capsule Profile for SCITT", Work in Progress, Internet-Draft, draft-mih-scitt-agent-action-capsule-05, , <https://datatracker.ietf.org/doc/html/draft-mih-scitt-agent-action-capsule-05>.
[I-D.mih-sokolov-scitt-payload-binding]
Mih, S. and A. Sokolov, "Canonicalization Declaration for SCITT Signed Statements", Work in Progress, Internet-Draft, draft-mih-sokolov-scitt-payload-binding-05, , <https://datatracker.ietf.org/doc/html/draft-mih-sokolov-scitt-payload-binding-05>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC8785]
Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, , <https://www.rfc-editor.org/rfc/rfc8785>.
[W3C.TraceContext]
W3C, "Trace Context", , <https://www.w3.org/TR/trace-context/>.

11.2. Informative References

[I-D.mih-agent-accountability-conformance]
Mih, S., "Agent Accountability: A Conformance and Verification Method", Work in Progress, Internet-Draft, draft-mih-agent-accountability-conformance-00, , <https://datatracker.ietf.org/doc/draft-mih-agent-accountability-conformance/>.
[OTEL-BAGGAGE]
OpenTelemetry, "OpenTelemetry Baggage", n.d., <https://opentelemetry.io/docs/specs/otel/baggage/api/>.
[OTEL-GENAI]
OpenTelemetry, "OpenTelemetry GenAI Semantic Conventions (repository open-telemetry/semantic-conventions-genai, commit 8c1b98a)", , <https://github.com/open-telemetry/semantic-conventions-genai>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, , <https://www.rfc-editor.org/rfc/rfc7942>.

Appendix A. Example

{
  "spec_version": "draft-mih-scitt-agent-action-capsule-05",
  "format_version": "4",
  "canonicalization_id": "jcs",
  "capsule_id": "…",
  "action_id": "act-7f3e…",
  "action_type": "decide",
  "operator": "example-tenant",
  "developer": "support-agent@2.3.1",
  "timestamp": "2026-09-04T18:02:11Z",
  "org.agentactioncapsule.otel": {
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "span_id": "00f067aa0ba902b7",
    "trace_flags": "01",
    "resource": { "service.name": "support-agent",
                  "service.version": "2.3.1" },
    "semconv": {
      "source": "open-telemetry/semantic-conventions-genai@8c1b98a",
      "gen_ai.provider.name": "local",
      "gen_ai.operation.name": "execute_tool",
      "gen_ai.usage.input_tokens": 412,
      "gen_ai.usage.output_tokens": 88
    }
  }
}

Appendix B. Acknowledgments

The authors thank the maintainers of the OpenTelemetry GenAI semantic conventions, whose attribute vocabulary this document admits by reference, and the contributors to the capsule-emit OpenTelemetry exporter, whose implementation shaped the digest-only defaults in Section 6.

Authors' Addresses

Govindaraj Palanisamy
Independent
Steven Mih
Action State Group, Inc.