EVIDENCE / OPERATIONS

Keep the decision inspectable.

Audit, metrics, and telemetry serve different purposes. Configure and validate each surface you rely on.

Record format

DecisionRecord contains id, timestamp, effect, policies, principal, action, resource, reasons, request/session identifiers, and optional agent-chain, trace, tenant, subject, and authenticated-actor fields. Authenticated standalone PDP requests record the bound caller identity, API-key id, tenant, and whether the privileged authorize:any scope was used. This provenance is separate from the evaluated principal and Cedar context. JSONL, CEF, LEEF, and ECS exports retain it. A chained record adds chain_id, prev_hash, and record_hash. These records describe authorization decisions, not proof that the tool executed successfully.

Illustrative audit fields · abbreviated, not a complete record
{
  "principal": "research",
  "action": "repo_read",
  "resource": "demo",
  "effect": "allow",
  "authenticated_actor": {
    "subject_type": "Agent",
    "subject_id": "console-service",
    "credential_id": "key-123",
    "can_act_as": true
  },
  "policies": [
    "policy0"
  ],
  "timestamp": "2026-09-21T12:00:00Z",
  "prev_hash": "illustrative previous hash",
  "record_hash": "illustrative HMAC"
}

Enable and verify the chain

Set AGENTGUARD_CHAIN_SECRET to a protected secret file before starting the server or CLI authorization. Without a secret, the log is plain JSONL. HMAC-SHA256 chains records using canonical serialization. Keep the original log and .chainid sidecar together.

Audit operations
agentguard audit verify --audit .audit/decisions.jsonl --secret-file .chain-secret
agentguard audit export --format jsonl --out decisions.jsonl
agentguard audit export --format cef --out decisions.cef
agentguard audit export --format leef --out decisions.leef
agentguard audit export --format ecs --out decisions.ecs.jsonl

Exports reformat records for downstream ingestion; there are no managed Splunk, Elastic, or other vendor connectors implied. Configure your own collector, retention, and access controls. Exporting does not substitute for verifying the original chain.

Integrity limits

The HMAC secret is trusted. An attacker with that key can forge records. A valid chain alone does not prove completeness: keep independent trusted head checkpoints to detect truncation or wholesale replacement. Rotation and pseudonymization require preserving original evidence; audit erase changes records and invalidates their original authentication.

Server handlers return an error when a configured audit append fails. Embedders can omit audit configuration, and the core authorizer does not log automatically. The CLI can skip audit and prints its decision before appending; callers must wait for a successful process exit.

Trace context and metrics

HTTP middleware reads traceparent, creates a child span identifier, and returns x-agentguard-span-id. The single-evaluation handler copies trace context into the request for audit correlation. Do not assume identical correlation or metrics behavior across batch, gRPC, and embedded paths.

Health and Prometheus endpoints
curl http://127.0.0.1:8443/healthz
curl http://127.0.0.1:8443/readyz
curl http://127.0.0.1:8443/metrics

The telemetry Metrics type tracks decision count/duration, cache activity, policy reloads, and PDP errors. These are in-memory counters, not a durable audit trail. Scraping requires your monitoring infrastructure. Health/metrics routes are not protected by decision-route authentication.

OpenTelemetry and OTLP

agentguard-telemetry exposes Sink and SinkEvent with stdout, JSONL, and feature-gated OtlpSink implementations. The OTLP sink exports OpenTelemetry log records over gRPC, not an automatically installed distributed-tracing pipeline.

Construct the sink in your embedding application, emit events, and flush/shut it down. OtlpSink::from_env reads OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_SERVICE_NAME. Standalone server startup configures tracing-subscriber logging but does not instantiate this sink.

Actual exported attributes include agentguard.effect, agentguard.principal, agentguard.action, agentguard.resource, agentguard.cached, and optional trace.id, span.id, and agentguard.tenant_id. Do not assume an authz.* semantic convention that is not emitted by this code.

Sources: record schema, chain implementation, and OTLP exporter.