🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@attestry/otel-agent-compliance

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@attestry/otel-agent-compliance

OpenTelemetry SpanProcessor that emits Attestry ABDR records for compliance record-keeping

latest
Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

@attestry/otel-agent-compliance

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.

Install

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.

Quick start

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
});

What gets recorded

By default, the exporter records a span as a decision when ANY of the following is true:

SignalSource
ai.operation attribute setOpenInference / OpenTelemetry semantic conventions
gen_ai.operation.name attribute setOTel GenAI semantic conventions
tool.name attribute setLangChain / LlamaIndex tool spans
policy.outcome or decision.outcome attribute setCustomer policy engines
Span name contains tool, llm, completion, or policyHeuristic on framework span names

Spans that don't match are dropped without making a network call. Override with shouldRecordAsDecision.

What lands on the wire

Each decision posted to /api/v1/decisions/bulk contains:

  • systemId — the Attestry system this exporter is attached to
  • inputDigestsha256: of the canonical-form span input (sorted keys)
  • outputDigestsha256: of the canonical-form span output, when present
  • frameworkClaims[] — heuristic mappings to EU AI Act / NIST AI RMF / ISO 42001 articles
  • toolInvocations[]tool.name if set
  • policyOutcomepermitted / denied / escalated if recognized
  • idempotencyKey — 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.

PII sanitizer

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;
  },
});

Framework tagger

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 [];
  },
});

Configuration reference

OptionDefaultDescription
apiUrl(required)Full URL of the bulk ingest endpoint
apiKey(required)API key with write:assessments permission
systemId(required)Attestry system UUID
batchSize20Flush trigger — records per batch
batchInterval5000msFlush trigger — max delay before partial flush
fetchTimeoutMs10_000Per-request abort timeout
sanitizerregex stripperOverride PII sanitization
frameworkTaggerheuristic mappingOverride claim generation
shouldRecordAsDecisionheuristicOverride decision detection
loggerconsole (stderr)Wire pino/winston/etc. via warn/error

Failure mode

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.

Integration examples

LangChain

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

LlamaIndex's OpenInference instrumentation tags spans with openinference.span.kind. The default decider catches them via the ai.operation / gen_ai.operation.name keys.

OpenAI / Anthropic SDK

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();
});

License

Apache-2.0

FAQs

Package last updated on 06 Jun 2026

Did you know?

Socket

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.

Install

Related posts