@centient/secrets 0.9.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 (152) hide show
  1. package/README.md +424 -8
  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/cli/secrets-cli.d.ts.map +1 -1
  18. package/dist/cli/secrets-cli.js +191 -32
  19. package/dist/cli/secrets-cli.js.map +1 -1
  20. package/dist/client.d.ts +26 -0
  21. package/dist/client.d.ts.map +1 -0
  22. package/dist/client.js +129 -0
  23. package/dist/client.js.map +1 -0
  24. package/dist/compatibility.d.ts +199 -0
  25. package/dist/compatibility.d.ts.map +1 -0
  26. package/dist/compatibility.js +419 -0
  27. package/dist/compatibility.js.map +1 -0
  28. package/dist/crypto/darwin-keychain.d.ts +394 -0
  29. package/dist/crypto/darwin-keychain.d.ts.map +1 -0
  30. package/dist/crypto/darwin-keychain.js +793 -0
  31. package/dist/crypto/darwin-keychain.js.map +1 -0
  32. package/dist/crypto/vault-common.d.ts +55 -12
  33. package/dist/crypto/vault-common.d.ts.map +1 -1
  34. package/dist/crypto/vault-common.js +74 -71
  35. package/dist/crypto/vault-common.js.map +1 -1
  36. package/dist/environment/EnvironmentManager.d.ts.map +1 -1
  37. package/dist/environment/EnvironmentManager.js +5 -10
  38. package/dist/environment/EnvironmentManager.js.map +1 -1
  39. package/dist/index.d.ts +37 -9
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +38 -6
  42. package/dist/index.js.map +1 -1
  43. package/dist/key-providers/keychain-provider.d.ts +30 -2
  44. package/dist/key-providers/keychain-provider.d.ts.map +1 -1
  45. package/dist/key-providers/keychain-provider.js +29 -5
  46. package/dist/key-providers/keychain-provider.js.map +1 -1
  47. package/dist/key-providers/onepassword-provider.d.ts +65 -5
  48. package/dist/key-providers/onepassword-provider.d.ts.map +1 -1
  49. package/dist/key-providers/onepassword-provider.js +159 -67
  50. package/dist/key-providers/onepassword-provider.js.map +1 -1
  51. package/dist/key-providers/op-cli.d.ts +78 -0
  52. package/dist/key-providers/op-cli.d.ts.map +1 -0
  53. package/dist/key-providers/op-cli.js +123 -0
  54. package/dist/key-providers/op-cli.js.map +1 -0
  55. package/dist/key-providers/passphrase-provider.d.ts +20 -0
  56. package/dist/key-providers/passphrase-provider.d.ts.map +1 -1
  57. package/dist/key-providers/passphrase-provider.js +49 -0
  58. package/dist/key-providers/passphrase-provider.js.map +1 -1
  59. package/dist/key-providers/probe.d.ts +46 -0
  60. package/dist/key-providers/probe.d.ts.map +1 -0
  61. package/dist/key-providers/probe.js +70 -0
  62. package/dist/key-providers/probe.js.map +1 -0
  63. package/dist/key-providers/types.d.ts +51 -1
  64. package/dist/key-providers/types.d.ts.map +1 -1
  65. package/dist/platform/agent-detect.d.ts +39 -3
  66. package/dist/platform/agent-detect.d.ts.map +1 -1
  67. package/dist/platform/agent-detect.js +55 -9
  68. package/dist/platform/agent-detect.js.map +1 -1
  69. package/dist/platform/session-context.d.ts +77 -0
  70. package/dist/platform/session-context.d.ts.map +1 -0
  71. package/dist/platform/session-context.js +83 -0
  72. package/dist/platform/session-context.js.map +1 -0
  73. package/dist/policies/audit-trail.d.ts +25 -0
  74. package/dist/policies/audit-trail.d.ts.map +1 -0
  75. package/dist/policies/audit-trail.js +31 -0
  76. package/dist/policies/audit-trail.js.map +1 -0
  77. package/dist/secret-state.d.ts +54 -0
  78. package/dist/secret-state.d.ts.map +1 -0
  79. package/dist/secret-state.js +2 -0
  80. package/dist/secret-state.js.map +1 -0
  81. package/dist/sinks/index.d.ts +9 -0
  82. package/dist/sinks/index.d.ts.map +1 -0
  83. package/dist/sinks/index.js +5 -0
  84. package/dist/sinks/index.js.map +1 -0
  85. package/dist/sinks/jsonl.d.ts +16 -0
  86. package/dist/sinks/jsonl.d.ts.map +1 -0
  87. package/dist/sinks/jsonl.js +51 -0
  88. package/dist/sinks/jsonl.js.map +1 -0
  89. package/dist/sinks/otel.d.ts +22 -0
  90. package/dist/sinks/otel.d.ts.map +1 -0
  91. package/dist/sinks/otel.js +155 -0
  92. package/dist/sinks/otel.js.map +1 -0
  93. package/dist/sinks/queue.d.ts +12 -0
  94. package/dist/sinks/queue.d.ts.map +1 -0
  95. package/dist/sinks/queue.js +89 -0
  96. package/dist/sinks/queue.js.map +1 -0
  97. package/dist/sinks/syslog.d.ts +17 -0
  98. package/dist/sinks/syslog.d.ts.map +1 -0
  99. package/dist/sinks/syslog.js +103 -0
  100. package/dist/sinks/syslog.js.map +1 -0
  101. package/dist/sinks/types.d.ts +27 -0
  102. package/dist/sinks/types.d.ts.map +1 -0
  103. package/dist/sinks/types.js +18 -0
  104. package/dist/sinks/types.js.map +1 -0
  105. package/dist/vault/policy.d.ts +64 -34
  106. package/dist/vault/policy.d.ts.map +1 -1
  107. package/dist/vault/policy.js +109 -67
  108. package/dist/vault/policy.js.map +1 -1
  109. package/dist/vault/session-vault-errors.d.ts +72 -4
  110. package/dist/vault/session-vault-errors.d.ts.map +1 -1
  111. package/dist/vault/session-vault-errors.js +95 -4
  112. package/dist/vault/session-vault-errors.js.map +1 -1
  113. package/dist/vault/session-vault.d.ts +145 -2
  114. package/dist/vault/session-vault.d.ts.map +1 -1
  115. package/dist/vault/session-vault.js +548 -72
  116. package/dist/vault/session-vault.js.map +1 -1
  117. package/dist/vault/sidecar.d.ts +9 -0
  118. package/dist/vault/sidecar.d.ts.map +1 -1
  119. package/dist/vault/sidecar.js +72 -3
  120. package/dist/vault/sidecar.js.map +1 -1
  121. package/dist/vault/types.d.ts +58 -10
  122. package/dist/vault/types.d.ts.map +1 -1
  123. package/dist/vault/types.js.map +1 -1
  124. package/dist/vault/vault-env.d.ts +43 -50
  125. package/dist/vault/vault-env.d.ts.map +1 -1
  126. package/dist/vault/vault-env.js +141 -62
  127. package/dist/vault/vault-env.js.map +1 -1
  128. package/dist/vault/vault-gpg.d.ts +6 -1
  129. package/dist/vault/vault-gpg.d.ts.map +1 -1
  130. package/dist/vault/vault-gpg.js +10 -8
  131. package/dist/vault/vault-gpg.js.map +1 -1
  132. package/dist/vault/vault-libsecret.d.ts +6 -1
  133. package/dist/vault/vault-libsecret.d.ts.map +1 -1
  134. package/dist/vault/vault-libsecret.js +16 -14
  135. package/dist/vault/vault-libsecret.js.map +1 -1
  136. package/dist/vault/vault-onepassword.d.ts +119 -0
  137. package/dist/vault/vault-onepassword.d.ts.map +1 -0
  138. package/dist/vault/vault-onepassword.js +271 -0
  139. package/dist/vault/vault-onepassword.js.map +1 -0
  140. package/dist/vault/vault-utils.d.ts +37 -3
  141. package/dist/vault/vault-utils.d.ts.map +1 -1
  142. package/dist/vault/vault-utils.js +65 -3
  143. package/dist/vault/vault-utils.js.map +1 -1
  144. package/dist/vault/vault-windows.d.ts +7 -2
  145. package/dist/vault/vault-windows.d.ts.map +1 -1
  146. package/dist/vault/vault-windows.js +21 -16
  147. package/dist/vault/vault-windows.js.map +1 -1
  148. package/dist/vault/vault.d.ts +120 -9
  149. package/dist/vault/vault.d.ts.map +1 -1
  150. package/dist/vault/vault.js +222 -139
  151. package/dist/vault/vault.js.map +1 -1
  152. package/package.json +8 -2
@@ -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"}
@@ -1,42 +1,50 @@
1
1
  /**
2
2
  * SecretsPolicy — Middleware layer for credential operations.
3
3
  *
4
- * Policies are cross-cutting concerns (audit, rate limiting, access
5
- * control, attestation) applied to every credential operation via
6
- * `setSecretsPolicies([...])`. In 0.5.0 only the audit policy is
7
- * shipped; the API shape is designed to grow into the full policy
8
- * stack described in ADR-002.
4
+ * Policies are cross-cutting concerns (audit, rate limiting, access control,
5
+ * attestation) applied to every credential operation. Explicit clients own an
6
+ * isolated stack supplied to `createSecretsClient`; `setSecretsPolicies`
7
+ * remains as the deprecated configuration path for the module-level shims and
8
+ * SessionVault. The API shape is designed for the full stack in ADR-002.
9
9
  *
10
10
  * Execution model:
11
11
  * 1. `before` hooks run top-to-bottom. If one throws, the operation
12
12
  * is aborted and the error propagates to the caller — but the
13
- * `after` hooks of already-entered policies (those whose `before`
14
- * hook already completed) still fire with a `*_rejected` event, so
13
+ * rejecting policy and already-entered policies still fire their
14
+ * `after` hooks with a `*_rejected` event, so
15
15
  * a policy-denied operation is audited rather than vanishing
16
- * (ADR-002 §1.0.0). The rejecting policy's own `after` hook does
17
- * not fire — its `before` hook did not complete.
16
+ * (issue #98). Policies not yet reached do not fire.
18
17
  * 2. The backend operation executes.
19
18
  * 3. `after` hooks run bottom-to-top with a structured event
20
19
  * describing the outcome. Exceptions in `after` hooks are
21
20
  * swallowed with a one-time stderr warning — audit infrastructure
22
21
  * failures must never break credential operations.
23
22
  */
24
- import type { VaultType } from "./types.js";
25
23
  export type SecretsEventType = "credential_read" | "credential_read_missing" | "credential_read_failed" | "credential_read_rejected" | "credential_written" | "credential_write_failed" | "credential_write_rejected" | "credential_deleted" | "credential_delete_failed" | "credential_delete_rejected" | "credential_enumerated" | "credential_enumerate_failed" | "credential_enumerate_rejected";
26
24
  export interface SecretsEvent {
27
- type: SecretsEventType;
28
- timestamp: string;
29
- backend: VaultType;
30
- key?: string;
31
- keyCount?: number;
32
- prefix?: string;
33
- error?: string;
34
- durationMs: number;
25
+ readonly type: SecretsEventType;
26
+ readonly timestamp: string;
27
+ readonly backend: string;
28
+ /** Full value-free operation descriptor supplied to policy hooks. */
29
+ readonly operation: SecretsOperation;
30
+ readonly key?: string;
31
+ readonly keyCount?: number;
32
+ readonly prefix?: string;
33
+ readonly error?: string;
34
+ readonly durationMs: number;
35
+ }
36
+ export interface SecretsCaller {
37
+ readonly id: string;
38
+ readonly kind?: string;
39
+ }
40
+ export interface SecretsOperationContext {
41
+ readonly caller?: SecretsCaller;
35
42
  }
36
43
  export interface SecretsOperation {
37
- type: "read" | "write" | "delete" | "enumerate";
38
- key?: string;
39
- prefix?: string;
44
+ readonly type: "read" | "write" | "delete" | "enumerate";
45
+ readonly key?: string;
46
+ readonly prefix?: string;
47
+ readonly caller?: SecretsCaller;
40
48
  }
41
49
  /**
42
50
  * The audit event type emitted when a `before` hook rejects an
@@ -46,6 +54,12 @@ export interface SecretsOperation {
46
54
  export declare function rejectedEventType(op: SecretsOperation): SecretsEventType;
47
55
  export interface SecretsPolicy {
48
56
  readonly name: string;
57
+ /**
58
+ * Set by policies whose contract includes observing every policy denial.
59
+ * Such a policy must appear before every `before` hook, because a preceding
60
+ * hook can reject before the observer is entered.
61
+ */
62
+ readonly observesPolicyRejections?: true;
49
63
  /** `before` hooks may be async; they are awaited before the operation runs. */
50
64
  before?(op: SecretsOperation): void | Promise<void>;
51
65
  /**
@@ -59,23 +73,39 @@ export interface SecretsPolicy {
59
73
  */
60
74
  after?(event: SecretsEvent): void;
61
75
  }
76
+ export type PolicyStackFrame = readonly SecretsPolicy[];
77
+ export interface PolicyRunner {
78
+ runBefore(op: SecretsOperation, makeRejectionEvent: (error: string) => SecretsEvent): Promise<PolicyStackFrame>;
79
+ runAfter(event: SecretsEvent, frame?: PolicyStackFrame): void;
80
+ getPolicies(): readonly SecretsPolicy[];
81
+ replacePolicies(policies: readonly SecretsPolicy[]): void;
82
+ }
83
+ /**
84
+ * Build an isolated policy runner. Its input is snapshotted immediately, and
85
+ * every operation captures the current immutable frame so replacement cannot
86
+ * splice two different stacks across an await boundary.
87
+ */
88
+ export declare function createPolicyRunner(initialPolicies?: readonly SecretsPolicy[]): PolicyRunner;
89
+ /** Global runner retained only for legacy module APIs and SessionVault. */
90
+ export declare const defaultPolicyRunner: PolicyRunner;
91
+ /**
92
+ * @deprecated Configure policies on an isolated client created with
93
+ * `createSecretsClient`. This setter remains for module-level shims and
94
+ * SessionVault compatibility through the 1.x deprecation window.
95
+ */
62
96
  export declare function setSecretsPolicies(policies: SecretsPolicy[]): void;
97
+ /** @deprecated Inspect the policy list owned by the legacy default client. */
63
98
  export declare function getActivePolicies(): readonly SecretsPolicy[];
64
99
  /**
65
100
  * Run `before` hooks top-to-bottom. If a hook throws, the operation is
66
- * rejected: the `after` hooks of the already-entered policies (indices
67
- * `0..i-1`, bottom-to-top) fire with the event built by
101
+ * rejected: the rejecting policy and already-entered policies (indices
102
+ * `0..i`, bottom-to-top) fire `after` with the event built by
68
103
  * `makeRejectionEvent` so the denied operation is still audited, then the
69
- * original error is re-thrown to abort the operation. The rejecting
70
- * policy's own `after` hook is intentionally skipped its `before` hook
71
- * did not complete, so the policy was not fully entered. See ADR-002
72
- * §1.0.0.
104
+ * original error is re-thrown to abort the operation. This follows issue
105
+ * #98's acceptance contract; policies after the rejector are never entered.
73
106
  */
74
- export declare function runBeforeHooks(op: SecretsOperation, makeRejectionEvent: (error: string) => SecretsEvent): Promise<void>;
75
- export declare function runAfterHooks(event: SecretsEvent): void;
76
- export interface AuditTrailOptions {
77
- sink: (event: SecretsEvent) => void;
78
- includeReads?: boolean;
79
- }
80
- export declare function auditTrail(opts: AuditTrailOptions): SecretsPolicy;
107
+ export declare function runBeforeHooks(op: SecretsOperation, makeRejectionEvent: (error: string) => SecretsEvent): Promise<PolicyStackFrame>;
108
+ export declare function runAfterHooks(event: SecretsEvent, frame?: PolicyStackFrame): void;
109
+ export { auditTrail } from "../policies/audit-trail.js";
110
+ export type { AuditEventChain, AuditTrailOptions, } from "../policies/audit-trail.js";
81
111
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/vault/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GACjB,yBAAyB,GACzB,wBAAwB,GACxB,0BAA0B,GAC1B,oBAAoB,GACpB,yBAAyB,GACzB,2BAA2B,GAC3B,oBAAoB,GACpB,0BAA0B,GAC1B,4BAA4B,GAC5B,uBAAuB,GACvB,6BAA6B,GAC7B,+BAA+B,CAAC;AAEpC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,gBAAgB,GAAG,gBAAgB,CAiBxE;AAMD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,MAAM,CAAC,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC;AASD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAGlE;AAED,wBAAgB,iBAAiB,IAAI,SAAS,aAAa,EAAE,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,gBAAgB,EACpB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAClD,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAEvD;AAkCD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAejE"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/vault/policy.ts"],"names":[],"mappings":"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"}