Files
skills/docs/security-stack/security/vault/src/otel/instruments.md
2026-05-29 08:20:56 +01:00

4.2 KiB

vault OTel instruments

(no submodules)

Purpose

instruments.ts is the single source of truth for OpenTelemetry instruments emitted by @suaveplan/vault. It exports a frozen VaultInstruments interface plus lazy-singleton accessors (getVaultInstruments, getVaultTracer) and test-only overrides (setVaultMeterProvider, setVaultTracerProvider, resetVaultInstruments, resetVaultTracer).

Every histogram, counter, and span is safe-by-construction: no password, no secret key, no AUK, no item content, no vault identifier, no item id, and no key material is permitted in any attribute. Only operation labels, status enums (status ∈ documented allowlist), durations in ms, and counts cross the OTel boundary. This guarantees that enabling vault telemetry can never leak vault contents into a tracing backend, even when the backend is misconfigured or compromised.

Features

  • unlockDurationMs / lockDurationMs / flushDurationMs — lifecycle latency histograms with no per-vault attributes.
  • itemOpDurationMs / attachmentOpDurationMs / shareOpDurationMs / syncOpDurationMs — operation latency histograms keyed by operation kind.
  • lifecycleOutcomeTotal / itemOutcomeTotal / attachmentOutcomeTotal / shareOutcomeTotal / syncOutcomeTotal — outcome counters with status allowlist enforced at the call site.
  • Lazy-singleton accessors so no OTel cost is paid until the first use.
  • set*Provider overrides for deterministic in-memory test providers; reset* to clear cached state between tests.

Usage: Basic Example

import { getVaultInstruments } from "@suaveplan/vault/otel/instruments";

const instruments = getVaultInstruments();
const start = Date.now();
await vault.unlock(password, secretKey);
instruments.unlockDurationMs.record(Date.now() - start);
instruments.lifecycleOutcomeTotal.add(1, { status: "unlocked" });

Usage: Advanced Example

import { metrics, type MeterProvider } from "@opentelemetry/api";
import {
    getVaultInstruments,
    resetVaultInstruments,
    setVaultMeterProvider,
} from "@suaveplan/vault/otel/instruments";

// Inject an in-memory test provider for assertion-driven tests.
const testProvider: MeterProvider = createInMemoryMeterProvider();
setVaultMeterProvider(testProvider);
try {
    const instruments = getVaultInstruments();
    instruments.itemOpDurationMs.record(12, { op: "create" });
    instruments.itemOutcomeTotal.add(1, { op: "create", status: "success" });
    // ... assert against testProvider's recorded data points ...
} finally {
    resetVaultInstruments();
    setVaultMeterProvider(undefined);
}

API Reference

  • interface VaultInstruments — frozen shape of the instrument set.
  • getVaultInstruments(): VaultInstruments — lazy accessor for the cached instrument set.
  • setVaultMeterProvider(provider: MeterProvider | undefined): void — override the meter provider for tests.
  • resetVaultInstruments(): void — drop the cached instrument set.
  • getVaultTracer(): Tracer — lazy accessor for the cached tracer.
  • setVaultTracerProvider(provider: TracerProvider | undefined): void — override the tracer provider for tests.
  • resetVaultTracer(): void — drop the cached tracer.

Implementation Notes

  • Histograms are recorded in milliseconds against the OTel unit: "ms" convention; consumers can configure histogram buckets globally via the SDK without per-instrument code.
  • Counters expose a documented status allowlist for each surface (lifecycle: opened | unlocked | locked | denied; items: success | not_found | conflict | rejected; attachments: success | not_found | rejected; shares: success | not_found | revoked | rejected; sync: success | failed | rejected). Call sites pass a string from this list — adding a new value requires an OpenSpec change.
  • Resetting a provider mid-process drops the cached singleton so subsequent getVaultInstruments() calls re-acquire from the new provider — used in test isolation only.
  • The global OTel API returns no-op instruments when no provider is registered; production code can call getVaultInstruments() unconditionally without performance impact when telemetry is disabled.