
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@attestry/otel-agent-compliance
Advanced tools
OpenTelemetry SpanProcessor that emits Attestry ABDR records for compliance record-keeping
OpenTelemetry SpanProcessor that emits Attestry ABDR (Agent-Based Decision Record) entries for every AI tool call, LLM completion, retrieval, or policy evaluation that flows through your tracer. Every recorded decision becomes part of a hash-chained, cryptographically-verifiable compliance ledger you can replay against EU AI Act, NIST AI RMF, and ISO 42001 audits.
npm install @attestry/otel-agent-compliance @opentelemetry/sdk-node
@opentelemetry/sdk-node is a peer dependency. Install it alongside if you don't have it already.
import { NodeSDK } from "@opentelemetry/sdk-node";
import { AttestryDecisionExporter } from "@attestry/otel-agent-compliance";
const sdk = new NodeSDK({
spanProcessors: [
new AttestryDecisionExporter({
apiUrl: "https://attestry.app/api/v1/decisions/bulk",
apiKey: process.env.ATTESTRY_API_KEY!,
systemId: process.env.ATTESTRY_SYSTEM_ID!,
}),
],
});
sdk.start();
process.on("SIGTERM", async () => {
await sdk.shutdown(); // flushes the in-memory queue
});
By default, the exporter records a span as a decision when ANY of the following is true:
| Signal | Source |
|---|---|
ai.operation attribute set | OpenInference / OpenTelemetry semantic conventions |
gen_ai.operation.name attribute set | OTel GenAI semantic conventions |
tool.name attribute set | LangChain / LlamaIndex tool spans |
policy.outcome or decision.outcome attribute set | Customer policy engines |
Span name contains tool, llm, completion, or policy | Heuristic on framework span names |
Spans that don't match are dropped without making a network call. Override with shouldRecordAsDecision.
Each decision posted to /api/v1/decisions/bulk contains:
systemId — the Attestry system this exporter is attached toinputDigest — sha256: of the canonical-form span input (sorted keys)outputDigest — sha256: of the canonical-form span output, when presentframeworkClaims[] — heuristic mappings to EU AI Act / NIST AI RMF / ISO 42001 articlestoolInvocations[] — tool.name if setpolicyOutcome — permitted / denied / escalated if recognizedidempotencyKey — the OTel span ID (replay-safe)The exporter never sends raw span input or output text. Only digests cross the wire by default. Tools, prompts, and completions stay inside your process.
The default sanitizer redacts emails, phone numbers, US SSNs, credit card numbers, and IPv4 addresses inside any string-valued span attribute. Override with config.sanitizer to plug in HIPAA / GDPR special-category rules:
new AttestryDecisionExporter({
// ...
sanitizer: (attrs) => {
const out = { ...attrs };
delete out["http.request.body"]; // never ship request bodies
return out;
},
});
Heuristic mapping from span context to frameworkClaims[]. Customers with curated taxonomies override it:
new AttestryDecisionExporter({
// ...
frameworkTagger: ({ name, attributes }) => {
if (attributes["custom.tag"] === "loan-decision") {
return [
{
framework: "EU AI Act",
article: "Annex III §5(b)",
claim: "Creditworthiness evaluation for natural persons.",
},
];
}
return [];
},
});
| Option | Default | Description |
|---|---|---|
apiUrl | (required) | Full URL of the bulk ingest endpoint |
apiKey | (required) | API key with write:assessments permission |
systemId | (required) | Attestry system UUID |
batchSize | 20 | Flush trigger — records per batch |
batchInterval | 5000ms | Flush trigger — max delay before partial flush |
fetchTimeoutMs | 10_000 | Per-request abort timeout |
sanitizer | regex stripper | Override PII sanitization |
frameworkTagger | heuristic mapping | Override claim generation |
shouldRecordAsDecision | heuristic | Override decision detection |
logger | console (stderr) | Wire pino/winston/etc. via warn/error |
The exporter never throws to your application. Network errors, 5xx responses, and timeouts go through three retries with capped exponential backoff (250ms → 750ms → 2_250ms + jitter), then log via the configured logger and drop the batch. 4xx responses (other than 429) are treated as permanent — no retry, log + drop.
LangChain emits OTel spans automatically when LANGCHAIN_TRACING_V2=true and an OTel SDK is initialized in the process. Wire the exporter and every chain step shows up in Attestry.
LlamaIndex's OpenInference instrumentation tags spans with openinference.span.kind. The default decider catches them via the ai.operation / gen_ai.operation.name keys.
Wrap the SDK call in a manual span and set ai.operation to "completion":
import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer("my-app");
await tracer.startActiveSpan("openai.completion", async (span) => {
span.setAttribute("ai.operation", "completion");
span.setAttribute("input", prompt);
const result = await openai.chat.completions.create({ ... });
span.setAttribute("output", result.choices[0].message.content);
span.end();
});
Apache-2.0
FAQs
OpenTelemetry SpanProcessor that emits Attestry ABDR records for compliance record-keeping
We found that @attestry/otel-agent-compliance demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.