Skip to content

Security

Content is exported on purpose

User prompts, assistant messages, tool input and tool output all ship to the log and trace sinks. Anything an agent printed, including a secret it happened to read, can land in the log store. This is a deliberate choice for a private single-tenant deployment. logs.record_types is the control: listing only the bodiless kinds gives an event timeline with no content.

Content never reaches the repository

Two guards, neither of which may be weakened:

  • TestNoTranscriptsAreTracked fails the build if anything transcript-shaped is staged. The .gitignore covers the corpus tree and the file extensions wherever they land, because a sample copied to a new path is the failure mode that actually happens.
  • TestSignature_CarriesNoConversationContent proves the committed drift baseline holds field names and types only, never a value from a transcript.

backlog/ is committed, so the same bar applies there: write the shape, not the instance. A task that quotes a real prompt to illustrate a decoder bug is a leak.

Cardinality is a safety property, not just a cost one

A metric attribute is indexed and retained differently from a log attribute. Identifiers and content are confined to logs and spans, where they ride as unindexed attributes. The rule is enforced in internal/attr rather than by convention, so a new field cannot reach a metric without a deliberate classification.

The transcript trees are read-only

The service opens them read-only and never writes, renames, locks or prunes. Retention is owned by agent-session-archive.timer on camden, and this service is not part of that chain. Its checkpoint lives outside the tree.

Credentials

The OTLP endpoint is the local Alloy on camden, which holds the Grafana Cloud credential through Fleet Management. This service carries no Grafana credential. If otlp.headers is ever set, it goes in config.yaml, which is gitignored; never in config.example.yaml.