@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.
- package/README.md +424 -8
- 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/cli/secrets-cli.d.ts.map +1 -1
- package/dist/cli/secrets-cli.js +191 -32
- package/dist/cli/secrets-cli.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/crypto/darwin-keychain.d.ts +394 -0
- package/dist/crypto/darwin-keychain.d.ts.map +1 -0
- package/dist/crypto/darwin-keychain.js +793 -0
- package/dist/crypto/darwin-keychain.js.map +1 -0
- package/dist/crypto/vault-common.d.ts +55 -12
- package/dist/crypto/vault-common.d.ts.map +1 -1
- package/dist/crypto/vault-common.js +74 -71
- package/dist/crypto/vault-common.js.map +1 -1
- package/dist/environment/EnvironmentManager.d.ts.map +1 -1
- package/dist/environment/EnvironmentManager.js +5 -10
- package/dist/environment/EnvironmentManager.js.map +1 -1
- package/dist/index.d.ts +37 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -6
- package/dist/index.js.map +1 -1
- package/dist/key-providers/keychain-provider.d.ts +30 -2
- package/dist/key-providers/keychain-provider.d.ts.map +1 -1
- package/dist/key-providers/keychain-provider.js +29 -5
- package/dist/key-providers/keychain-provider.js.map +1 -1
- package/dist/key-providers/onepassword-provider.d.ts +65 -5
- package/dist/key-providers/onepassword-provider.d.ts.map +1 -1
- package/dist/key-providers/onepassword-provider.js +159 -67
- package/dist/key-providers/onepassword-provider.js.map +1 -1
- package/dist/key-providers/op-cli.d.ts +78 -0
- package/dist/key-providers/op-cli.d.ts.map +1 -0
- package/dist/key-providers/op-cli.js +123 -0
- package/dist/key-providers/op-cli.js.map +1 -0
- package/dist/key-providers/passphrase-provider.d.ts +20 -0
- package/dist/key-providers/passphrase-provider.d.ts.map +1 -1
- package/dist/key-providers/passphrase-provider.js +49 -0
- package/dist/key-providers/passphrase-provider.js.map +1 -1
- package/dist/key-providers/probe.d.ts +46 -0
- package/dist/key-providers/probe.d.ts.map +1 -0
- package/dist/key-providers/probe.js +70 -0
- package/dist/key-providers/probe.js.map +1 -0
- package/dist/key-providers/types.d.ts +51 -1
- package/dist/key-providers/types.d.ts.map +1 -1
- package/dist/platform/agent-detect.d.ts +39 -3
- package/dist/platform/agent-detect.d.ts.map +1 -1
- package/dist/platform/agent-detect.js +55 -9
- package/dist/platform/agent-detect.js.map +1 -1
- package/dist/platform/session-context.d.ts +77 -0
- package/dist/platform/session-context.d.ts.map +1 -0
- package/dist/platform/session-context.js +83 -0
- package/dist/platform/session-context.js.map +1 -0
- 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/secret-state.d.ts +54 -0
- package/dist/secret-state.d.ts.map +1 -0
- package/dist/secret-state.js +2 -0
- package/dist/secret-state.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-errors.d.ts +72 -4
- package/dist/vault/session-vault-errors.d.ts.map +1 -1
- package/dist/vault/session-vault-errors.js +95 -4
- package/dist/vault/session-vault-errors.js.map +1 -1
- package/dist/vault/session-vault.d.ts +145 -2
- package/dist/vault/session-vault.d.ts.map +1 -1
- package/dist/vault/session-vault.js +548 -72
- 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 +58 -10
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/vault/vault-env.d.ts +43 -50
- package/dist/vault/vault-env.d.ts.map +1 -1
- package/dist/vault/vault-env.js +141 -62
- package/dist/vault/vault-env.js.map +1 -1
- package/dist/vault/vault-gpg.d.ts +6 -1
- package/dist/vault/vault-gpg.d.ts.map +1 -1
- package/dist/vault/vault-gpg.js +10 -8
- package/dist/vault/vault-gpg.js.map +1 -1
- package/dist/vault/vault-libsecret.d.ts +6 -1
- package/dist/vault/vault-libsecret.d.ts.map +1 -1
- package/dist/vault/vault-libsecret.js +16 -14
- package/dist/vault/vault-libsecret.js.map +1 -1
- package/dist/vault/vault-onepassword.d.ts +119 -0
- package/dist/vault/vault-onepassword.d.ts.map +1 -0
- package/dist/vault/vault-onepassword.js +271 -0
- package/dist/vault/vault-onepassword.js.map +1 -0
- package/dist/vault/vault-utils.d.ts +37 -3
- package/dist/vault/vault-utils.d.ts.map +1 -1
- package/dist/vault/vault-utils.js +65 -3
- package/dist/vault/vault-utils.js.map +1 -1
- package/dist/vault/vault-windows.d.ts +7 -2
- package/dist/vault/vault-windows.d.ts.map +1 -1
- package/dist/vault/vault-windows.js +21 -16
- package/dist/vault/vault-windows.js.map +1 -1
- package/dist/vault/vault.d.ts +120 -9
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +222 -139
- package/dist/vault/vault.js.map +1 -1
- 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"}
|
package/dist/vault/policy.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* stack
|
|
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
|
-
*
|
|
14
|
-
*
|
|
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
|
-
* (
|
|
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:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
67
|
-
* `0..i
|
|
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.
|
|
70
|
-
*
|
|
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<
|
|
75
|
-
export declare function runAfterHooks(event: SecretsEvent): void;
|
|
76
|
-
export
|
|
77
|
-
|
|
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
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/vault/policy.ts"],"names":[],"mappings":"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"}
|