@centient/secrets 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +355 -7
  2. package/dist/audit/hmac-chain.d.ts +117 -0
  3. package/dist/audit/hmac-chain.d.ts.map +1 -0
  4. package/dist/audit/hmac-chain.js +811 -0
  5. package/dist/audit/hmac-chain.js.map +1 -0
  6. package/dist/audit/ocsf.d.ts +108 -0
  7. package/dist/audit/ocsf.d.ts.map +1 -0
  8. package/dist/audit/ocsf.js +204 -0
  9. package/dist/audit/ocsf.js.map +1 -0
  10. package/dist/cli/hidden-prompt.d.ts.map +1 -1
  11. package/dist/cli/hidden-prompt.js +55 -10
  12. package/dist/cli/hidden-prompt.js.map +1 -1
  13. package/dist/cli/messages.d.ts +40 -8
  14. package/dist/cli/messages.d.ts.map +1 -1
  15. package/dist/cli/messages.js +34 -8
  16. package/dist/cli/messages.js.map +1 -1
  17. package/dist/client.d.ts +26 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +129 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/compatibility.d.ts +199 -0
  22. package/dist/compatibility.d.ts.map +1 -0
  23. package/dist/compatibility.js +419 -0
  24. package/dist/compatibility.js.map +1 -0
  25. package/dist/index.d.ts +19 -5
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +16 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/policies/audit-trail.d.ts +25 -0
  30. package/dist/policies/audit-trail.d.ts.map +1 -0
  31. package/dist/policies/audit-trail.js +31 -0
  32. package/dist/policies/audit-trail.js.map +1 -0
  33. package/dist/sinks/index.d.ts +9 -0
  34. package/dist/sinks/index.d.ts.map +1 -0
  35. package/dist/sinks/index.js +5 -0
  36. package/dist/sinks/index.js.map +1 -0
  37. package/dist/sinks/jsonl.d.ts +16 -0
  38. package/dist/sinks/jsonl.d.ts.map +1 -0
  39. package/dist/sinks/jsonl.js +51 -0
  40. package/dist/sinks/jsonl.js.map +1 -0
  41. package/dist/sinks/otel.d.ts +22 -0
  42. package/dist/sinks/otel.d.ts.map +1 -0
  43. package/dist/sinks/otel.js +155 -0
  44. package/dist/sinks/otel.js.map +1 -0
  45. package/dist/sinks/queue.d.ts +12 -0
  46. package/dist/sinks/queue.d.ts.map +1 -0
  47. package/dist/sinks/queue.js +89 -0
  48. package/dist/sinks/queue.js.map +1 -0
  49. package/dist/sinks/syslog.d.ts +17 -0
  50. package/dist/sinks/syslog.d.ts.map +1 -0
  51. package/dist/sinks/syslog.js +103 -0
  52. package/dist/sinks/syslog.js.map +1 -0
  53. package/dist/sinks/types.d.ts +27 -0
  54. package/dist/sinks/types.d.ts.map +1 -0
  55. package/dist/sinks/types.js +18 -0
  56. package/dist/sinks/types.js.map +1 -0
  57. package/dist/vault/policy.d.ts +64 -34
  58. package/dist/vault/policy.d.ts.map +1 -1
  59. package/dist/vault/policy.js +109 -67
  60. package/dist/vault/policy.js.map +1 -1
  61. package/dist/vault/session-vault.d.ts +43 -0
  62. package/dist/vault/session-vault.d.ts.map +1 -1
  63. package/dist/vault/session-vault.js +323 -36
  64. package/dist/vault/session-vault.js.map +1 -1
  65. package/dist/vault/sidecar.d.ts +9 -0
  66. package/dist/vault/sidecar.d.ts.map +1 -1
  67. package/dist/vault/sidecar.js +72 -3
  68. package/dist/vault/sidecar.js.map +1 -1
  69. package/dist/vault/types.d.ts +16 -9
  70. package/dist/vault/types.d.ts.map +1 -1
  71. package/dist/vault/vault-env.d.ts +41 -62
  72. package/dist/vault/vault-env.d.ts.map +1 -1
  73. package/dist/vault/vault-env.js +139 -75
  74. package/dist/vault/vault-env.js.map +1 -1
  75. package/dist/vault/vault-gpg.d.ts +1 -0
  76. package/dist/vault/vault-gpg.d.ts.map +1 -1
  77. package/dist/vault/vault-gpg.js +1 -0
  78. package/dist/vault/vault-gpg.js.map +1 -1
  79. package/dist/vault/vault-libsecret.d.ts +1 -0
  80. package/dist/vault/vault-libsecret.d.ts.map +1 -1
  81. package/dist/vault/vault-libsecret.js +7 -6
  82. package/dist/vault/vault-libsecret.js.map +1 -1
  83. package/dist/vault/vault-onepassword.d.ts +1 -0
  84. package/dist/vault/vault-onepassword.d.ts.map +1 -1
  85. package/dist/vault/vault-onepassword.js +1 -0
  86. package/dist/vault/vault-onepassword.js.map +1 -1
  87. package/dist/vault/vault-utils.d.ts +7 -6
  88. package/dist/vault/vault-utils.d.ts.map +1 -1
  89. package/dist/vault/vault-utils.js +8 -7
  90. package/dist/vault/vault-utils.js.map +1 -1
  91. package/dist/vault/vault-windows.d.ts +2 -1
  92. package/dist/vault/vault-windows.d.ts.map +1 -1
  93. package/dist/vault/vault-windows.js +12 -8
  94. package/dist/vault/vault-windows.js.map +1 -1
  95. package/dist/vault/vault.d.ts +6 -7
  96. package/dist/vault/vault.d.ts.map +1 -1
  97. package/dist/vault/vault.js +37 -193
  98. package/dist/vault/vault.js.map +1 -1
  99. package/package.json +8 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sinks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EACV,SAAS,EACT,qBAAqB,EACrB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { jsonlAuditSink } from "./jsonl.js";
2
+ export { credentialAuditSpanAttributes, otelAuditSink, OtelAuditSinkDegradedError, } from "./otel.js";
3
+ export { syslogAuditSink } from "./syslog.js";
4
+ export { AuditSinkOverflowError } from "./types.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sinks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { AuditSink, AuditSinkErrorHandler } from "./types.js";
2
+ export interface JsonlAuditSinkOptions {
3
+ readonly filePath: string;
4
+ /** Creation mode for a new log file. Defaults to owner-only `0o600`. */
5
+ readonly fileMode?: number;
6
+ /** Creation mode for missing directories. Defaults to owner-only `0o700`. */
7
+ readonly directoryMode?: number;
8
+ readonly maxPending?: number;
9
+ readonly onError?: AuditSinkErrorHandler;
10
+ }
11
+ /**
12
+ * Append bare OCSF records as newline-delimited JSON. Writes are serialized in
13
+ * emission order; `flush()` rejects if any queued append failed.
14
+ */
15
+ export declare function jsonlAuditSink(options: JsonlAuditSinkOptions): AuditSink;
16
+ //# sourceMappingURL=jsonl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../src/sinks/jsonl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAQD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,SAAS,CAuCxE"}
@@ -0,0 +1,51 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ import { createQueuedAuditSink } from "./queue.js";
4
+ function assertMode(mode, field) {
5
+ if (!Number.isInteger(mode) || mode < 0 || mode > 0o777) {
6
+ throw new RangeError(`${field} must be an integer permission mode from 0o000 to 0o777`);
7
+ }
8
+ }
9
+ /**
10
+ * Append bare OCSF records as newline-delimited JSON. Writes are serialized in
11
+ * emission order; `flush()` rejects if any queued append failed.
12
+ */
13
+ export function jsonlAuditSink(options) {
14
+ if (options.filePath.length === 0) {
15
+ throw new TypeError("filePath must not be empty");
16
+ }
17
+ const fileMode = options.fileMode ?? 0o600;
18
+ const directoryMode = options.directoryMode ?? 0o700;
19
+ assertMode(fileMode, "fileMode");
20
+ assertMode(directoryMode, "directoryMode");
21
+ let directoryReady = false;
22
+ return createQueuedAuditSink({
23
+ name: "jsonl",
24
+ ...(options.maxPending !== undefined ? { maxPending: options.maxPending } : {}),
25
+ ...(options.onError !== undefined ? { onError: options.onError } : {}),
26
+ async write(event) {
27
+ if (!directoryReady) {
28
+ await mkdir(dirname(options.filePath), {
29
+ recursive: true,
30
+ mode: directoryMode,
31
+ });
32
+ directoryReady = true;
33
+ }
34
+ try {
35
+ await appendFile(options.filePath, `${JSON.stringify(event)}\n`, {
36
+ encoding: "utf8",
37
+ mode: fileMode,
38
+ });
39
+ }
40
+ catch (error) {
41
+ if (error instanceof Error &&
42
+ "code" in error &&
43
+ error.code === "ENOENT") {
44
+ directoryReady = false;
45
+ }
46
+ throw error;
47
+ }
48
+ },
49
+ });
50
+ }
51
+ //# sourceMappingURL=jsonl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/sinks/jsonl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAYnD,SAAS,UAAU,CAAC,IAAY,EAAE,KAAa;IAC7C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,yDAAyD,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC;IACrD,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACjC,UAAU,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;IAE3C,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,OAAO,qBAAqB,CAAC;QAC3B,IAAI,EAAE,OAAO;QACb,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,KAAK,CAAC,KAAK,CAAC,KAAK;YACf,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;oBACrC,SAAS,EAAE,IAAI;oBACf,IAAI,EAAE,aAAa;iBACpB,CAAC,CAAC;gBACH,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE;oBAC/D,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,QAAQ;iBACf,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IACE,KAAK,YAAY,KAAK;oBACtB,MAAM,IAAI,KAAK;oBACd,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAClD,CAAC;oBACD,cAAc,GAAG,KAAK,CAAC;gBACzB,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type Attributes, type Tracer } from "@opentelemetry/api";
2
+ import type { CredentialAuditEvent } from "../audit/ocsf.js";
3
+ import { type AuditSink, type AuditSinkErrorHandler } from "./types.js";
4
+ export declare class OtelAuditSinkDegradedError extends Error {
5
+ readonly code: "OTEL_AUDIT_SINK_DEGRADED";
6
+ constructor(reason: "not-recording" | "not-sampled");
7
+ }
8
+ export interface OtelAuditSinkOptions {
9
+ /** Application-owned tracer; defaults to the global OTel API tracer. */
10
+ readonly tracer?: Tracer;
11
+ /** Called once when spans are not recording/sampled, and on synchronous errors. */
12
+ readonly onError?: AuditSinkErrorHandler;
13
+ }
14
+ /** Flatten one OCSF JSON record into primitive span attributes. */
15
+ export declare function credentialAuditSpanAttributes(event: CredentialAuditEvent): Attributes;
16
+ /**
17
+ * Emit one completed credential operation as a retroactive OTel span. The
18
+ * application owns SDK/exporter configuration; this package depends only on
19
+ * the OTel API, as required for reusable instrumentation libraries.
20
+ */
21
+ export declare function otelAuditSink(options?: OtelAuditSinkOptions): AuditSink;
22
+ //# sourceMappingURL=otel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../src/sinks/otel.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,qBAAqB,EAE3B,MAAM,YAAY,CAAC;AAKpB,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,EAAG,0BAA0B,CAAU;gBAExC,MAAM,EAAE,eAAe,GAAG,aAAa;CAQpD;AAED,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED,mEAAmE;AACnE,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,oBAAoB,GAC1B,UAAU,CA6DZ;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,SAAS,CA0E3E"}
@@ -0,0 +1,155 @@
1
+ import { SpanKind, SpanStatusCode, TraceFlags, trace, } from "@opentelemetry/api";
2
+ import { asError, defaultAuditSinkErrorHandler, } from "./types.js";
3
+ const TRACER_NAME = "@centient/secrets";
4
+ const SPAN_NAME = "centient.secrets.credential";
5
+ export class OtelAuditSinkDegradedError extends Error {
6
+ code = "OTEL_AUDIT_SINK_DEGRADED";
7
+ constructor(reason) {
8
+ super(reason === "not-recording"
9
+ ? "OpenTelemetry audit span is not recording; configure an audit tracer provider"
10
+ : "OpenTelemetry audit span is not sampled; configure an always-on audit sampler");
11
+ this.name = "OtelAuditSinkDegradedError";
12
+ }
13
+ }
14
+ /** Flatten one OCSF JSON record into primitive span attributes. */
15
+ export function credentialAuditSpanAttributes(event) {
16
+ const attestation = event.attestation_list?.[0];
17
+ const previousHash = attestation?.prev_event?.fingerprint.value;
18
+ const durationMs = event.unmapped["centient.secrets.operation.duration_ms"];
19
+ return {
20
+ "ocsf.category_uid": event.category_uid,
21
+ "ocsf.class_uid": event.class_uid,
22
+ "ocsf.type_uid": event.type_uid,
23
+ "ocsf.activity_id": event.activity_id,
24
+ "ocsf.activity_name": event.activity_name,
25
+ "ocsf.action_id": event.action_id,
26
+ "ocsf.status_id": event.status_id,
27
+ "ocsf.severity_id": event.severity_id,
28
+ "ocsf.time": event.time,
29
+ "ocsf.metadata.version": event.metadata.version,
30
+ "ocsf.metadata.uid": event.metadata.uid,
31
+ "ocsf.actor.user.uid": event.actor.user.uid,
32
+ "ocsf.entity.name": event.entity.name,
33
+ "ocsf.entity.type": event.entity.type,
34
+ "ocsf.entity.type_id": event.entity.type_id,
35
+ "centient.secrets.credential.vault.name": event.entity.data.vault_name,
36
+ "centient.secrets.operation.duration_ms": durationMs,
37
+ "centient.secrets.event_type": event.unmapped["centient.secrets.event_type"],
38
+ // ADR-002's original attribute spellings are retained as projection
39
+ // aliases. They are not fields in released OCSF 1.9 JSON.
40
+ activity_id: event.activity_id,
41
+ "actor.user": event.actor.user.uid,
42
+ "credential.name": event.entity.name,
43
+ "credential.vault.name": event.entity.data.vault_name,
44
+ status_id: event.status_id,
45
+ time: event.time,
46
+ duration: durationMs,
47
+ ...(event.status_detail !== undefined
48
+ ? { "ocsf.status_detail": event.status_detail }
49
+ : {}),
50
+ ...(event.metadata.sequence !== undefined
51
+ ? {
52
+ "ocsf.metadata.sequence": event.metadata.sequence,
53
+ sequence_number: event.metadata.sequence,
54
+ }
55
+ : {}),
56
+ ...(attestation !== undefined
57
+ ? {
58
+ "ocsf.attestation.chain_uid": attestation.chain_uid,
59
+ "ocsf.attestation.fingerprint": attestation.fingerprint.value,
60
+ event_hash: attestation.fingerprint.value,
61
+ }
62
+ : {}),
63
+ ...(previousHash !== undefined
64
+ ? {
65
+ "ocsf.attestation.prev_event.fingerprint": previousHash,
66
+ previous_hash: previousHash,
67
+ }
68
+ : {}),
69
+ ...(event.unmapped["centient.audit_chain.key_id"] !== undefined
70
+ ? {
71
+ "centient.audit_chain.key_id": event.unmapped["centient.audit_chain.key_id"],
72
+ }
73
+ : {}),
74
+ };
75
+ }
76
+ /**
77
+ * Emit one completed credential operation as a retroactive OTel span. The
78
+ * application owns SDK/exporter configuration; this package depends only on
79
+ * the OTel API, as required for reusable instrumentation libraries.
80
+ */
81
+ export function otelAuditSink(options = {}) {
82
+ const tracer = options.tracer ?? trace.getTracer(TRACER_NAME);
83
+ const onError = options.onError ?? defaultAuditSinkErrorHandler;
84
+ let degraded;
85
+ let failures = 0;
86
+ let degradationReported = false;
87
+ const report = (error, once = false) => {
88
+ degraded = error;
89
+ failures += 1;
90
+ if (once && degradationReported)
91
+ return;
92
+ if (once)
93
+ degradationReported = true;
94
+ try {
95
+ onError(error);
96
+ }
97
+ catch (handlerError) {
98
+ defaultAuditSinkErrorHandler(asError(handlerError));
99
+ }
100
+ };
101
+ const sink = ((event) => {
102
+ let span;
103
+ try {
104
+ span = tracer.startSpan(SPAN_NAME, {
105
+ kind: SpanKind.INTERNAL,
106
+ startTime: event.time,
107
+ attributes: credentialAuditSpanAttributes(event),
108
+ });
109
+ }
110
+ catch (error) {
111
+ const normalized = asError(error);
112
+ report(normalized);
113
+ throw normalized;
114
+ }
115
+ let operationError;
116
+ try {
117
+ if (!span.isRecording()) {
118
+ report(new OtelAuditSinkDegradedError("not-recording"), true);
119
+ }
120
+ else if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
121
+ report(new OtelAuditSinkDegradedError("not-sampled"), true);
122
+ }
123
+ span.setStatus({
124
+ code: event.status_id === 1 ? SpanStatusCode.OK : SpanStatusCode.ERROR,
125
+ ...(event.status_detail !== undefined ? { message: event.status_detail } : {}),
126
+ });
127
+ }
128
+ catch (error) {
129
+ operationError = asError(error);
130
+ report(operationError);
131
+ }
132
+ try {
133
+ // A started span must be ended even when its recording/status methods
134
+ // throw through an injected tracer seam.
135
+ span.end(event.time + event.unmapped["centient.secrets.operation.duration_ms"]);
136
+ }
137
+ catch (error) {
138
+ const endError = asError(error);
139
+ report(endError);
140
+ operationError = operationError === undefined
141
+ ? endError
142
+ : new AggregateError([operationError, endError], "OpenTelemetry audit span processing and end both failed");
143
+ }
144
+ if (operationError !== undefined)
145
+ throw operationError;
146
+ });
147
+ sink.health = () => ({
148
+ status: degraded === undefined ? "healthy" : "degraded",
149
+ pending: 0,
150
+ failures,
151
+ ...(degraded !== undefined ? { lastError: degraded.message } : {}),
152
+ });
153
+ return sink;
154
+ }
155
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/sinks/otel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { CredentialAuditEvent } from "../audit/ocsf.js";
2
+ import { type AuditSink, type AuditSinkErrorHandler } from "./types.js";
3
+ export interface QueuedAuditSinkOptions {
4
+ readonly name: string;
5
+ readonly write: (event: CredentialAuditEvent) => void | Promise<void>;
6
+ readonly close?: () => void | Promise<void>;
7
+ readonly maxPending?: number;
8
+ readonly onError?: AuditSinkErrorHandler;
9
+ }
10
+ /** Internal serialized queue shared by the JSONL and syslog transports. */
11
+ export declare function createQueuedAuditSink(options: QueuedAuditSinkOptions): AuditSink;
12
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/sinks/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,qBAAqB,EAE3B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAID,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAgGhF"}
@@ -0,0 +1,89 @@
1
+ import { asError, AuditSinkOverflowError, defaultAuditSinkErrorHandler, } from "./types.js";
2
+ const DEFAULT_MAX_PENDING = 1_000;
3
+ /** Internal serialized queue shared by the JSONL and syslog transports. */
4
+ export function createQueuedAuditSink(options) {
5
+ const maxPending = options.maxPending ?? DEFAULT_MAX_PENDING;
6
+ if (!Number.isSafeInteger(maxPending) || maxPending < 1) {
7
+ throw new RangeError("maxPending must be a positive safe integer");
8
+ }
9
+ const onError = options.onError ?? defaultAuditSinkErrorHandler;
10
+ let tail = Promise.resolve();
11
+ let pending = 0;
12
+ let failures = 0;
13
+ let lastError;
14
+ let closed = false;
15
+ let closePromise;
16
+ const recordFailure = (error) => {
17
+ const normalized = asError(error);
18
+ failures += 1;
19
+ lastError = normalized;
20
+ try {
21
+ onError(normalized);
22
+ }
23
+ catch (handlerError) {
24
+ // An error reporter must not turn a handled queue rejection into an
25
+ // unhandled rejection. The fallback is deliberately value-free.
26
+ defaultAuditSinkErrorHandler(asError(handlerError));
27
+ }
28
+ };
29
+ const sink = ((event) => {
30
+ if (closed) {
31
+ throw new Error(`${options.name} audit sink is closed`);
32
+ }
33
+ if (pending >= maxPending) {
34
+ const error = new AuditSinkOverflowError(options.name, maxPending);
35
+ recordFailure(error);
36
+ throw error;
37
+ }
38
+ pending += 1;
39
+ const writeResult = tail.then(() => options.write(event));
40
+ tail = writeResult.then(() => {
41
+ pending -= 1;
42
+ }, (error) => {
43
+ pending -= 1;
44
+ recordFailure(error);
45
+ });
46
+ });
47
+ sink.flush = async () => {
48
+ await tail;
49
+ if (failures > 0) {
50
+ throw new AggregateError(lastError === undefined ? [] : [lastError], `${options.name} audit sink failed to write ${failures} record(s)`);
51
+ }
52
+ };
53
+ sink.close = () => {
54
+ if (closePromise !== undefined)
55
+ return closePromise;
56
+ closed = true;
57
+ closePromise = (async () => {
58
+ const closeErrors = [];
59
+ try {
60
+ await sink.flush?.();
61
+ }
62
+ catch (error) {
63
+ closeErrors.push(asError(error));
64
+ }
65
+ try {
66
+ await options.close?.();
67
+ }
68
+ catch (error) {
69
+ const normalized = asError(error);
70
+ recordFailure(normalized);
71
+ closeErrors.push(normalized);
72
+ }
73
+ if (closeErrors.length === 1)
74
+ throw closeErrors[0];
75
+ if (closeErrors.length > 1) {
76
+ throw new AggregateError(closeErrors, `${options.name} audit sink drain and transport close both failed`);
77
+ }
78
+ })();
79
+ return closePromise;
80
+ };
81
+ sink.health = () => ({
82
+ status: failures === 0 ? "healthy" : "degraded",
83
+ pending,
84
+ failures,
85
+ ...(lastError !== undefined ? { lastError: lastError.message } : {}),
86
+ });
87
+ return sink;
88
+ }
89
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/sinks/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type AuditSink, type AuditSinkErrorHandler } from "./types.js";
2
+ export type SyslogAuditSender = (message: string) => void | Promise<void>;
3
+ export interface SyslogAuditSinkOptions {
4
+ readonly host?: string;
5
+ readonly port?: number;
6
+ /** RFC 5424 facility number. Defaults to 10 (`authpriv`). */
7
+ readonly facility?: number;
8
+ readonly hostname?: string;
9
+ readonly appName?: string;
10
+ readonly maxPending?: number;
11
+ readonly onError?: AuditSinkErrorHandler;
12
+ /** Injectable transport seam. When omitted, UDP is used. */
13
+ readonly sender?: SyslogAuditSender;
14
+ }
15
+ /** Create an RFC 5424 syslog sink, using UDP unless a sender is injected. */
16
+ export declare function syslogAuditSink(options?: SyslogAuditSinkOptions): AuditSink;
17
+ //# sourceMappingURL=syslog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syslog.d.ts","sourceRoot":"","sources":["../../src/sinks/syslog.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IACzC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CACrC;AA2ED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,SAAS,CA8B/E"}
@@ -0,0 +1,103 @@
1
+ import { createSocket } from "node:dgram";
2
+ import { hostname as getHostname } from "node:os";
3
+ import { createQueuedAuditSink } from "./queue.js";
4
+ import { asError, defaultAuditSinkErrorHandler, } from "./types.js";
5
+ function headerToken(value, fallback) {
6
+ const sanitized = value.replace(/[^\x21-\x7e]/g, "_").slice(0, 48);
7
+ return sanitized.length === 0 ? fallback : sanitized;
8
+ }
9
+ function syslogMessage(event, options) {
10
+ // RFC 5424: informational for a successful operation, warning otherwise.
11
+ const severity = event.status_id === 1 ? 6 : 4;
12
+ const priority = options.facility * 8 + severity;
13
+ const timestamp = new Date(event.time).toISOString();
14
+ const host = headerToken(options.hostname, "-");
15
+ const appName = headerToken(options.appName, "centient-secrets");
16
+ return `<${priority}>1 ${timestamp} ${host} ${appName} ${process.pid} OCSF3004 - ${JSON.stringify(event)}`;
17
+ }
18
+ function createUdpSender(host, port, onError) {
19
+ const socket = createSocket(host.includes(":") ? "udp6" : "udp4");
20
+ let sendInFlight = false;
21
+ let started = false;
22
+ socket.unref();
23
+ // Keep socket-level failures observable even if they occur outside a send
24
+ // callback. A per-send listener below also rejects the queued write.
25
+ socket.on("error", (error) => {
26
+ if (sendInFlight)
27
+ return;
28
+ try {
29
+ onError(error);
30
+ }
31
+ catch (handlerError) {
32
+ defaultAuditSinkErrorHandler(asError(handlerError));
33
+ }
34
+ });
35
+ return {
36
+ send(message) {
37
+ return new Promise((resolve, reject) => {
38
+ sendInFlight = true;
39
+ const onSocketError = (error) => {
40
+ socket.off("error", onSocketError);
41
+ sendInFlight = false;
42
+ reject(error);
43
+ };
44
+ socket.once("error", onSocketError);
45
+ try {
46
+ started = true;
47
+ socket.send(message, port, host, (error) => {
48
+ socket.off("error", onSocketError);
49
+ sendInFlight = false;
50
+ if (error)
51
+ reject(error);
52
+ else
53
+ resolve();
54
+ });
55
+ }
56
+ catch (error) {
57
+ socket.off("error", onSocketError);
58
+ sendInFlight = false;
59
+ started = false;
60
+ reject(error);
61
+ }
62
+ });
63
+ },
64
+ close() {
65
+ if (!started)
66
+ return Promise.resolve();
67
+ return new Promise((resolve) => {
68
+ socket.close(() => resolve());
69
+ });
70
+ },
71
+ };
72
+ }
73
+ /** Create an RFC 5424 syslog sink, using UDP unless a sender is injected. */
74
+ export function syslogAuditSink(options = {}) {
75
+ const host = options.host ?? "127.0.0.1";
76
+ const port = options.port ?? 514;
77
+ const facility = options.facility ?? 10;
78
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
79
+ throw new RangeError("syslog port must be an integer from 1 through 65535");
80
+ }
81
+ if (!Number.isInteger(facility) || facility < 0 || facility > 23) {
82
+ throw new RangeError("syslog facility must be an integer from 0 through 23");
83
+ }
84
+ const onError = options.onError ?? defaultAuditSinkErrorHandler;
85
+ const udp = options.sender === undefined
86
+ ? createUdpSender(host, port, onError)
87
+ : undefined;
88
+ const sender = options.sender ?? udp.send;
89
+ return createQueuedAuditSink({
90
+ name: "syslog",
91
+ ...(options.maxPending !== undefined ? { maxPending: options.maxPending } : {}),
92
+ onError,
93
+ write(event) {
94
+ return sender(syslogMessage(event, {
95
+ facility,
96
+ hostname: options.hostname ?? getHostname(),
97
+ appName: options.appName ?? "centient-secrets",
98
+ }));
99
+ },
100
+ ...(udp !== undefined ? { close: udp.close } : {}),
101
+ });
102
+ }
103
+ //# sourceMappingURL=syslog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syslog.js","sourceRoot":"","sources":["../../src/sinks/syslog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { CredentialAuditEvent } from "../audit/ocsf.js";
2
+ export interface AuditSinkHealth {
3
+ readonly status: "healthy" | "degraded";
4
+ readonly pending: number;
5
+ readonly failures: number;
6
+ readonly lastError?: string;
7
+ }
8
+ /**
9
+ * Synchronous policy boundary. Buffered sinks enqueue before returning and
10
+ * expose `flush()` so delivery-sensitive callers can observe async failure.
11
+ */
12
+ export interface AuditSink {
13
+ (event: CredentialAuditEvent): void;
14
+ flush?(): Promise<void>;
15
+ close?(): Promise<void>;
16
+ health?(): AuditSinkHealth;
17
+ }
18
+ export type AuditSinkErrorHandler = (error: Error) => void;
19
+ export declare class AuditSinkOverflowError extends Error {
20
+ readonly sink: string;
21
+ readonly maxPending: number;
22
+ readonly code: "AUDIT_SINK_OVERFLOW";
23
+ constructor(sink: string, maxPending: number);
24
+ }
25
+ export declare function asError(error: unknown): Error;
26
+ export declare function defaultAuditSinkErrorHandler(error: Error): void;
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sinks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,MAAM,CAAC,IAAI,eAAe,CAAC;CAC5B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAE3D,qBAAa,sBAAuB,SAAQ,KAAK;IAI7C,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM;IAJ7B,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBAGpC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM;CAK9B;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAE7C;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,18 @@
1
+ export class AuditSinkOverflowError extends Error {
2
+ sink;
3
+ maxPending;
4
+ code = "AUDIT_SINK_OVERFLOW";
5
+ constructor(sink, maxPending) {
6
+ super(`${sink} audit sink queue reached its ${maxPending}-record limit`);
7
+ this.sink = sink;
8
+ this.maxPending = maxPending;
9
+ this.name = "AuditSinkOverflowError";
10
+ }
11
+ }
12
+ export function asError(error) {
13
+ return error instanceof Error ? error : new Error(String(error));
14
+ }
15
+ export function defaultAuditSinkErrorHandler(error) {
16
+ process.stderr.write(`[secrets] audit sink failure: ${error.message}\n`);
17
+ }
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sinks/types.ts"],"names":[],"mappings":"AAsBA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAIpC;IACA;IAJF,IAAI,GAAG,qBAA8B,CAAC;IAE/C,YACW,IAAY,EACZ,UAAkB;QAE3B,KAAK,CAAC,GAAG,IAAI,iCAAiC,UAAU,eAAe,CAAC,CAAC;QAHhE,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAG3B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,KAAY;IACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAC3E,CAAC"}