@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.
- package/README.md +355 -7
- package/dist/audit/hmac-chain.d.ts +117 -0
- package/dist/audit/hmac-chain.d.ts.map +1 -0
- package/dist/audit/hmac-chain.js +811 -0
- package/dist/audit/hmac-chain.js.map +1 -0
- package/dist/audit/ocsf.d.ts +108 -0
- package/dist/audit/ocsf.d.ts.map +1 -0
- package/dist/audit/ocsf.js +204 -0
- package/dist/audit/ocsf.js.map +1 -0
- package/dist/cli/hidden-prompt.d.ts.map +1 -1
- package/dist/cli/hidden-prompt.js +55 -10
- package/dist/cli/hidden-prompt.js.map +1 -1
- package/dist/cli/messages.d.ts +40 -8
- package/dist/cli/messages.d.ts.map +1 -1
- package/dist/cli/messages.js +34 -8
- package/dist/cli/messages.js.map +1 -1
- package/dist/client.d.ts +26 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +129 -0
- package/dist/client.js.map +1 -0
- package/dist/compatibility.d.ts +199 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +419 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/index.d.ts +19 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/policies/audit-trail.d.ts +25 -0
- package/dist/policies/audit-trail.d.ts.map +1 -0
- package/dist/policies/audit-trail.js +31 -0
- package/dist/policies/audit-trail.js.map +1 -0
- package/dist/sinks/index.d.ts +9 -0
- package/dist/sinks/index.d.ts.map +1 -0
- package/dist/sinks/index.js +5 -0
- package/dist/sinks/index.js.map +1 -0
- package/dist/sinks/jsonl.d.ts +16 -0
- package/dist/sinks/jsonl.d.ts.map +1 -0
- package/dist/sinks/jsonl.js +51 -0
- package/dist/sinks/jsonl.js.map +1 -0
- package/dist/sinks/otel.d.ts +22 -0
- package/dist/sinks/otel.d.ts.map +1 -0
- package/dist/sinks/otel.js +155 -0
- package/dist/sinks/otel.js.map +1 -0
- package/dist/sinks/queue.d.ts +12 -0
- package/dist/sinks/queue.d.ts.map +1 -0
- package/dist/sinks/queue.js +89 -0
- package/dist/sinks/queue.js.map +1 -0
- package/dist/sinks/syslog.d.ts +17 -0
- package/dist/sinks/syslog.d.ts.map +1 -0
- package/dist/sinks/syslog.js +103 -0
- package/dist/sinks/syslog.js.map +1 -0
- package/dist/sinks/types.d.ts +27 -0
- package/dist/sinks/types.d.ts.map +1 -0
- package/dist/sinks/types.js +18 -0
- package/dist/sinks/types.js.map +1 -0
- package/dist/vault/policy.d.ts +64 -34
- package/dist/vault/policy.d.ts.map +1 -1
- package/dist/vault/policy.js +109 -67
- package/dist/vault/policy.js.map +1 -1
- package/dist/vault/session-vault.d.ts +43 -0
- package/dist/vault/session-vault.d.ts.map +1 -1
- package/dist/vault/session-vault.js +323 -36
- package/dist/vault/session-vault.js.map +1 -1
- package/dist/vault/sidecar.d.ts +9 -0
- package/dist/vault/sidecar.d.ts.map +1 -1
- package/dist/vault/sidecar.js +72 -3
- package/dist/vault/sidecar.js.map +1 -1
- package/dist/vault/types.d.ts +16 -9
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/vault-env.d.ts +41 -62
- package/dist/vault/vault-env.d.ts.map +1 -1
- package/dist/vault/vault-env.js +139 -75
- package/dist/vault/vault-env.js.map +1 -1
- package/dist/vault/vault-gpg.d.ts +1 -0
- package/dist/vault/vault-gpg.d.ts.map +1 -1
- package/dist/vault/vault-gpg.js +1 -0
- package/dist/vault/vault-gpg.js.map +1 -1
- package/dist/vault/vault-libsecret.d.ts +1 -0
- package/dist/vault/vault-libsecret.d.ts.map +1 -1
- package/dist/vault/vault-libsecret.js +7 -6
- package/dist/vault/vault-libsecret.js.map +1 -1
- package/dist/vault/vault-onepassword.d.ts +1 -0
- package/dist/vault/vault-onepassword.d.ts.map +1 -1
- package/dist/vault/vault-onepassword.js +1 -0
- package/dist/vault/vault-onepassword.js.map +1 -1
- package/dist/vault/vault-utils.d.ts +7 -6
- package/dist/vault/vault-utils.d.ts.map +1 -1
- package/dist/vault/vault-utils.js +8 -7
- package/dist/vault/vault-utils.js.map +1 -1
- package/dist/vault/vault-windows.d.ts +2 -1
- package/dist/vault/vault-windows.d.ts.map +1 -1
- package/dist/vault/vault-windows.js +12 -8
- package/dist/vault/vault-windows.js.map +1 -1
- package/dist/vault/vault.d.ts +6 -7
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +37 -193
- package/dist/vault/vault.js.map +1 -1
- 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"}
|