@queno/agent-node 0.1.2

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 (154) hide show
  1. package/README.md +421 -0
  2. package/dist/agent.d.ts +222 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +591 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/api-discovery/discovery-buffer.d.ts +27 -0
  7. package/dist/api-discovery/discovery-buffer.d.ts.map +1 -0
  8. package/dist/api-discovery/discovery-buffer.js +50 -0
  9. package/dist/api-discovery/discovery-buffer.js.map +1 -0
  10. package/dist/api-discovery/endpoint-observer.d.ts +25 -0
  11. package/dist/api-discovery/endpoint-observer.d.ts.map +1 -0
  12. package/dist/api-discovery/endpoint-observer.js +127 -0
  13. package/dist/api-discovery/endpoint-observer.js.map +1 -0
  14. package/dist/api-discovery/route-normalizer.d.ts +15 -0
  15. package/dist/api-discovery/route-normalizer.d.ts.map +1 -0
  16. package/dist/api-discovery/route-normalizer.js +34 -0
  17. package/dist/api-discovery/route-normalizer.js.map +1 -0
  18. package/dist/config.d.ts +100 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +101 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/db-hooks/correlate.d.ts +19 -0
  23. package/dist/db-hooks/correlate.d.ts.map +1 -0
  24. package/dist/db-hooks/correlate.js +45 -0
  25. package/dist/db-hooks/correlate.js.map +1 -0
  26. package/dist/db-hooks/instrument.d.ts +27 -0
  27. package/dist/db-hooks/instrument.d.ts.map +1 -0
  28. package/dist/db-hooks/instrument.js +194 -0
  29. package/dist/db-hooks/instrument.js.map +1 -0
  30. package/dist/detectors/base.d.ts +61 -0
  31. package/dist/detectors/base.d.ts.map +1 -0
  32. package/dist/detectors/base.js +57 -0
  33. package/dist/detectors/base.js.map +1 -0
  34. package/dist/detectors/bola.d.ts +60 -0
  35. package/dist/detectors/bola.d.ts.map +1 -0
  36. package/dist/detectors/bola.js +108 -0
  37. package/dist/detectors/bola.js.map +1 -0
  38. package/dist/detectors/command-injection.d.ts +22 -0
  39. package/dist/detectors/command-injection.d.ts.map +1 -0
  40. package/dist/detectors/command-injection.js +41 -0
  41. package/dist/detectors/command-injection.js.map +1 -0
  42. package/dist/detectors/custom-rule.d.ts +24 -0
  43. package/dist/detectors/custom-rule.d.ts.map +1 -0
  44. package/dist/detectors/custom-rule.js +65 -0
  45. package/dist/detectors/custom-rule.js.map +1 -0
  46. package/dist/detectors/index.d.ts +17 -0
  47. package/dist/detectors/index.d.ts.map +1 -0
  48. package/dist/detectors/index.js +31 -0
  49. package/dist/detectors/index.js.map +1 -0
  50. package/dist/detectors/nosql-injection.d.ts +23 -0
  51. package/dist/detectors/nosql-injection.d.ts.map +1 -0
  52. package/dist/detectors/nosql-injection.js +54 -0
  53. package/dist/detectors/nosql-injection.js.map +1 -0
  54. package/dist/detectors/path-traversal.d.ts +21 -0
  55. package/dist/detectors/path-traversal.d.ts.map +1 -0
  56. package/dist/detectors/path-traversal.js +54 -0
  57. package/dist/detectors/path-traversal.js.map +1 -0
  58. package/dist/detectors/prototype-pollution.d.ts +23 -0
  59. package/dist/detectors/prototype-pollution.d.ts.map +1 -0
  60. package/dist/detectors/prototype-pollution.js +50 -0
  61. package/dist/detectors/prototype-pollution.js.map +1 -0
  62. package/dist/detectors/sql-injection.d.ts +22 -0
  63. package/dist/detectors/sql-injection.d.ts.map +1 -0
  64. package/dist/detectors/sql-injection.js +42 -0
  65. package/dist/detectors/sql-injection.js.map +1 -0
  66. package/dist/detectors/ssrf.d.ts +26 -0
  67. package/dist/detectors/ssrf.d.ts.map +1 -0
  68. package/dist/detectors/ssrf.js +37 -0
  69. package/dist/detectors/ssrf.js.map +1 -0
  70. package/dist/detectors/suspicious-headers.d.ts +25 -0
  71. package/dist/detectors/suspicious-headers.d.ts.map +1 -0
  72. package/dist/detectors/suspicious-headers.js +87 -0
  73. package/dist/detectors/suspicious-headers.js.map +1 -0
  74. package/dist/detectors/template-injection.d.ts +27 -0
  75. package/dist/detectors/template-injection.d.ts.map +1 -0
  76. package/dist/detectors/template-injection.js +35 -0
  77. package/dist/detectors/template-injection.js.map +1 -0
  78. package/dist/detectors/xss.d.ts +22 -0
  79. package/dist/detectors/xss.d.ts.map +1 -0
  80. package/dist/detectors/xss.js +38 -0
  81. package/dist/detectors/xss.js.map +1 -0
  82. package/dist/index.d.ts +28 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +24 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/integrations/express.d.ts +39 -0
  87. package/dist/integrations/express.d.ts.map +1 -0
  88. package/dist/integrations/express.js +62 -0
  89. package/dist/integrations/express.js.map +1 -0
  90. package/dist/integrations/fastify.d.ts +33 -0
  91. package/dist/integrations/fastify.d.ts.map +1 -0
  92. package/dist/integrations/fastify.js +63 -0
  93. package/dist/integrations/fastify.js.map +1 -0
  94. package/dist/integrations/nestjs.d.ts +40 -0
  95. package/dist/integrations/nestjs.d.ts.map +1 -0
  96. package/dist/integrations/nestjs.js +58 -0
  97. package/dist/integrations/nestjs.js.map +1 -0
  98. package/dist/policy/canonical.d.ts +23 -0
  99. package/dist/policy/canonical.d.ts.map +1 -0
  100. package/dist/policy/canonical.js +40 -0
  101. package/dist/policy/canonical.js.map +1 -0
  102. package/dist/policy/policy-manager.d.ts +43 -0
  103. package/dist/policy/policy-manager.d.ts.map +1 -0
  104. package/dist/policy/policy-manager.js +89 -0
  105. package/dist/policy/policy-manager.js.map +1 -0
  106. package/dist/policy/types.d.ts +70 -0
  107. package/dist/policy/types.d.ts.map +1 -0
  108. package/dist/policy/types.js +2 -0
  109. package/dist/policy/types.js.map +1 -0
  110. package/dist/policy/verify.d.ts +11 -0
  111. package/dist/policy/verify.d.ts.map +1 -0
  112. package/dist/policy/verify.js +61 -0
  113. package/dist/policy/verify.js.map +1 -0
  114. package/dist/redaction/audit-log.d.ts +40 -0
  115. package/dist/redaction/audit-log.d.ts.map +1 -0
  116. package/dist/redaction/audit-log.js +110 -0
  117. package/dist/redaction/audit-log.js.map +1 -0
  118. package/dist/redaction/engine.d.ts +50 -0
  119. package/dist/redaction/engine.d.ts.map +1 -0
  120. package/dist/redaction/engine.js +143 -0
  121. package/dist/redaction/engine.js.map +1 -0
  122. package/dist/redaction/patterns.d.ts +24 -0
  123. package/dist/redaction/patterns.d.ts.map +1 -0
  124. package/dist/redaction/patterns.js +142 -0
  125. package/dist/redaction/patterns.js.map +1 -0
  126. package/dist/runtime-context.d.ts +33 -0
  127. package/dist/runtime-context.d.ts.map +1 -0
  128. package/dist/runtime-context.js +46 -0
  129. package/dist/runtime-context.js.map +1 -0
  130. package/dist/self-protect.d.ts +34 -0
  131. package/dist/self-protect.d.ts.map +1 -0
  132. package/dist/self-protect.js +134 -0
  133. package/dist/self-protect.js.map +1 -0
  134. package/dist/transport/buffer.d.ts +52 -0
  135. package/dist/transport/buffer.d.ts.map +1 -0
  136. package/dist/transport/buffer.js +57 -0
  137. package/dist/transport/buffer.js.map +1 -0
  138. package/dist/transport/client.d.ts +77 -0
  139. package/dist/transport/client.d.ts.map +1 -0
  140. package/dist/transport/client.js +178 -0
  141. package/dist/transport/client.js.map +1 -0
  142. package/dist/transport/heartbeat.d.ts +86 -0
  143. package/dist/transport/heartbeat.d.ts.map +1 -0
  144. package/dist/transport/heartbeat.js +110 -0
  145. package/dist/transport/heartbeat.js.map +1 -0
  146. package/dist/transport/secure-request.d.ts +30 -0
  147. package/dist/transport/secure-request.d.ts.map +1 -0
  148. package/dist/transport/secure-request.js +95 -0
  149. package/dist/transport/secure-request.js.map +1 -0
  150. package/dist/types.d.ts +311 -0
  151. package/dist/types.d.ts.map +1 -0
  152. package/dist/types.js +12 -0
  153. package/dist/types.js.map +1 -0
  154. package/package.json +60 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Canonical policy serialization (agent side).
3
+ *
4
+ * MUST stay byte-for-byte identical to the control-plane implementation in
5
+ * `rasp/lib/policy-signing.ts`. The Ed25519 signature is computed over these
6
+ * exact bytes, so any divergence would make every signature fail to verify.
7
+ */
8
+ /** Policy fields covered by the signature. */
9
+ export interface SignablePolicy {
10
+ projectId: string;
11
+ version: number;
12
+ channel: string;
13
+ mode: string;
14
+ detectionRules: unknown;
15
+ redactionConfig: unknown;
16
+ dataResidency: unknown;
17
+ targetAgentVersion: string | null;
18
+ }
19
+ /** Deterministic JSON serialization with recursively sorted object keys. */
20
+ export declare function stableStringify(value: unknown): string;
21
+ /** Build the exact bytes that were signed by the control plane. */
22
+ export declare function canonicalPolicyBytes(policy: SignablePolicy): Buffer;
23
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/policy/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgBtD;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAYnE"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Canonical policy serialization (agent side).
3
+ *
4
+ * MUST stay byte-for-byte identical to the control-plane implementation in
5
+ * `rasp/lib/policy-signing.ts`. The Ed25519 signature is computed over these
6
+ * exact bytes, so any divergence would make every signature fail to verify.
7
+ */
8
+ /** Deterministic JSON serialization with recursively sorted object keys. */
9
+ export function stableStringify(value) {
10
+ if (value === null || value === undefined)
11
+ return "null";
12
+ if (typeof value === "number" || typeof value === "boolean") {
13
+ return JSON.stringify(value);
14
+ }
15
+ if (typeof value === "string")
16
+ return JSON.stringify(value);
17
+ if (Array.isArray(value)) {
18
+ return "[" + value.map((v) => stableStringify(v)).join(",") + "]";
19
+ }
20
+ const obj = value;
21
+ const keys = Object.keys(obj).sort();
22
+ return ("{" +
23
+ keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") +
24
+ "}");
25
+ }
26
+ /** Build the exact bytes that were signed by the control plane. */
27
+ export function canonicalPolicyBytes(policy) {
28
+ const canonical = {
29
+ channel: policy.channel,
30
+ dataResidency: policy.dataResidency ?? null,
31
+ detectionRules: policy.detectionRules ?? null,
32
+ mode: policy.mode,
33
+ projectId: policy.projectId,
34
+ redactionConfig: policy.redactionConfig ?? null,
35
+ targetAgentVersion: policy.targetAgentVersion ?? null,
36
+ version: policy.version,
37
+ };
38
+ return Buffer.from(stableStringify(canonical), "utf8");
39
+ }
40
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/policy/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACpE,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,CACL,GAAG;QACH,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC5E,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,MAAM,SAAS,GAAG;QAChB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;QAC/C,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { DistributedPolicy } from "./types.js";
2
+ export interface AcceptResult {
3
+ applied: boolean;
4
+ reason?: string;
5
+ }
6
+ export declare class PolicyManager {
7
+ private readonly projectId;
8
+ private readonly trustedKeys;
9
+ private current;
10
+ private lastValid;
11
+ /** The policy in force immediately before the current one (for self-rollback). */
12
+ private previous;
13
+ /**
14
+ * @param projectId - The agent's project id (part of the signed bytes).
15
+ * @param publicKeysPem - Pinned trust anchor public key(s) in PEM form.
16
+ */
17
+ constructor(projectId: string, publicKeysPem: string[]);
18
+ /** Currently applied policy, or null if none accepted yet. */
19
+ get currentPolicy(): DistributedPolicy | null;
20
+ /** Version currently in force (0 if none). */
21
+ get currentVersion(): number;
22
+ /** True if at least one trust anchor is configured. */
23
+ get hasTrustAnchor(): boolean;
24
+ /**
25
+ * Verify and accept a distributed policy.
26
+ *
27
+ * @returns Whether the policy was applied, with a reason on rejection.
28
+ */
29
+ accept(policy: DistributedPolicy): AcceptResult;
30
+ /**
31
+ * Self-rollback: discard the current policy and restore the one in force
32
+ * before it. Used when applying a freshly-accepted policy fails at runtime
33
+ * (Addendum D.4). Returns the policy to re-apply, or null if none.
34
+ */
35
+ rollback(): DistributedPolicy | null;
36
+ /**
37
+ * Add a trusted public key at runtime. Used to honour a key rotation that was
38
+ * announced inside a previously-verified policy, without re-shipping the
39
+ * package.
40
+ */
41
+ addTrustedKey(pem: string): void;
42
+ }
43
+ //# sourceMappingURL=policy-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-manager.d.ts","sourceRoot":"","sources":["../../src/policy/policy-manager.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,aAAa;IAYtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAX5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAkC;IACnD,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAkC;IAElD;;;OAGG;gBAEgB,SAAS,EAAE,MAAM,EAClC,aAAa,EAAE,MAAM,EAAE;IAKzB,8DAA8D;IAC9D,IAAI,aAAa,IAAI,iBAAiB,GAAG,IAAI,CAE5C;IAED,8CAA8C;IAC9C,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,uDAAuD;IACvD,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,YAAY;IAmB/C;;;;OAIG;IACH,QAAQ,IAAI,iBAAiB,GAAG,IAAI;IAWpC;;;;OAIG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAKjC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Policy manager (agent side).
3
+ *
4
+ * Owns the trust decision for incoming policies:
5
+ * 1. Verifies the Ed25519 signature against the pinned trust anchor(s).
6
+ * 2. Enforces version monotonicity (refuses to apply an older version than the
7
+ * one currently in force - anti-replay / anti-rollback).
8
+ * 3. Tracks the last valid policy so the agent can fall back to it if a new
9
+ * policy fails verification (self-rollback of policy, Addendum D.4).
10
+ *
11
+ * It never throws; an untrusted or malformed policy is simply rejected and the
12
+ * current policy is kept.
13
+ */
14
+ import { verifyPolicySignature } from "./verify.js";
15
+ export class PolicyManager {
16
+ projectId;
17
+ trustedKeys;
18
+ current = null;
19
+ lastValid = null;
20
+ /** The policy in force immediately before the current one (for self-rollback). */
21
+ previous = null;
22
+ /**
23
+ * @param projectId - The agent's project id (part of the signed bytes).
24
+ * @param publicKeysPem - Pinned trust anchor public key(s) in PEM form.
25
+ */
26
+ constructor(projectId, publicKeysPem) {
27
+ this.projectId = projectId;
28
+ this.trustedKeys = publicKeysPem.filter((k) => k && k.trim().length > 0);
29
+ }
30
+ /** Currently applied policy, or null if none accepted yet. */
31
+ get currentPolicy() {
32
+ return this.current;
33
+ }
34
+ /** Version currently in force (0 if none). */
35
+ get currentVersion() {
36
+ return this.current?.version ?? 0;
37
+ }
38
+ /** True if at least one trust anchor is configured. */
39
+ get hasTrustAnchor() {
40
+ return this.trustedKeys.length > 0;
41
+ }
42
+ /**
43
+ * Verify and accept a distributed policy.
44
+ *
45
+ * @returns Whether the policy was applied, with a reason on rejection.
46
+ */
47
+ accept(policy) {
48
+ if (this.trustedKeys.length === 0) {
49
+ return { applied: false, reason: "no_trust_anchor" };
50
+ }
51
+ if (!verifyPolicySignature(this.projectId, policy, this.trustedKeys)) {
52
+ return { applied: false, reason: "invalid_signature" };
53
+ }
54
+ if (this.current && policy.version < this.current.version) {
55
+ return { applied: false, reason: "stale_version" };
56
+ }
57
+ this.previous = this.current;
58
+ this.current = policy;
59
+ this.lastValid = policy;
60
+ return { applied: true };
61
+ }
62
+ /**
63
+ * Self-rollback: discard the current policy and restore the one in force
64
+ * before it. Used when applying a freshly-accepted policy fails at runtime
65
+ * (Addendum D.4). Returns the policy to re-apply, or null if none.
66
+ */
67
+ rollback() {
68
+ if (this.previous) {
69
+ this.current = this.previous;
70
+ this.lastValid = this.previous;
71
+ this.previous = null;
72
+ }
73
+ else {
74
+ this.current = null;
75
+ }
76
+ return this.current;
77
+ }
78
+ /**
79
+ * Add a trusted public key at runtime. Used to honour a key rotation that was
80
+ * announced inside a previously-verified policy, without re-shipping the
81
+ * package.
82
+ */
83
+ addTrustedKey(pem) {
84
+ if (pem && pem.trim().length > 0 && !this.trustedKeys.includes(pem)) {
85
+ this.trustedKeys.push(pem);
86
+ }
87
+ }
88
+ }
89
+ //# sourceMappingURL=policy-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-manager.js","sourceRoot":"","sources":["../../src/policy/policy-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAQpD,MAAM,OAAO,aAAa;IAYL;IAXF,WAAW,CAAW;IAC/B,OAAO,GAA6B,IAAI,CAAC;IACzC,SAAS,GAA6B,IAAI,CAAC;IACnD,kFAAkF;IAC1E,QAAQ,GAA6B,IAAI,CAAC;IAElD;;;OAGG;IACH,YACmB,SAAiB,EAClC,aAAuB;QADN,cAAS,GAAT,SAAS,CAAQ;QAGlC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,8DAA8D;IAC9D,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,8CAA8C;IAC9C,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,uDAAuD;IACvD,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAyB;QAC9B,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACrE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QACzD,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC7B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,GAAW;QACvB,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Types describing a policy as distributed by the control plane and applied by
3
+ * the agent. The wire shape returned by `GET /v1/policy` is
4
+ * {@link DistributedPolicy}; the agent verifies its signature, then applies the
5
+ * embedded {@link CustomRuleSpec}s, {@link RedactionConfig} and
6
+ * {@link DataResidencyConfig}.
7
+ */
8
+ import type { AgentMode, Severity } from "../types.js";
9
+ /**
10
+ * A customer-defined detection rule, evaluated by the generic
11
+ * CustomRuleDetector. This is the codeable form of the Addendum requirement
12
+ * "customers can create custom rules used in the RASP agent by policy".
13
+ */
14
+ export interface CustomRuleSpec {
15
+ /** Stable id, surfaced as the matched rule in telemetry. */
16
+ id: string;
17
+ /** Human-readable name. */
18
+ name?: string;
19
+ /** Machine-readable event type emitted on match (e.g. `custom_rule`). */
20
+ eventType?: string;
21
+ /** Severity assigned to a match. */
22
+ severity?: Severity;
23
+ /** Which part of the request to inspect. */
24
+ target?: "path" | "query" | "body" | "headers" | "any";
25
+ /** Regex source string, tested case-insensitively against stringified values. */
26
+ pattern: string;
27
+ /** Optional description for the audit trail. */
28
+ description?: string;
29
+ /** Whether the rule is active. Defaults to true. */
30
+ enabled?: boolean;
31
+ }
32
+ /** How to handle IP addresses found in values. */
33
+ export type IpRedactionMode = "hash" | "mask" | "passthrough";
34
+ /** Redaction directives pushed via policy (Addendum B.2). */
35
+ export interface RedactionConfig {
36
+ /** denylist (default), allowlist, metadata-only, local-only. */
37
+ mode?: "denylist" | "allowlist" | "metadata-only" | "local-only";
38
+ /** Extra field-name regexes to redact (denylist additions). */
39
+ customKeyPatterns?: string[];
40
+ /** Field-name regexes that are always allowed through (allowlist mode). */
41
+ allowKeyPatterns?: string[];
42
+ /** Whether to apply built-in value detectors (Luhn, SIN, email, etc.). */
43
+ valueRedaction?: boolean;
44
+ /** IP handling. Defaults to "hash". */
45
+ ipMode?: IpRedactionMode;
46
+ }
47
+ /** Data residency directives (Addendum B.3). */
48
+ export interface DataResidencyConfig {
49
+ /** Strip all payload data, send only event metadata. */
50
+ metadataOnly?: boolean;
51
+ /** Keep all telemetry local; never send to the collector. */
52
+ localOnly?: boolean;
53
+ /** Only export these event types to the collector (selective export). */
54
+ exportEventTypes?: string[];
55
+ /** Only export blocked detections (not informational/monitor). */
56
+ exportBlockedOnly?: boolean;
57
+ }
58
+ /** Wire shape returned by `GET /v1/policy`. */
59
+ export interface DistributedPolicy {
60
+ version: number;
61
+ channel: string;
62
+ mode: AgentMode;
63
+ detectionRules: CustomRuleSpec[] | null;
64
+ redactionConfig: RedactionConfig | null;
65
+ dataResidency: DataResidencyConfig | null;
66
+ targetAgentVersion: string | null;
67
+ signature: string;
68
+ signingKeyId: string | null;
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IACvD,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAE9D,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,eAAe,GAAG,YAAY,CAAC;IACjE,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uCAAuC;IACvC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,gDAAgD;AAChD,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,cAAc,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import type { DistributedPolicy } from "./types.js";
2
+ /**
3
+ * Verify a distributed policy's signature against a set of trusted public keys.
4
+ *
5
+ * @param projectId - The agent's project id; included in the signed bytes.
6
+ * @param policy - The policy returned by `GET /v1/policy`.
7
+ * @param publicKeysPem - One or more trusted public keys in PEM (SPKI) form.
8
+ * @returns true iff at least one trusted key validates the signature.
9
+ */
10
+ export declare function verifyPolicySignature(projectId: string, policy: DistributedPolicy, publicKeysPem: string[]): boolean;
11
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/policy/verify.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAkCT"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Policy signature verification (agent side).
3
+ *
4
+ * The agent pins one or more trusted Ed25519 public keys (the trust anchor).
5
+ * It verifies every distributed policy against these keys before applying it.
6
+ * A policy that fails verification is ignored and the previous valid policy is
7
+ * kept - a compromised network path or collector cannot inject malicious
8
+ * policies (Addendum E.4.1).
9
+ *
10
+ * Multiple keys are supported so a key rotation announced via a previous
11
+ * (validly signed) policy can be honoured without re-shipping the package.
12
+ */
13
+ import crypto from "node:crypto";
14
+ import { canonicalPolicyBytes } from "./canonical.js";
15
+ function normalizePem(pem) {
16
+ return pem.includes("\\n") ? pem.replace(/\\n/g, "\n") : pem;
17
+ }
18
+ /**
19
+ * Verify a distributed policy's signature against a set of trusted public keys.
20
+ *
21
+ * @param projectId - The agent's project id; included in the signed bytes.
22
+ * @param policy - The policy returned by `GET /v1/policy`.
23
+ * @param publicKeysPem - One or more trusted public keys in PEM (SPKI) form.
24
+ * @returns true iff at least one trusted key validates the signature.
25
+ */
26
+ export function verifyPolicySignature(projectId, policy, publicKeysPem) {
27
+ if (!policy.signature)
28
+ return false;
29
+ const signable = {
30
+ projectId,
31
+ version: policy.version,
32
+ channel: policy.channel,
33
+ mode: policy.mode,
34
+ detectionRules: policy.detectionRules ?? null,
35
+ redactionConfig: policy.redactionConfig ?? null,
36
+ dataResidency: policy.dataResidency ?? null,
37
+ targetAgentVersion: policy.targetAgentVersion ?? null,
38
+ };
39
+ let bytes;
40
+ let sig;
41
+ try {
42
+ bytes = canonicalPolicyBytes(signable);
43
+ sig = Buffer.from(policy.signature, "base64");
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ for (const pem of publicKeysPem) {
49
+ try {
50
+ const key = crypto.createPublicKey(normalizePem(pem));
51
+ if (crypto.verify(null, bytes, key, sig)) {
52
+ return true;
53
+ }
54
+ }
55
+ catch {
56
+ // Try the next key.
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/policy/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAuB,MAAM,gBAAgB,CAAC;AAG3E,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC/D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAAiB,EACjB,MAAyB,EACzB,aAAuB;IAEvB,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAEpC,MAAM,QAAQ,GAAmB;QAC/B,SAAS;QACT,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7C,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;QAC/C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;KACtD,CAAC;IAEF,IAAI,KAAa,CAAC;IAClB,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,KAAK,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACvC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { RedactionAuditEntry } from "../types.js";
2
+ export declare class AuditLog {
3
+ private readonly filePath;
4
+ private readonly maxBytes;
5
+ private fd;
6
+ private currentBytes;
7
+ private rotationIndex;
8
+ /**
9
+ * @param filePath - Destination file. Relative paths are resolved against
10
+ * the process CWD.
11
+ * @param maxBytes - Maximum file size before rotation.
12
+ */
13
+ constructor(filePath: string, maxBytes: number);
14
+ /**
15
+ * Append one entry as JSON + `\n`. Rotates the file first if appending
16
+ * the line would cross the size threshold.
17
+ *
18
+ * All failures (disk full, EBADF, permissions…) are swallowed: an audit
19
+ * log issue must never propagate into the request hot path.
20
+ */
21
+ write(entry: RedactionAuditEntry): void;
22
+ /**
23
+ * Close the underlying file descriptor. Idempotent; safe to call from
24
+ * shutdown handlers and from the kill-switch path.
25
+ */
26
+ close(): void;
27
+ /**
28
+ * Lazily open the file (creating the parent directory if needed) and
29
+ * seed `currentBytes` from the existing file size so we don't blow past
30
+ * `maxBytes` after a restart.
31
+ */
32
+ private ensureOpen;
33
+ /**
34
+ * Close the active file, rename it to `<path>.<rotationIndex>` and reopen
35
+ * a fresh one. If the rename fails (e.g. EACCES), keep writing to the
36
+ * same file - losing rotation is preferred to losing audit data.
37
+ */
38
+ private rotate;
39
+ }
40
+ //# sourceMappingURL=audit-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../src/redaction/audit-log.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAK;IAE1B;;;;OAIG;gBACS,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAK9C;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAoBvC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAWb;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAgBlB;;;;OAIG;IACH,OAAO,CAAC,MAAM;CAYf"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Local redaction audit log.
3
+ *
4
+ * Per `AGENTS.md` "Local Redaction Audit Log" rules:
5
+ * - every redaction action is recorded locally inside the customer
6
+ * environment;
7
+ * - lines never contain raw sensitive values - only metadata;
8
+ * - log rotation by file size is supported to avoid filling the disk;
9
+ * - audit-log failures must NEVER crash the host application - every
10
+ * failure path here returns silently.
11
+ *
12
+ * On-disk format: JSON-Lines (one {@link RedactionAuditEntry} per line),
13
+ * UTF-8, append-mode. When the file exceeds `maxBytes`, it is renamed to
14
+ * `<path>.<n>` and a fresh file is opened.
15
+ */
16
+ import fs from "node:fs";
17
+ import path from "node:path";
18
+ export class AuditLog {
19
+ filePath;
20
+ maxBytes;
21
+ fd = null;
22
+ currentBytes = 0;
23
+ rotationIndex = 0;
24
+ /**
25
+ * @param filePath - Destination file. Relative paths are resolved against
26
+ * the process CWD.
27
+ * @param maxBytes - Maximum file size before rotation.
28
+ */
29
+ constructor(filePath, maxBytes) {
30
+ this.filePath = path.resolve(filePath);
31
+ this.maxBytes = maxBytes;
32
+ }
33
+ /**
34
+ * Append one entry as JSON + `\n`. Rotates the file first if appending
35
+ * the line would cross the size threshold.
36
+ *
37
+ * All failures (disk full, EBADF, permissions…) are swallowed: an audit
38
+ * log issue must never propagate into the request hot path.
39
+ */
40
+ write(entry) {
41
+ try {
42
+ const line = JSON.stringify(entry) + "\n";
43
+ const lineBytes = Buffer.byteLength(line, "utf8");
44
+ this.ensureOpen();
45
+ if (this.currentBytes + lineBytes > this.maxBytes) {
46
+ this.rotate();
47
+ }
48
+ if (this.fd !== null) {
49
+ fs.writeSync(this.fd, line);
50
+ this.currentBytes += lineBytes;
51
+ }
52
+ }
53
+ catch {
54
+ // Intentional - see class-level note.
55
+ }
56
+ }
57
+ /**
58
+ * Close the underlying file descriptor. Idempotent; safe to call from
59
+ * shutdown handlers and from the kill-switch path.
60
+ */
61
+ close() {
62
+ if (this.fd !== null) {
63
+ try {
64
+ fs.closeSync(this.fd);
65
+ }
66
+ catch {
67
+ // ignore
68
+ }
69
+ this.fd = null;
70
+ }
71
+ }
72
+ /**
73
+ * Lazily open the file (creating the parent directory if needed) and
74
+ * seed `currentBytes` from the existing file size so we don't blow past
75
+ * `maxBytes` after a restart.
76
+ */
77
+ ensureOpen() {
78
+ if (this.fd !== null)
79
+ return;
80
+ const dir = path.dirname(this.filePath);
81
+ fs.mkdirSync(dir, { recursive: true });
82
+ this.fd = fs.openSync(this.filePath, "a");
83
+ try {
84
+ const stat = fs.fstatSync(this.fd);
85
+ this.currentBytes = stat.size;
86
+ }
87
+ catch {
88
+ this.currentBytes = 0;
89
+ }
90
+ }
91
+ /**
92
+ * Close the active file, rename it to `<path>.<rotationIndex>` and reopen
93
+ * a fresh one. If the rename fails (e.g. EACCES), keep writing to the
94
+ * same file - losing rotation is preferred to losing audit data.
95
+ */
96
+ rotate() {
97
+ this.close();
98
+ this.rotationIndex += 1;
99
+ const rotated = `${this.filePath}.${this.rotationIndex}`;
100
+ try {
101
+ fs.renameSync(this.filePath, rotated);
102
+ }
103
+ catch {
104
+ // See rationale above.
105
+ }
106
+ this.currentBytes = 0;
107
+ this.ensureOpen();
108
+ }
109
+ }
110
+ //# sourceMappingURL=audit-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/redaction/audit-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,OAAO,QAAQ;IACF,QAAQ,CAAS;IACjB,QAAQ,CAAS;IAC1B,EAAE,GAAkB,IAAI,CAAC;IACzB,YAAY,GAAG,CAAC,CAAC;IACjB,aAAa,GAAG,CAAC,CAAC;IAE1B;;;;OAIG;IACH,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAA0B;QAC9B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAElD,IAAI,CAAC,UAAU,EAAE,CAAC;YAElB,IAAI,IAAI,CAAC,YAAY,GAAG,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,CAAC;YAED,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;gBACrB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC5B,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;YACjC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,UAAU;QAChB,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI;YAAE,OAAO;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,MAAM;QACZ,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;QACxB,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Redaction engine - sanitises an event payload before it leaves the process.
3
+ *
4
+ * Layers (Addendum B.2):
5
+ * 1. Key-based redaction: object keys matching a {@link RedactionPattern} are
6
+ * replaced wholesale.
7
+ * 2. Value-based redaction: string leaves are scanned for sensitive shapes
8
+ * (credit cards, SIN, email, health IDs, IPs, SQL literals) and masked.
9
+ * 3. Mode:
10
+ * - `denylist` (default): strip known-sensitive data, pass everything else.
11
+ * - `allowlist`: redact every value except explicitly approved keys (and a
12
+ * fixed set of structural envelope keys required by the collector).
13
+ *
14
+ * The walker returns a new object - the input is never mutated. A thrown error
15
+ * is treated by the agent as a fatal redaction failure (the event is dropped).
16
+ */
17
+ import { type RedactionPattern, type IpMode } from "./patterns.js";
18
+ import type { RedactionConfig } from "../policy/types.js";
19
+ export interface RedactionResult {
20
+ /** Deep-cloned, sanitised copy of the input value. */
21
+ redacted: unknown;
22
+ /** Dotted paths of every field that was replaced or masked. */
23
+ redactedFields: string[];
24
+ }
25
+ export interface RedactionEngineOptions {
26
+ mode?: "denylist" | "allowlist";
27
+ keyPatterns?: RedactionPattern[];
28
+ allowKeyPatterns?: RegExp[];
29
+ valueRedaction?: boolean;
30
+ ipMode?: IpMode;
31
+ }
32
+ export declare class RedactionEngine {
33
+ private readonly patterns;
34
+ private readonly mode;
35
+ private readonly allowKeyPatterns;
36
+ private readonly valueRedaction;
37
+ private readonly ipMode;
38
+ constructor(extraPatternsOrOptions?: RedactionPattern[] | RedactionEngineOptions);
39
+ /**
40
+ * Build an engine from a policy-supplied {@link RedactionConfig}. Unknown or
41
+ * absent fields fall back to safe defaults (denylist + value redaction).
42
+ */
43
+ static fromConfig(cfg?: RedactionConfig): RedactionEngine;
44
+ redact(value: unknown, path?: string): RedactionResult;
45
+ private walk;
46
+ private redactLeaf;
47
+ private isApprovedKey;
48
+ private shouldRedactKey;
49
+ }
50
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/redaction/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAwBD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IAChC,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,sBAAsB,GAAE,gBAAgB,EAAE,GAAG,sBAA2B;IAYpF;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,eAAe;IA0BzD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,SAAK,GAAG,eAAe;IAMlD,OAAO,CAAC,IAAI;IAuCZ,OAAO,CAAC,UAAU;IAqBlB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,eAAe;CAGxB"}