first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
# crypto-vault — OpenTelemetry instruments
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`instruments.ts` holds the full OTel instrument set emitted by
`@suaveplan/crypto-vault` production paths. The module exposes a lazy
singleton that defers `metrics.getMeter(...)` until first use, so loading
the package does nothing observable when no exporter is wired up. Every
instrument is safe-by-construction — no key bytes, salts, plaintext, or
user-identifiable data appears in attributes.
## Features
- Lazy `getCryptoVaultInstruments()` accessor — first call materialises the
instrument set against the global meter; subsequent calls hit the cached
set.
- `setCryptoVaultMeterProvider(provider)` lets tests register a deterministic
in-memory `MeterProvider` and then assert against captured observations.
- `resetCryptoVaultInstruments()` clears the cache so tests can re-run with a
fresh provider without leaking state.
- Counters and histograms covering Argon2id derivations, HKDF derivations,
zeroization, SecureBuffer allocations / zeroizations, and the SRP-6a
handshake.
## Usage: Basic Example
```ts
import { getCryptoVaultInstruments } from "@suaveplan/crypto-vault/otel";
const i = getCryptoVaultInstruments();
i.argon2idDurationMs.record(143.2);
i.secureBufferAllocateTotal.add(1, { length: "32" });
```
## Usage: Advanced Example
```ts
import {
getCryptoVaultInstruments,
resetCryptoVaultInstruments,
setCryptoVaultMeterProvider,
} from "@suaveplan/crypto-vault/otel";
class CountingMeter {
public readonly events: Array<[string, number]> = [];
public createHistogram = (name: string) => ({
record: (v: number) => this.events.push([`hist:${name}`, v]),
});
public createCounter = (name: string) => ({
add: (v: number) => this.events.push([`ctr:${name}`, v]),
});
}
const meter = new CountingMeter();
setCryptoVaultMeterProvider({ getMeter: () => meter as unknown as never });
getCryptoVaultInstruments().secureBufferZeroizeTotal.add(1);
console.log(meter.events); // [["ctr:crypto_vault.secure_buffer.zeroize.total", 1]]
setCryptoVaultMeterProvider(undefined);
resetCryptoVaultInstruments();
```
## API Reference
### `getCryptoVaultInstruments(): CryptoVaultInstruments`
Returns the cached instrument set, building it on first call against the
global OTel meter.
### `setCryptoVaultMeterProvider(provider?)`
Replace the meter provider used by subsequent
`getCryptoVaultInstruments()` calls. Pass `undefined` to revert to the
global default.
### `resetCryptoVaultInstruments(): void`
Clear the cache so the next `getCryptoVaultInstruments()` re-acquires the
meter. Tests use this to defeat singleton leakage between suites.
### `CryptoVaultInstruments`
Bag of `Counter` and `Histogram` instances. Field names map to the metric
names listed under "Features".
## Implementation Notes
- The cache is intentionally module-level — production code should not need
per-instance instrument sets. Tests that want isolation register a
provider, run their assertions, then reset.
- Metric names follow the OTel semantic-conventions style:
`<package>.<feature>.<dimension>_<unit>`.
- The package never adds key material, vault IDs, item IDs, salts, or email
addresses to instrument attributes. The only attributes used are
fixed-cardinality status / outcome strings.