Skip to content

docs: Add AURA security and data-handling guide; correct OTEL content-recording docs - #95

Open
promptless[bot] wants to merge 4 commits into
mainfrom
promptless/aura-security-data-handling
Open

promptless[bot] wants to merge 4 commits into
mainfrom
promptless/aura-security-data-handling

Conversation

@promptless

@promptless promptless Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Open in Promptless

Adds a new operator-facing security and data-handling reference for AURA at /aura/security, derived from the new SECURITY.md added in mezmo/aura PR #524. The page covers AURA's safety boundary and operator responsibilities, the two independent telemetry mechanisms (Mezmo CLI product telemetry and operator OpenTelemetry export), credentials handling, data retention and LLM egress, RBAC and MCP permission boundaries, read-only versus mutating tools, approval and fail-closed behavior, prompt injection from logs and runbooks, vulnerability reporting, and release integrity.

It also corrects and expands the OTEL content-recording documentation on two existing pages. OTEL_RECORD_CONTENT gates content only on AURA-owned spans, so OTEL_RECORD_CONTENT=false does not fully suppress exported content: Rig-owned chat, agent-turn, and tool spans record prompt, response, and tool content regardless of the flag, truncated by OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT (65,536 bytes) rather than OTEL_CONTENT_MAX_LENGTH (1,000 bytes).

Folds in mezmo/aura PR #543: when OTEL_RECORD_CONTENT=true, AURA-owned spans now also record the assembled system prompt (the preamble, which includes the orchestration instructions and the skills catalog), truncated by OTEL_CONTENT_MAX_LENGTH. At export it appears as leading system entries in llm.input_messages in Phoenix and other OpenInference viewers. The aura/tracing-spans.mdx content-recording and span-attributes sections and the aura/cli-reference.mdx OTEL environment-variable table are updated to reflect this and to cross-link the new security page.

Folds in mezmo/aura PR #566 (fix empty assistant content 400, enrich Phoenix span). This change enriches the exported OpenTelemetry spans and moves where token counts live, so the tracing and reference pages are updated to match shipped behavior:

  • New PHOENIX_PROJECT_NAME environment variable — sets the openinference.project.name resource attribute, the only attribute Phoenix uses to route a trace to a project. Documented in aura/tracing-spans.mdx and the aura/cli-reference.mdx OTEL environment-variable table, with the multi-replica rule to set the same value on every pod so their traces group into one project.
  • Breaking change (observability): llm.token_count.total and llm.token_count.tool_completion are no longer emitted on AURA-owned spans. Per-turn llm.token_count.prompt and llm.token_count.completion on each agent.turn span replace them, and Phoenix aggregates cost from those turns. A migration warning tells operators to repoint dashboards and alerts.
  • Span-kind reclassification — the agent-level spans (agent.stream, agent.prompt, agent.chat, orchestration.planning, orchestration.worker) now export as LLM, and vector.search exports as RETRIEVER. The span-kinds table and trace diagrams are updated, and a new Retriever spans section documents retrieval.documents.{i}.*.
  • New span attributes and eventllm.provider, agent.name, llm.invocation_parameters, llm.tools.{i}.tool.json_schema, llm.prompt_template.template/.variables, aura.version, aura.mode, service.version, and an exception span event carrying exception.message.
  • New request fields — the OpenAI-compatible user and metadata fields on /v1/chat/completions are documented in aura/web-server-reference.mdx, including that they surface only as span attributes on exported traces.
  • The aura/security.mdx OTLP export section now also lists the retrieval-document and prompt-template-variable content families as gated by OTEL_RECORD_CONTENT.

Files: new aura/security.mdx; edits to aura/cli-reference.mdx, aura/tracing-spans.mdx, aura/web-server-reference.mdx, docs.json (navigation), and the Vale vocabulary.

Trigger Events


Tip: Filter the Dashboard by labels or assignees to focus on what matters to you 🔎

promptless Bot added 2 commits August 13, 2026 17:25
…t-recording

Document AURA's operator security and data-handling model (mezmo/aura PR #524):
new aura/security.mdx covering the safety boundary, telemetry and data egress,
credentials, data retention, RBAC/MCP permission boundaries, approval and
fail-closed behavior, prompt injection, vulnerability reporting, and release
integrity.

Correct aura/cli-reference.mdx and aura/tracing-spans.mdx: OTEL_RECORD_CONTENT
gates content only on AURA-owned spans, so false does not fully suppress export;
Rig-owned spans record content regardless, truncated by
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT (65536 bytes) not OTEL_CONTENT_MAX_LENGTH.

Add nav entry and Vale vocabulary.
Fold mezmo/aura PR #543 into the OTEL_RECORD_CONTENT documentation: when
enabled, AURA-owned spans now also record the assembled system prompt (the
preamble, including orchestration instructions and the skills catalog),
truncated by OTEL_CONTENT_MAX_LENGTH and exported as leading system entries
in llm.input_messages. Correct the Rig-owned span list in the cli-reference
OTEL table.
Comment thread aura/security.mdx

Treat data returned by logs, runbooks, vector stores, webpages, and MCP servers as untrusted model input.

[aura-web-server](/aura/web-server-reference) has no end-user authentication and no identity-aware role-based access control (RBAC) for its OpenAI-compatible API. Bind it to a private interface, or place it behind an authenticated Transport Layer Security (TLS) gateway or service mesh.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aura-web-server has no end-user auth or identity-aware RBAC on its OpenAI-compatible API; bind to a private interface or place behind an authenticated TLS gateway/service mesh — verified verbatim against SECURITY.md "Safety Boundary" section.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L20-L22

@mintlify

mintlify Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
mezmo-docs 🟢 Ready View Preview Aug 18, 2026, 5:18 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread aura/security.mdx

[aura-web-server](/aura/web-server-reference) has no end-user authentication and no identity-aware role-based access control (RBAC) for its OpenAI-compatible API. Bind it to a private interface, or place it behind an authenticated Transport Layer Security (TLS) gateway or service mesh.

An air-gapped deployment requires every enabled network dependency to be local or disabled. AURA does not implement a general-purpose egress firewall, so you enforce that boundary with your own network policy. See Data Retention and Large Language Model Egress below for the destinations to check against this rule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An air-gapped deployment requires every enabled network dependency to be local or disabled; AURA implements no general-purpose egress firewall, so the operator enforces that boundary with network policy (specific destinations enumerated in the Data Retention and LLM Egress section below) -- verified against SECURITY.md's "Safety Boundary and Operator Responsibilities" air-gapped-deployment paragraph.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L24-L31

Comment thread aura/security.mdx Outdated
Once OpenTelemetry Protocol (OTLP) export is on, treat the collector as a recipient of prompt, response, and tool content. `OTEL_RECORD_CONTENT=false` is **not** a complete content-suppression control. Do not set `OTEL_EXPORTER_OTLP_ENDPOINT` unless the collector and its downstream systems are approved to receive model and tool content.
</Warning>

AURA emits two kinds of spans. AURA-owned spans honor `OTEL_RECORD_CONTENT`; Rig-owned spans (created by the underlying Rig library) do not. For AURA-owned spans, `OTEL_RECORD_CONTENT=false` (the default) omits prompt and completion text, and tool arguments and results. `OTEL_RECORD_CONTENT=true` includes them, subject to `OTEL_CONTENT_MAX_LENGTH` (default 1000 bytes). Rig-owned spans (`chat`, `chat_streaming`, `agent.turn`, and `execute_tool`) record content independently of that flag. AURA translates their prompt, response, message, tool-argument, and tool-result attributes for export, subject to `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` (65,536 bytes by default), not `OTEL_CONTENT_MAX_LENGTH`. So setting `OTEL_RECORD_CONTENT=false` still exports content from Rig-owned spans.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL_RECORD_CONTENT=false (default) omits AURA-owned span content; =true includes it bounded by OTEL_CONTENT_MAX_LENGTH (default 1000 bytes, per logging.rs); Rig-owned spans (chat, chat_streaming, agent.turn, execute_tool -- exact names per openinference_exporter.rs infer_span_kind) record content independently of that flag, bounded by OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT (65,536 bytes default, DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT const), not OTEL_CONTENT_MAX_LENGTH -- verified against SECURITY.md's "Operator OpenTelemetry Export" section plus source defaults/span names in logging.rs and openinference_exporter.rs.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L85-L98

Comment thread aura/security.mdx

## Credentials

Reference credentials with environment-variable placeholders such as `{{ env.OPENAI_API_KEY }}` instead of writing literal secrets into your TOML, and populate those environment variables from your secret manager. Initialization keeps the placeholder in `config.toml`, but if you enter a new key, the CLI can write it to a local `.env` file using normal filesystem permissions rather than a restrictive mode. Restrict that file and exclude it from version control.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user enters a new key during init, the CLI may write it to a local .env using the process's normal filesystem permissions rather than a dedicated restrictive mode; operator must restrict the file and exclude it from version control — verified against SECURITY.md "Credentials" section.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L105-L108

Comment thread aura/security.mdx

## RBAC and MCP Permission Boundaries

`mcp_filter` and `client_tool_filter` control which named tools an agent or worker sees. An explicit empty `mcp_filter` grants no MCP tools, while a missing filter can expose every discovered tool. Use explicit allow-lists for every agent and worker.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcp_filter/client_tool_filter are capability-reduction controls, not user-aware RBAC; empty mcp_filter grants no MCP tools, missing filter can expose all discovered tools; enforce RBAC at ingress/MCP/IAM/k8s/network layers — verified against SECURITY.md "RBAC and MCP Permission Boundaries."

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L166-L175

Comment thread aura/security.mdx

## Approval and Fail-Closed Behavior

The `[hitl]` policy gates only tool names that match its `require_approval` glob patterns. A matching call reaches its tool only after the configured route returns an `Approved` decision. The following outcomes all fail closed for that call:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[hitl] gates only tool names matching require_approval glob patterns; a matching call proceeds only after an Approved decision; denial/timeout/disconnect/shutdown/malformed-rejected/transport failures fail closed for that call but do not block the model from proposing another — verified against SECURITY.md "Approval and Fail-Closed Behavior" (note: source treats "Denial short-circuits that call" as distinct from the enumerated error-return outcomes; see corrections).

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L193-L199

Comment thread aura/security.mdx

## Vulnerability Reporting

Report suspected vulnerabilities privately to [security@mezmo.com](mailto:security@mezmo.com). GitHub private vulnerability reporting is not enabled for the repository, so do not rely on its private-advisory URL. Include the affected version, deployment mode, reproduction steps, impact, and any proposed mitigation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Report vulnerabilities privately to security@mezmo.com; GitHub private vulnerability reporting is not currently enabled for the repository, so do not rely on the repo's private-advisory submission URL — verified verbatim against SECURITY.md "Vulnerability Reporting."

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L237-L240

Comment thread aura/security.mdx

## Release Integrity and Supply Chain

Release binaries and `.deb` and `.rpm` packages ship with SHA-256 checksums. The install script requires a matching checksum by default, and a mismatch is always fatal. Keep `AURA_REQUIRE_CHECKSUM=1`, or supply a separately obtained trusted checksum with `AURA_CHECKSUMS`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release binaries and .deb/.rpm packages ship with SHA-256 checksums; install script requires a matching checksum by default and a mismatch is always fatal; keep AURA_REQUIRE_CHECKSUM=1 or supply a trusted checksum via AURA_CHECKSUMS — verified against SECURITY.md and cross-checked against docs_repos/mezmo__documentation/aura/installation.mdx (AURA_REQUIRE_CHECKSUM default 1, mismatch always fatal, AURA_CHECKSUMS is a local checksums.txt path).

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L253-L256

Comment thread aura/tracing-spans.mdx
When `OTEL_RECORD_CONTENT=true`, prompt/completion text and tool
arguments/results are recorded as span attributes, truncated to
`OTEL_CONTENT_MAX_LENGTH` (default 1000 bytes, rounded to a UTF-8 boundary).
`OTEL_RECORD_CONTENT` governs only AURA-owned spans. When `false` (the default),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL_RECORD_CONTENT=false does not fully suppress content; Rig-owned chat/agent-turn/tool spans record prompt/response/structured-message/tool-argument/tool-result content independently of the flag, bounded by OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT (65,536 bytes default), not OTEL_CONTENT_MAX_LENGTH — verified against SECURITY.md.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L89-L93

Comment thread aura/cli-reference.mdx
| `OTEL_LOG_LEVEL` | Override the OTel layer's filter. Default captures `aura=trace`, `aura_cli=info`, and rig spans. |
| `OTEL_RECORD_CONTENT` | When `true`, prompt/completion/tool args/results are recorded as span attributes. |
| `OTEL_CONTENT_MAX_LENGTH` | Max bytes for content attributes (default 1000, rounded down to UTF-8 boundary). |
| `OTEL_RECORD_CONTENT` | Gates content, including the assembled system prompt, on AURA-owned spans (`false` default omits it). Rig-owned `chat`, `chat_streaming`, `agent.turn`, and `execute_tool` spans record content regardless, so `false` does not fully suppress exported content. See [Security and Data Handling](/aura/security). |

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL_RECORD_CONTENT does not fully suppress content when false — Rig-owned spans record content independently, bounded by OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT — verified against SECURITY.md's Rig-owned-span content-export limitation.

Source: https://github.com/mezmo/aura/blob/6c4a5ba66d899a831ff2c589fafe029168af39da/SECURITY.md#L89-L93

Comment thread aura/security.mdx

- **Model provider:** the system prompt, user input, relevant conversation history, and tool results placed into model context.
- **MCP server:** the selected tool name and its arguments, which can contain user input or model-derived data.
- **Optional destinations:** retrieval-augmented generation (RAG) services, approval webhooks, Redis-compatible session stores, and OTLP collectors, only when you configure them. An approval webhook receives the tool name and arguments under review, and by default that request is unsigned and can use plaintext `http://` unless you configure a signing secret (see Approval and Fail-Closed Behavior below). A Redis-compatible session store can hold operational data such as parked approval payloads and task state, so treat it as a destination with comparable sensitivity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval webhook request body includes tool_name and arguments (see ApprovalRequestWire/ApprovalItem in protocol.rs and the documented webhook JSON payload in hitl.mdx); by default (no HMAC secret) the request is unsigned and http:// is permitted -- verified against route.rs EgressSigning::Disabled default and WebhookHmac::load_from_env (signing.rs L309-357, "unsigned and unverified" when unset).

Source: https://github.com/mezmo/aura/blob/f0aacb8b410f3ad2f3f98e2eb2fad28f9bb566b1/crates/aura/src/hitl/route.rs#L491-L498

Comment thread aura/security.mdx

- **Model provider:** the system prompt, user input, relevant conversation history, and tool results placed into model context.
- **MCP server:** the selected tool name and its arguments, which can contain user input or model-derived data.
- **Optional destinations:** retrieval-augmented generation (RAG) services, approval webhooks, Redis-compatible session stores, and OTLP collectors, only when you configure them. An approval webhook receives the tool name and arguments under review, and by default that request is unsigned and can use plaintext `http://` unless you configure a signing secret (see Approval and Fail-Closed Behavior below). A Redis-compatible session store can hold operational data such as parked approval payloads and task state, so treat it as a destination with comparable sensitivity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Redis-compatible session store can hold operational data such as parked approval payloads and task state -- verified against configuration-reference.mdx's Session Store section: "cross-request session state (A2A tasks, parked HITL approvals) lives in process memory... configure a shared Redis/Valkey backend" for multi-pod deployments.

Source:

By default, cross-request session state (A2A tasks, parked HITL approvals) lives in process memory — correct for a single pod, the CLI, and local dev. Behind a load balancer with multiple replicas, configure a shared Redis/Valkey backend and every cross-request flow works no matter which pod serves each request: A2A `message:send` → poll → `list` → history-by-context, A2A `subscribe`/`cancel` against a task executing on another pod, and conversational HITL approvals resolved by a `POST /v1/approvals/{id}` that lands away from the pod that parked them.

Comment thread aura/security.mdx

AURA does not establish that an approver is human. A conversational decision comes from the connected client, and a webhook decision can come from a person or an automated service. Your deployment must authenticate users and enforce approver identity and authorization outside AURA.

Webhook hash-based message authentication code (HMAC) signing and verification are optional. Without a signing secret (the `AURA_HITL_WEBHOOK_SECRET` environment variable), AURA sends unsigned requests, accepts unsigned responses, and permits a plaintext `http://` URL. When you set that secret, AURA rejects unsigned or invalid responses and rejects plaintext URLs. Production should use TLS and HMAC.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The webhook HMAC signing secret is the environment variable AURA_HITL_WEBHOOK_SECRET (PRIMARY_SECRET_VAR const), read only via WebhookHmac::load_from_env (signing.rs L309-357) -- not a TOML field. Without it, load_from_env returns Ok(None) and logs "webhook traffic is unsigned and unverified" (L317-322); route.rs defaults EgressSigning::Disabled (permits plaintext http://) and rejects/misconfigures a plaintext http:// URL once a secret is configured (route.rs L488-498, boot guard validate_webhook_signing_config L674-687).

Source: https://github.com/mezmo/aura/blob/f0aacb8b410f3ad2f3f98e2eb2fad28f9bb566b1/crates/aura/src/hitl/signing.rs#L36-L38

Comment thread aura/security.mdx Outdated
Once OpenTelemetry Protocol (OTLP) export is on, treat the collector as a recipient of prompt, response, and tool content. `OTEL_RECORD_CONTENT=false` is **not** a complete content-suppression control. Do not set `OTEL_EXPORTER_OTLP_ENDPOINT` unless the collector and its downstream systems are approved to receive model and tool content.
</Warning>

AURA emits two kinds of spans. AURA-owned spans honor `OTEL_RECORD_CONTENT`; Rig-owned spans (created by the underlying Rig library) do not. For AURA-owned spans, `OTEL_RECORD_CONTENT=false` (the default) omits prompt and completion text, and tool arguments and results. `OTEL_RECORD_CONTENT=true` includes them, subject to `OTEL_CONTENT_MAX_LENGTH` (default 1000 bytes). Rig-owned spans (`chat`, `chat_streaming`, `agent.turn`, and `execute_tool`) record content independently of that flag. AURA translates their prompt, response, message, tool-argument, and tool-result attributes for export, subject to `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` (65,536 bytes by default), not `OTEL_CONTENT_MAX_LENGTH`. So setting `OTEL_RECORD_CONTENT=false` still exports content from Rig-owned spans.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL_CONTENT_MAX_LENGTH default is 1000 bytes -- verified against logging.rs doc comment "Controlled by OTEL_CONTENT_MAX_LENGTH env var (default 1000)" (also stated identically in cli-reference.mdx and tracing-spans.mdx, both previously verified).

Source: https://github.com/mezmo/aura/blob/f0aacb8b410f3ad2f3f98e2eb2fad28f9bb566b1/crates/aura/src/logging.rs#L154

Comment thread aura/security.mdx Outdated
Once OpenTelemetry Protocol (OTLP) export is on, treat the collector as a recipient of prompt, response, and tool content. `OTEL_RECORD_CONTENT=false` is **not** a complete content-suppression control. Do not set `OTEL_EXPORTER_OTLP_ENDPOINT` unless the collector and its downstream systems are approved to receive model and tool content.
</Warning>

AURA emits two kinds of spans. AURA-owned spans honor `OTEL_RECORD_CONTENT`; Rig-owned spans (created by the underlying Rig library) do not. For AURA-owned spans, `OTEL_RECORD_CONTENT=false` (the default) omits prompt and completion text, and tool arguments and results. `OTEL_RECORD_CONTENT=true` includes them, subject to `OTEL_CONTENT_MAX_LENGTH` (default 1000 bytes). Rig-owned spans (`chat`, `chat_streaming`, `agent.turn`, and `execute_tool`) record content independently of that flag. AURA translates their prompt, response, message, tool-argument, and tool-result attributes for export, subject to `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` (65,536 bytes by default), not `OTEL_CONTENT_MAX_LENGTH`. So setting `OTEL_RECORD_CONTENT=false` still exports content from Rig-owned spans.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exact Rig-owned span names are chat, chat_streaming, agent.turn, and execute_tool -- verified against openinference_exporter.rs infer_span_kind match arms ("chat" | "chat_streaming" | "agent.turn" => "LLM"; "execute_tool" | "mcp.tool_call" => "TOOL") and corresponding unit tests (L492-499).

Source: https://github.com/mezmo/aura/blob/f0aacb8b410f3ad2f3f98e2eb2fad28f9bb566b1/crates/aura/src/openinference_exporter.rs#L108-L113

Comment thread aura/tracing-spans.mdx

## Span attributes

*When `OTEL_RECORD_CONTENT=true`, AURA also records the assembled system prompt on the agent entry-point spans (`agent.stream`, `agent.prompt`, `agent.chat`) and on the `orchestration.planning` and `orchestration.worker` spans. See [Content recording](#content-recording).*

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_system_prompt_attribute (gated on should_record_content) records gen_ai.system_instructions; called on all five spans named in the doc sentence: agent.prompt and agent.chat via record_input_attributes (builder.rs L1140/L1165 calling L1568), orchestration.planning (orchestrator.rs L1468-1471), orchestration.worker (orchestrator.rs L3105-3109), and the agent.stream span via StreamOtelContext::record_input (aura-web-server/src/streaming/otel.rs L51-53), which is invoked for both the streaming and non-streaming HTTP completion paths (handlers.rs L546-559) -- verified against merged PR mezmo/aura#543 (commit 474556e).

Source: https://github.com/mezmo/aura/blob/474556efc177bbd18670f2ce4a130bcb824f9b8e/crates/aura/src/logging.rs#L544-L560

Comment thread aura/tracing-spans.mdx
it omits prompt and completion text, and tool arguments and results. When `true`,
it includes them, along with the assembled system prompt (the preamble, which
includes the orchestration instructions and the skills catalog). AURA truncates
all of this content to `OTEL_CONTENT_MAX_LENGTH` (default 1000 bytes, rounded down

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

system_instructions_json truncates the prompt text via truncate_for_otel (OTEL_CONTENT_MAX_LENGTH) before JSON-serializing it as the gen_ai.system_instructions parts array, confirming the system prompt is truncated pre-serialization rather than post-serialization -- verified against merged PR mezmo/aura#543 (commit 474556e). Assembled preamble = orchestration instructions + skills catalog per builder.rs L436-438 (config.effective_preamble() + render_skill_catalog) and the PR's own commit message.

Source: https://github.com/mezmo/aura/blob/474556efc177bbd18670f2ce4a130bcb824f9b8e/crates/aura/src/logging.rs#L544-L546

Comment thread aura/tracing-spans.mdx
to the nearest UTF-8 boundary). At export, the recorded system prompt appears as
leading `system` entries in the input messages (`llm.input_messages`) in Phoenix
and other OpenInference viewers. AURA translates the raw `gen_ai.system_instructions`
key into those leading `system` entries rather than exporting it directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At export, gen_ai.system_instructions is parsed (parse_system_instructions, L451) into leading role:"system" entries prepended to llm.input_messages (L233-252); span.attributes.retain(...) at L290-291 strips every gen_ai.* key, including the raw gen_ai.system_instructions, so it is translated and not exported verbatim -- verified against merged PR mezmo/aura#543 (commit 474556e).

Source: https://github.com/mezmo/aura/blob/474556efc177bbd18670f2ce4a130bcb824f9b8e/crates/aura/src/openinference_exporter.rs#L182-L252

Comment thread aura/cli-reference.mdx
| `OTEL_LOG_LEVEL` | Override the OTel layer's filter. Default captures `aura=trace`, `aura_cli=info`, and rig spans. |
| `OTEL_RECORD_CONTENT` | When `true`, prompt/completion/tool args/results are recorded as span attributes. |
| `OTEL_CONTENT_MAX_LENGTH` | Max bytes for content attributes (default 1000, rounded down to UTF-8 boundary). |
| `OTEL_RECORD_CONTENT` | Gates content, including the assembled system prompt, on AURA-owned spans (`false` default omits it). Rig-owned `chat`, `chat_streaming`, `agent.turn`, and `execute_tool` spans record content regardless, so `false` does not fully suppress exported content. See [Security and Data Handling](/aura/security). |

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL_RECORD_CONTENT (via should_record_content) gates set_system_prompt_attribute, which records the assembled system prompt as gen_ai.system_instructions on AURA-owned spans -- verified against merged PR mezmo/aura#543 (commit 474556e). Default false confirmed at logging.rs L145 / L182-185 (bool_env("OTEL_RECORD_CONTENT", false)).

Source: https://github.com/mezmo/aura/blob/474556efc177bbd18670f2ce4a130bcb824f9b8e/crates/aura/src/logging.rs#L544-L560

- Add PHOENIX_PROJECT_NAME (openinference.project.name routing) to
  tracing-spans and the CLI OTel env-var table, with the multi-replica
  same-value rule.
- Reclassify agent-level spans to LLM and vector.search to RETRIEVER in
  the span-kinds table and trace diagrams; document retrieval.documents.*.
- Record the token-count breaking change: llm.token_count.total and
  llm.token_count.tool_completion removed from AURA spans; per-turn
  prompt/completion counts now on agent.turn, with a migration Warning.
- Document new span attributes (llm.provider, agent.name,
  llm.invocation_parameters, llm.tools.*, llm.prompt_template.*,
  aura.version, aura.mode, service.version) and the exception span event.
- Document the OpenAI-compatible user and metadata request fields on the
  web server reference.
- Extend the security page's OTLP content scope to the new content-bearing
  attribute families.
Comment thread aura/tracing-spans.mdx
[Phoenix](https://github.com/Arize-ai/phoenix) and other OpenInference-aware
observability tools.

Set `PHOENIX_PROJECT_NAME` to choose which Phoenix project receives your

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHOENIX_PROJECT_NAME sets the openinference.project.name OTLP resource attribute; when unset it falls back to service_name (OTEL_SERVICE_NAME, then "aura"); service.version resource attr is also set from CARGO_PKG_VERSION here -- verified against mezmo/aura PR #566 (merged commit c3b8b996), init_otel_provider in logging.rs.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L300-L315

Comment thread aura/cli-reference.mdx
| `OTEL_RECORD_CONTENT` | Gates content, including the assembled system prompt, on AURA-owned spans (`false` default omits it). Rig-owned `chat`, `chat_streaming`, `agent.turn`, and `execute_tool` spans record content regardless, so `false` does not fully suppress exported content. See [Security and Data Handling](/aura/security). |
| `OTEL_CONTENT_MAX_LENGTH` | Max bytes for content attributes on AURA-owned spans (default 1000, rounded down to the nearest UTF-8 boundary). |
| `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` | Truncation limit for translated Rig-owned content (default 65,536 bytes, rounded down to the nearest UTF-8 boundary). |
| `PHOENIX_PROJECT_NAME` | Sets the `openinference.project.name` resource attribute. Phoenix routes traces to a project by that attribute alone and ignores `service.name` and `OTEL_SERVICE_NAME` for routing. When unset, AURA sets the attribute to the service name (`OTEL_SERVICE_NAME`, then `aura`) instead, so traces are grouped under a project of that name. |

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHOENIX_PROJECT_NAME table row: sets openinference.project.name resource attr; Phoenix routing ignores service.name/OTEL_SERVICE_NAME per source comment; unset falls back to service_name -- verified against mezmo/aura PR #566 (merged commit c3b8b996), init_otel_provider in logging.rs.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L300-L315

Comment thread aura/tracing-spans.mdx

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Line 65)

infer_span_kind match arms confirm exact reclassification: agent.stream/agent.prompt/agent.chat/orchestration.planning/orchestration.worker -> LLM; vector.search -> RETRIEVER; chat_completions/streaming_completion/orchestration/orchestration.iteration -> CHAIN (orchestration.planning removed from CHAIN); execute_tool/mcp.tool_call -> TOOL -- verified against mezmo/aura PR #566 (merged commit c3b8b996). Confirms diagrams and the OpenInference span kinds table.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/openinference_exporter.rs#L119-L142

Comment thread aura/tracing-spans.mdx

RAG-enabled agents emit an additional `vector.search (RETRIEVER)` span under
`execute_tool`, alongside `mcp.tool_call`, wherever the agent calls a
vector-search tool.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StreamOtelContext::record_input stamps ATTR_AURA_VERSION (aura.version, from CARGO_PKG_VERSION) and ATTR_AURA_MODE (aura.mode = "orchestration"/"single-agent") on the agent.stream root span; service.version is set separately on the tracer resource (logging.rs init_otel_provider) -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura-web-server/src/streaming/otel.rs#L57-L64

Comment thread aura/tracing-spans.mdx
`llm.token_count.prompt`, `llm.token_count.completion`, `llm.token_count.total`
`aura.version`, `aura.mode`.

`aura.version` and `aura.mode` are stamped on the streaming root so you can

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_llm_identifiers now sets both ATTR_LLM_SYSTEM (llm.system) and the new ATTR_LLM_PROVIDER (llm.provider) to the same provider string -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L499-L505

Comment thread aura/tracing-spans.mdx
filter traces by release and by serving path. `service.version` is set on the
tracer resource.

### Agent and LLM spans

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

llm_invocation_parameters() builds the llm.invocation_parameters JSON (temperature, max_tokens, additional_params) from the effective LlmConfig; set_llm_invocation_parameters writes it as the ATTR_LLM_INVOCATION_PARAMETERS attribute -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L514-L539

Comment thread aura/tracing-spans.mdx
tracer resource.

### Agent and LLM spans

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

McpManager::tool_schemas_json(filter) serializes MCP tool definitions as OpenAI-style function schemas for llm.tools.{i}.tool.json_schema; filter narrows by worker mcp_filter glob patterns, None includes every tool -- verified against mezmo/aura PR #566 (merged commit c3b8b996). Called with a per-worker filter in orchestrator.rs execute_task (L3118-3123) and unfiltered for single-agent spans in builder.rs otel_llm_tools().

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/mcp.rs#L1150-L1177

Comment thread aura/tracing-spans.mdx
- `llm.tools.{i}.tool.json_schema` holds the MCP tool schemas each agent
advertises, filtered per worker.
- `user.id` comes from the request `user` field, and `metadata` comes from the
request metadata map. See the [web server reference](/aura/web-server-reference)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execute_task (the orchestration.worker span) calls set_llm_prompt_template with the WORKER_TASK_PROMPT_TEMPLATE and CONTEXT/YOUR_TASK variables, adding llm.prompt_template.template and llm.prompt_template.variables to that span -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/orchestration/orchestrator.rs#L3137-L3144

Comment thread aura/tracing-spans.mdx
- `user.id` comes from the request `user` field, and `metadata` comes from the
request metadata map. See the [web server reference](/aura/web-server-reference)
for those request fields.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module doc: token counts now live only on agent.turn spans (Rig fork records per-call model identifiers and usage there); Phoenix prices those LLM-kind spans and rolls turns up per worker/phase/trace; no Aura-owned span records token counts -- verified against mezmo/aura PR #566 (merged commit c3b8b996). Backs the Warning box (lines 135-141) and the removal of llm.token_count.total/tool_completion.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L20-L28

Comment thread aura/tracing-spans.mdx
@@ -102,13 +175,35 @@ spans (planning, worker).

## Content recording

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_llm_prompt_template always records ATTR_LLM_PROMPT_TEMPLATE (the static template); ATTR_LLM_PROMPT_TEMPLATE_VARIABLES is only recorded when should_record_content() is true, and each variable value is passed through truncate_for_otel -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L543-L565

Comment thread aura/tracing-spans.mdx
translates and exports these attributes regardless of `OTEL_RECORD_CONTENT`.
Content is truncated to `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT` (default 65,536
bytes, rounded down to the nearest UTF-8 boundary), not `OTEL_CONTENT_MAX_LENGTH`. Because of this,
`OTEL_RECORD_CONTENT=false` is not a complete content-suppression control. See [Security and Data Handling](/aura/security)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_span_error now fires tracing::error!(error = msg) before span.set_status; the tracing-opentelemetry layer converts that error-field event into an OTel exception span event carrying exception.message -- verified against mezmo/aura PR #566 (merged commit c3b8b996). Anchor updated: this claim now lives in the dedicated "## Error spans" section (moved from within Content recording).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L466-L482

"metadata": {"team": "sre"}
}
```

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChatCompletionRequest gained a new optional user: Option<String> field (OpenAI-compatible end-user identifier); pre-existing metadata: Option<HashMap<String,String>> is now consumed -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura-web-server/src/types.rs#L230-L233


Two optional OpenAI-compatible fields carry request context into traces:

- `user`: optional string. An end-user identifier that flows into the `user.id` span attribute.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StreamOtelContext::record_input sets ATTR_USER_ID (user.id) from the request's user field and ATTR_METADATA (metadata) from the request's metadata map (serialized to a JSON string in handlers.rs prepare_request) -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura-web-server/src/streaming/otel.rs#L45-L77

Comment thread aura/tracing-spans.mdx
filter traces by release and by serving path. `service.version` is set on the
tracer resource.

### Agent and LLM spans

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exporter's gen_ai.* translation pass strips "gen_ai.agent.name" and re-emits it as "agent.name" (ungated by span kind, so it applies to whichever span carries the field). Rig's AgentBuilder.name(...) is what stamps gen_ai.agent.name on the agent.turn span: single-agent builds call .name(&config.agent.name) (builder.rs L479), the coordinator calls .name("coordinator") (orchestrator.rs L2125), and each worker calls .name(&worker_config.agent.name) (orchestrator.rs L2582/2629/2672/2707/2736/2770). Unit tests confirm the attribute lands on the agent.turn span specifically (test_translates_agent_metadata, L911-932, using the literal value "Unnamed Agent" as the pre-fix placeholder; test_pipeline_agent_turn_span, L1620-1676, asserting find_attr(turn, "agent.name")) -- verified against mezmo/aura PR #566 (merged commit c3b8b996). The doc no longer claims name sits directly on agent.stream or orchestration.worker.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/openinference_exporter.rs#L222-L225

Comment thread aura/tracing-spans.mdx

- Phoenix rolls the turn counts up as the single cost anchor, so every aggregate
(per worker, per phase, per trace) is computed from the turns.
- AURA's agent-level spans carry no token counts, so they price at zero and

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_retrieval_documents writes retrieval.documents.{i}.document.score unconditionally and retrieval.documents.{i}.document.content / .document.metadata only when should_record_content() (OTEL_RECORD_CONTENT) is true, per its own doc comment ("Scores are always recorded; content and metadata only when content recording is enabled"). infer_span_kind classifies the "vector.search" span name as RETRIEVER (openinference_exporter.rs L126). Wired from both static RAG tools (rag_tools.rs L71-99, create_vector_search_tool! macro: info_span!("vector.search", ...) then set_retrieval_documents(&span, &documents)) and the dynamic vector-store tool (vector_dynamic.rs L116-164) -- verified against mezmo/aura PR #566 (merged commit c3b8b996). The doc's claim that only "content" (not the score) follows the OTEL_RECORD_CONTENT gate is accurate and not an over-claim.

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/logging.rs#L594-L615

Comment thread aura/tracing-spans.mdx
content.

## OpenInference span kinds

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

infer_span_kind(name: &str) has always matched purely on the span's name (never on attributes) -- this PR only changed which kind names map to (agent.stream/agent.prompt/agent.chat/orchestration.planning/orchestration.worker moved from AGENT/CHAIN to LLM; vector.search added as RETRIEVER), not the mechanism. The reworded doc sentence ("Each span's kind follows from its span name. The agent-level spans now map to LLM...") correctly describes a mapping change, not a switch from attribute-based to name-based inference -- verified against mezmo/aura PR #566 (merged commit c3b8b996).

Source: https://github.com/mezmo/aura/blob/c3b8b99634924a4c01212cbcdb54fbe20316760e/crates/aura/src/openinference_exporter.rs#L119-L144

…ity-data-handling

# Conflicts:
#	aura/tracing-spans.mdx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants