@blamejs/core 0.15.12 → 0.15.14

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 (365) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/index.js +2 -0
  3. package/lib/a2a-tasks.js +45 -29
  4. package/lib/acme.js +6 -5
  5. package/lib/agent-event-bus.js +18 -4
  6. package/lib/agent-idempotency.js +7 -6
  7. package/lib/agent-orchestrator.js +2 -5
  8. package/lib/agent-saga.js +3 -5
  9. package/lib/agent-snapshot.js +32 -2
  10. package/lib/agent-tenant.js +2 -5
  11. package/lib/ai-adverse-decision.js +2 -15
  12. package/lib/ai-aedt-bias-audit.js +2 -1
  13. package/lib/ai-capability.js +1 -6
  14. package/lib/ai-content-detect.js +1 -3
  15. package/lib/ai-dp.js +1 -5
  16. package/lib/ai-frontier-protocol.js +1 -1
  17. package/lib/ai-input.js +2 -2
  18. package/lib/ai-model-manifest.js +1 -1
  19. package/lib/ai-output.js +16 -7
  20. package/lib/ai-pref.js +3 -8
  21. package/lib/ai-quota.js +3 -14
  22. package/lib/api-key.js +37 -28
  23. package/lib/api-snapshot.js +4 -1
  24. package/lib/app-shutdown.js +7 -1
  25. package/lib/archive-adapters.js +2 -4
  26. package/lib/archive-entry-policy.js +32 -0
  27. package/lib/archive-gz.js +9 -0
  28. package/lib/archive-read.js +14 -24
  29. package/lib/archive-tar-read.js +56 -24
  30. package/lib/archive.js +6 -12
  31. package/lib/arg-parser.js +7 -6
  32. package/lib/asn1-der.js +70 -22
  33. package/lib/asyncapi-traits.js +2 -6
  34. package/lib/atomic-file.js +312 -33
  35. package/lib/audit-chain.js +183 -54
  36. package/lib/audit-daily-review.js +36 -16
  37. package/lib/audit-emit.js +82 -0
  38. package/lib/audit-sign.js +258 -0
  39. package/lib/audit-tools.js +108 -23
  40. package/lib/audit.js +91 -2
  41. package/lib/auth/access-lock.js +7 -29
  42. package/lib/auth/bot-challenge.js +1 -1
  43. package/lib/auth/ciba.js +43 -4
  44. package/lib/auth/dpop.js +29 -36
  45. package/lib/auth/fido-mds3.js +14 -16
  46. package/lib/auth/jwt-external.js +26 -8
  47. package/lib/auth/jwt.js +15 -17
  48. package/lib/auth/lockout.js +24 -27
  49. package/lib/auth/oauth.js +67 -45
  50. package/lib/auth/oid4vci.js +55 -32
  51. package/lib/auth/oid4vp.js +3 -2
  52. package/lib/auth/openid-federation.js +6 -6
  53. package/lib/auth/passkey.js +4 -4
  54. package/lib/auth/password.js +8 -2
  55. package/lib/auth/saml.js +70 -40
  56. package/lib/auth/sd-jwt-vc-holder.js +2 -14
  57. package/lib/auth/sd-jwt-vc-issuer.js +2 -14
  58. package/lib/auth/sd-jwt-vc.js +25 -5
  59. package/lib/auth/status-list.js +21 -9
  60. package/lib/auth/step-up.js +15 -13
  61. package/lib/auth-bot-challenge.js +27 -39
  62. package/lib/backup/bundle.js +18 -20
  63. package/lib/backup/crypto.js +23 -8
  64. package/lib/backup/index.js +55 -67
  65. package/lib/backup/manifest.js +7 -1
  66. package/lib/bounded-map.js +112 -1
  67. package/lib/breach-deadline.js +1 -11
  68. package/lib/break-glass.js +41 -22
  69. package/lib/cache.js +7 -18
  70. package/lib/cbor.js +36 -12
  71. package/lib/cdn-cache-control.js +15 -12
  72. package/lib/cert.js +8 -13
  73. package/lib/chain-writer.js +162 -47
  74. package/lib/cli.js +10 -2
  75. package/lib/client-hints.js +7 -9
  76. package/lib/cloud-events.js +43 -33
  77. package/lib/cluster-storage.js +9 -41
  78. package/lib/cms-codec.js +2 -1
  79. package/lib/codepoint-class.js +84 -1
  80. package/lib/compliance-ai-act-logging.js +1 -6
  81. package/lib/compliance-ai-act-transparency.js +2 -4
  82. package/lib/compliance-eaa.js +2 -12
  83. package/lib/compliance-sanctions-fetcher.js +21 -28
  84. package/lib/compliance-sanctions.js +11 -21
  85. package/lib/compliance.js +3 -10
  86. package/lib/config-drift.js +24 -20
  87. package/lib/content-credentials.js +11 -8
  88. package/lib/content-digest.js +21 -12
  89. package/lib/cookies.js +15 -13
  90. package/lib/cose.js +39 -11
  91. package/lib/cra-report.js +1 -11
  92. package/lib/crdt.js +2 -1
  93. package/lib/crypto-field.js +34 -33
  94. package/lib/crypto.js +138 -7
  95. package/lib/csp.js +239 -3
  96. package/lib/daemon.js +46 -42
  97. package/lib/data-act.js +46 -13
  98. package/lib/db-file-lifecycle.js +14 -6
  99. package/lib/db-query.js +75 -49
  100. package/lib/db.js +66 -27
  101. package/lib/dbsc.js +5 -6
  102. package/lib/ddl-change-control.js +18 -14
  103. package/lib/deprecate.js +4 -5
  104. package/lib/did.js +6 -2
  105. package/lib/dora.js +43 -13
  106. package/lib/dr-runbook.js +1 -1
  107. package/lib/dsa.js +2 -1
  108. package/lib/dsr.js +30 -20
  109. package/lib/early-hints.js +19 -0
  110. package/lib/eat.js +5 -1
  111. package/lib/external-db-migrate.js +21 -22
  112. package/lib/external-db.js +74 -30
  113. package/lib/fda-21cfr11.js +42 -13
  114. package/lib/fdx.js +22 -18
  115. package/lib/file-upload.js +80 -66
  116. package/lib/flag-evaluation-context.js +5 -8
  117. package/lib/flag-providers.js +6 -2
  118. package/lib/forms.js +1 -1
  119. package/lib/framework-error.js +12 -0
  120. package/lib/framework-schema.js +19 -0
  121. package/lib/fsm.js +7 -12
  122. package/lib/gate-contract.js +911 -39
  123. package/lib/gdpr-ropa.js +22 -22
  124. package/lib/graphql-federation.js +18 -5
  125. package/lib/guard-agent-registry.js +2 -1
  126. package/lib/guard-all.js +3 -2
  127. package/lib/guard-archive.js +9 -30
  128. package/lib/guard-auth.js +23 -80
  129. package/lib/guard-cidr.js +20 -96
  130. package/lib/guard-csv.js +135 -196
  131. package/lib/guard-domain.js +23 -106
  132. package/lib/guard-dsn.js +17 -14
  133. package/lib/guard-email.js +46 -53
  134. package/lib/guard-envelope.js +2 -2
  135. package/lib/guard-event-bus-topic.js +2 -1
  136. package/lib/guard-filename.js +12 -60
  137. package/lib/guard-graphql.js +28 -75
  138. package/lib/guard-html-wcag.js +15 -2
  139. package/lib/guard-html.js +74 -128
  140. package/lib/guard-idempotency-key.js +2 -1
  141. package/lib/guard-image.js +280 -77
  142. package/lib/guard-imap-command.js +9 -10
  143. package/lib/guard-jmap.js +1 -1
  144. package/lib/guard-json.js +101 -109
  145. package/lib/guard-jsonpath.js +20 -88
  146. package/lib/guard-jwt.js +32 -114
  147. package/lib/guard-list-id.js +2 -7
  148. package/lib/guard-list-unsubscribe.js +2 -7
  149. package/lib/guard-mail-compose.js +5 -6
  150. package/lib/guard-mail-move.js +3 -2
  151. package/lib/guard-mail-query.js +5 -3
  152. package/lib/guard-mail-sieve.js +6 -7
  153. package/lib/guard-managesieve-command.js +6 -5
  154. package/lib/guard-markdown.js +76 -110
  155. package/lib/guard-message-id.js +5 -6
  156. package/lib/guard-mime.js +20 -99
  157. package/lib/guard-oauth.js +19 -73
  158. package/lib/guard-pdf.js +65 -72
  159. package/lib/guard-pop3-command.js +13 -14
  160. package/lib/guard-posture-chain.js +2 -1
  161. package/lib/guard-regex.js +24 -99
  162. package/lib/guard-saga-config.js +2 -1
  163. package/lib/guard-shell.js +22 -87
  164. package/lib/guard-smtp-command.js +9 -12
  165. package/lib/guard-sql.js +15 -13
  166. package/lib/guard-stream-args.js +2 -1
  167. package/lib/guard-svg.js +103 -149
  168. package/lib/guard-template.js +23 -80
  169. package/lib/guard-tenant-id.js +2 -1
  170. package/lib/guard-text.js +592 -0
  171. package/lib/guard-time.js +27 -95
  172. package/lib/guard-uuid.js +21 -93
  173. package/lib/guard-xml.js +76 -106
  174. package/lib/guard-yaml.js +24 -60
  175. package/lib/html-balance.js +7 -3
  176. package/lib/http-client-cache.js +5 -12
  177. package/lib/http-client-cookie-jar.js +35 -16
  178. package/lib/http-client.js +233 -74
  179. package/lib/http-message-signature.js +3 -2
  180. package/lib/i18n-messageformat.js +5 -7
  181. package/lib/i18n.js +83 -26
  182. package/lib/iab-tcf.js +3 -2
  183. package/lib/importmap-integrity.js +41 -1
  184. package/lib/inbox.js +8 -8
  185. package/lib/incident-report.js +12 -27
  186. package/lib/ip-utils.js +49 -6
  187. package/lib/jobs.js +3 -2
  188. package/lib/json-patch.js +1 -1
  189. package/lib/json-path.js +24 -3
  190. package/lib/jtd.js +2 -2
  191. package/lib/keychain.js +6 -18
  192. package/lib/legal-hold.js +30 -23
  193. package/lib/log-stream-cloudwatch.js +44 -112
  194. package/lib/log-stream-otlp-grpc.js +17 -14
  195. package/lib/log-stream-otlp.js +16 -80
  196. package/lib/log-stream-webhook.js +20 -92
  197. package/lib/log.js +2 -2
  198. package/lib/mail-agent.js +2 -2
  199. package/lib/mail-arc-sign.js +8 -3
  200. package/lib/mail-arf.js +4 -3
  201. package/lib/mail-auth.js +43 -69
  202. package/lib/mail-bimi.js +35 -55
  203. package/lib/mail-bounce.js +3 -3
  204. package/lib/mail-crypto-pgp.js +3 -2
  205. package/lib/mail-crypto-smime.js +71 -6
  206. package/lib/mail-dav.js +8 -35
  207. package/lib/mail-deploy.js +15 -14
  208. package/lib/mail-dkim.js +19 -38
  209. package/lib/mail-greylist.js +17 -30
  210. package/lib/mail-helo.js +4 -7
  211. package/lib/mail-journal.js +13 -9
  212. package/lib/mail-mdn.js +12 -7
  213. package/lib/mail-rbl.js +7 -12
  214. package/lib/mail-scan.js +5 -7
  215. package/lib/mail-send-deliver.js +33 -20
  216. package/lib/mail-server-imap.js +32 -87
  217. package/lib/mail-server-jmap.js +39 -52
  218. package/lib/mail-server-managesieve.js +29 -83
  219. package/lib/mail-server-mx.js +33 -74
  220. package/lib/mail-server-net.js +177 -0
  221. package/lib/mail-server-pop3.js +30 -83
  222. package/lib/mail-server-rate-limit.js +30 -6
  223. package/lib/mail-server-registry.js +1 -1
  224. package/lib/mail-server-submission.js +34 -73
  225. package/lib/mail-server-tls.js +98 -2
  226. package/lib/mail-spam-score.js +9 -12
  227. package/lib/mail-store-fts.js +1 -1
  228. package/lib/mail-store.js +3 -2
  229. package/lib/mail.js +28 -13
  230. package/lib/markup-escape.js +31 -0
  231. package/lib/markup-tokenizer.js +78 -0
  232. package/lib/mcp-tool-registry.js +26 -23
  233. package/lib/mcp.js +7 -5
  234. package/lib/mdoc.js +36 -14
  235. package/lib/metrics.js +46 -33
  236. package/lib/middleware/age-gate.js +3 -23
  237. package/lib/middleware/api-encrypt.js +13 -24
  238. package/lib/middleware/assetlinks.js +2 -7
  239. package/lib/middleware/bearer-auth.js +2 -1
  240. package/lib/middleware/body-parser.js +41 -52
  241. package/lib/middleware/bot-disclose.js +7 -10
  242. package/lib/middleware/bot-guard.js +28 -28
  243. package/lib/middleware/clear-site-data.js +5 -1
  244. package/lib/middleware/compression.js +9 -0
  245. package/lib/middleware/cors.js +32 -23
  246. package/lib/middleware/csrf-protect.js +73 -23
  247. package/lib/middleware/daily-byte-quota.js +12 -30
  248. package/lib/middleware/deny-response.js +19 -1
  249. package/lib/middleware/fetch-metadata.js +35 -4
  250. package/lib/middleware/idempotency-key.js +4 -20
  251. package/lib/middleware/network-allowlist.js +61 -30
  252. package/lib/middleware/rate-limit.js +45 -44
  253. package/lib/middleware/scim-server.js +5 -3
  254. package/lib/middleware/security-headers.js +33 -7
  255. package/lib/middleware/security-txt.js +2 -6
  256. package/lib/middleware/speculation-rules.js +6 -3
  257. package/lib/middleware/tus-upload.js +14 -29
  258. package/lib/middleware/web-app-manifest.js +2 -7
  259. package/lib/migrations.js +4 -13
  260. package/lib/mime-parse.js +34 -17
  261. package/lib/module-loader.js +44 -0
  262. package/lib/money.js +105 -0
  263. package/lib/mtls-ca.js +125 -41
  264. package/lib/network-byte-quota.js +4 -18
  265. package/lib/network-dane.js +8 -6
  266. package/lib/network-dns-resolver.js +98 -7
  267. package/lib/network-dns.js +9 -2
  268. package/lib/network-dnssec.js +18 -17
  269. package/lib/network-heartbeat.js +3 -2
  270. package/lib/network-smtp-policy.js +52 -46
  271. package/lib/network-tls.js +67 -47
  272. package/lib/network-tsig.js +2 -2
  273. package/lib/nis2-report.js +2 -12
  274. package/lib/nist-crosswalk.js +1 -1
  275. package/lib/nonce-store.js +81 -3
  276. package/lib/ntp-check.js +28 -0
  277. package/lib/numeric-bounds.js +31 -8
  278. package/lib/object-store/azure-blob-bucket-ops.js +2 -6
  279. package/lib/object-store/azure-blob.js +6 -47
  280. package/lib/object-store/gcs-bucket-ops.js +4 -2
  281. package/lib/object-store/gcs.js +14 -75
  282. package/lib/object-store/http-put.js +2 -7
  283. package/lib/object-store/http-request.js +157 -0
  284. package/lib/object-store/local.js +37 -17
  285. package/lib/object-store/sigv4-bucket-ops.js +2 -1
  286. package/lib/object-store/sigv4.js +10 -79
  287. package/lib/observability-otlp-exporter.js +29 -29
  288. package/lib/observability.js +95 -0
  289. package/lib/openapi-paths-builder.js +7 -3
  290. package/lib/otel-export.js +7 -10
  291. package/lib/outbox.js +54 -41
  292. package/lib/pagination.js +11 -15
  293. package/lib/parsers/safe-env.js +5 -4
  294. package/lib/parsers/safe-ini.js +10 -4
  295. package/lib/parsers/safe-toml.js +11 -9
  296. package/lib/parsers/safe-xml.js +3 -3
  297. package/lib/parsers/safe-yaml.js +28 -9
  298. package/lib/pick.js +63 -5
  299. package/lib/pipl-cn.js +69 -59
  300. package/lib/privacy-pass.js +8 -6
  301. package/lib/problem-details.js +2 -5
  302. package/lib/pubsub.js +4 -8
  303. package/lib/queue-local.js +10 -3
  304. package/lib/redact.js +9 -4
  305. package/lib/render.js +4 -2
  306. package/lib/request-helpers.js +334 -29
  307. package/lib/resource-access-lock.js +3 -3
  308. package/lib/restore-bundle.js +46 -18
  309. package/lib/restore-rollback.js +10 -4
  310. package/lib/restore.js +24 -22
  311. package/lib/retention.js +23 -9
  312. package/lib/router.js +17 -4
  313. package/lib/safe-async.js +457 -0
  314. package/lib/safe-buffer.js +137 -6
  315. package/lib/safe-decompress.js +2 -1
  316. package/lib/safe-dns.js +2 -1
  317. package/lib/safe-ical.js +14 -28
  318. package/lib/safe-icap.js +1 -1
  319. package/lib/safe-json.js +51 -8
  320. package/lib/safe-jsonpath.js +6 -5
  321. package/lib/safe-mime.js +25 -29
  322. package/lib/safe-redirect.js +2 -5
  323. package/lib/safe-schema.js +7 -6
  324. package/lib/safe-sieve.js +1 -1
  325. package/lib/safe-sql.js +126 -0
  326. package/lib/safe-vcard.js +13 -27
  327. package/lib/sandbox-worker.js +15 -2
  328. package/lib/sandbox.js +4 -3
  329. package/lib/scheduler.js +22 -13
  330. package/lib/sec-cyber.js +82 -37
  331. package/lib/seeders.js +4 -11
  332. package/lib/self-update-standalone-verifier.js +16 -0
  333. package/lib/self-update.js +92 -69
  334. package/lib/session-device-binding.js +112 -66
  335. package/lib/session.js +219 -7
  336. package/lib/sql.js +228 -81
  337. package/lib/sse.js +6 -10
  338. package/lib/static.js +201 -111
  339. package/lib/storage.js +4 -2
  340. package/lib/structured-fields.js +275 -16
  341. package/lib/template.js +7 -5
  342. package/lib/tenant-quota.js +53 -38
  343. package/lib/tsa.js +16 -17
  344. package/lib/validate-opts.js +154 -8
  345. package/lib/vault/index.js +5 -0
  346. package/lib/vault/passphrase-ops.js +22 -26
  347. package/lib/vault/passphrase-source.js +8 -3
  348. package/lib/vault/rotate.js +13 -18
  349. package/lib/vault/seal-pem-file.js +34 -49
  350. package/lib/vault-aad.js +3 -2
  351. package/lib/vc.js +3 -8
  352. package/lib/vendor/MANIFEST.json +10 -10
  353. package/lib/vendor/public-suffix-list.dat +23 -10
  354. package/lib/vendor/public-suffix-list.data.js +5498 -5494
  355. package/lib/vex.js +35 -13
  356. package/lib/web-push-vapid.js +23 -20
  357. package/lib/webhook-dispatcher.js +706 -0
  358. package/lib/webhook.js +59 -19
  359. package/lib/websocket-channels.js +9 -7
  360. package/lib/websocket.js +8 -4
  361. package/lib/worm.js +3 -4
  362. package/lib/ws-client.js +65 -56
  363. package/lib/x509-chain.js +44 -0
  364. package/package.json +1 -1
  365. package/sbom.cdx.json +6 -6
package/lib/gdpr-ropa.js CHANGED
@@ -37,6 +37,7 @@
37
37
  var defineClass = require("./framework-error").defineClass;
38
38
  var lazyRequire = require("./lazy-require");
39
39
  var validateOpts = require("./validate-opts");
40
+ var boundedMap = require("./bounded-map");
40
41
 
41
42
  var audit = lazyRequire(function () { return require("./audit"); });
42
43
 
@@ -68,21 +69,11 @@ function create(opts) {
68
69
  var controller = opts.controller;
69
70
  var dpo = opts.dpo || null;
70
71
  var supervisoryAuthority = opts.supervisoryAuthority || null;
71
- var auditOn = opts.audit !== false;
72
72
  var now = typeof opts.now === "function" ? opts.now : function () { return Date.now(); };
73
73
 
74
74
  var activities = new Map();
75
75
 
76
- function _emitAudit(action, outcome, metadata) {
77
- if (!auditOn) return;
78
- try {
79
- audit().safeEmit({
80
- action: "gdpr.ropa." + action,
81
- outcome: outcome,
82
- metadata: metadata || {},
83
- });
84
- } catch (_e) { /* drop-silent */ }
85
- }
76
+ var _emitAudit = audit().namespaced("gdpr.ropa", opts.audit);
86
77
 
87
78
  function _validateActivity(activity, op) {
88
79
  if (!activity || typeof activity !== "object") {
@@ -100,7 +91,7 @@ function create(opts) {
100
91
  throw new GdprRopaError("gdpr-ropa/bad-id",
101
92
  "gdpr.ropa." + op + ": activity.id must be a non-empty string");
102
93
  }
103
- if (!VALID_LEGAL_BASES[activity.legalBasis]) {
94
+ if (!Object.prototype.hasOwnProperty.call(VALID_LEGAL_BASES, activity.legalBasis)) {
104
95
  throw new GdprRopaError("gdpr-ropa/bad-legal-basis",
105
96
  "gdpr.ropa." + op + ": activity.legalBasis must be one of " + Object.keys(VALID_LEGAL_BASES).join(", "));
106
97
  }
@@ -108,10 +99,10 @@ function create(opts) {
108
99
 
109
100
  function register(activity) {
110
101
  _validateActivity(activity, "register");
111
- if (activities.has(activity.id)) {
102
+ boundedMap.requireAbsent(activities, activity.id, function () {
112
103
  throw new GdprRopaError("gdpr-ropa/duplicate-id",
113
104
  "gdpr.ropa.register: activity '" + activity.id + "' already registered");
114
- }
105
+ });
115
106
  var rec = Object.assign({}, activity, {
116
107
  registeredAt: now(),
117
108
  lastUpdatedAt: now(),
@@ -136,7 +127,7 @@ function create(opts) {
136
127
  registeredAt: existing.registeredAt,
137
128
  lastUpdatedAt: now(),
138
129
  });
139
- if (patch.legalBasis && !VALID_LEGAL_BASES[merged.legalBasis]) {
130
+ if (patch.legalBasis && !Object.prototype.hasOwnProperty.call(VALID_LEGAL_BASES, merged.legalBasis)) {
140
131
  throw new GdprRopaError("gdpr-ropa/bad-legal-basis",
141
132
  "gdpr.ropa.update: legalBasis must be one of " + Object.keys(VALID_LEGAL_BASES).join(", "));
142
133
  }
@@ -182,6 +173,21 @@ function create(opts) {
182
173
  activities: list(),
183
174
  };
184
175
  }
176
+ // Quote a CSV cell AND neutralize spreadsheet formula injection (CWE-1236):
177
+ // a value beginning with = + - @ TAB or CR is evaluated as a formula by
178
+ // Excel / Google Sheets when the export is opened, so a RoPA field like
179
+ // "=HYPERLINK(...)" or "=cmd|..." would execute. Prefix such a value with a
180
+ // single quote so the spreadsheet renders it as literal text; then RFC-4180
181
+ // quote (double internal quotes).
182
+ function _csvCell(v) {
183
+ var s = (v === undefined || v === null) ? ""
184
+ : (Array.isArray(v) ? JSON.stringify(v) : String(v));
185
+ var c0 = s.charCodeAt(0);
186
+ if (c0 === 0x3d || c0 === 0x2b || c0 === 0x2d || c0 === 0x40 || c0 === 0x09 || c0 === 0x0d) {
187
+ s = "'" + s;
188
+ }
189
+ return '"' + s.replace(/"/g, '""') + '"';
190
+ }
185
191
  function _exportCsv() {
186
192
  var headers = [
187
193
  "id", "name", "purposes", "legalBasis", "dataCategories",
@@ -192,13 +198,7 @@ function create(opts) {
192
198
  var entries = list();
193
199
  for (var i = 0; i < entries.length; i++) {
194
200
  var e = entries[i];
195
- var row = headers.map(function (h) {
196
- var v = e[h];
197
- if (v === undefined || v === null) return "";
198
- if (Array.isArray(v)) return JSON.stringify(v).replace(/"/g, "\"\"");
199
- return String(v).replace(/"/g, "\"\"");
200
- });
201
- rows.push(row.map(function (c) { return '"' + c + '"'; }).join(","));
201
+ rows.push(headers.map(function (h) { return _csvCell(e[h]); }).join(","));
202
202
  }
203
203
  return rows.join("\n");
204
204
  }
@@ -35,7 +35,13 @@ var ROUTER_TOKEN_MIN_LEN = 32;
35
35
  var NONCE_MIN_LEN = 16; // string-length floor for nonce entropy, not bytes
36
36
  var NONCE_MAX_LEN = 256; // string-length cap, not bytes
37
37
  var NONCE_PREVIEW_LEN = 8; // log-preview slice length, not bytes
38
- var SDL_PROBE_RE = /(^|[\s,{])_service\b|_entities\b/;
38
+ // Word-boundary anchored on BOTH probes. A prefix char-class ([\s,{]) on
39
+ // `_service` was bypassable by an alias with no leading space — `query{x:_service{sdl}}`
40
+ // has `:` before `_service`, which is not in the class, so the SDL trust gate
41
+ // was skipped and the subgraph leaked its full SDL. `\b` already prevents
42
+ // matching substrings like `my_service` (no boundary between `y` and `_`), so
43
+ // the prefix class only added the bypass.
44
+ var SDL_PROBE_RE = /\b_service\b|\b_entities\b/;
39
45
 
40
46
  /**
41
47
  * @primitive b.graphqlFederation.queryProbesSdl
@@ -66,7 +72,7 @@ function queryProbesSdl(query) {
66
72
  function _readBearer(req) {
67
73
  var h = req.headers && req.headers.authorization;
68
74
  if (typeof h !== "string") return null;
69
- if (h.length > C.BYTES.kib(8)) return null;
75
+ if (safeBuffer.byteLengthOf(h) > C.BYTES.kib(8)) return null;
70
76
  var m = /^Bearer\s+([A-Za-z0-9._~+/=-]+)$/.exec(h.trim());
71
77
  return m ? m[1] : null;
72
78
  }
@@ -173,14 +179,21 @@ function guardSdl(opts) {
173
179
  return function graphqlFedGuard(req, res, next) {
174
180
  Promise.resolve().then(function () {
175
181
  return _readBody(req, errorClass).then(function (rawBody) {
176
- var query = null;
182
+ var probesSdl = false;
177
183
  try {
178
184
  var parsed = typeof rawBody === "string" ? safeJson.parse(rawBody, { maxBytes: C.BYTES.mib(1) }) : rawBody; // routed via safeJson.parse
179
- query = parsed && typeof parsed === "object" ? parsed.query : null;
185
+ // A GraphQL HTTP batch is a JSON ARRAY of operations; probe EVERY
186
+ // element's query, not just `parsed.query` (which is undefined for an
187
+ // array → the SDL gate was skipped and a batched `_service{sdl}`
188
+ // operation leaked the SDL on batching-enabled subgraphs).
189
+ var candidates = Array.isArray(parsed)
190
+ ? parsed.map(function (o) { return o && typeof o === "object" ? o.query : null; })
191
+ : [parsed && typeof parsed === "object" ? parsed.query : null];
192
+ probesSdl = candidates.some(queryProbesSdl);
180
193
  } catch (_e) { /* not JSON; pass through */ }
181
194
  if (req.body === undefined) req.body = rawBody;
182
195
 
183
- if (!queryProbesSdl(query)) {
196
+ if (!probesSdl) {
184
197
  if (typeof next === "function") next();
185
198
  return;
186
199
  }
@@ -24,6 +24,7 @@
24
24
 
25
25
  var { defineClass } = require("./framework-error");
26
26
  var gateContract = require("./gate-contract");
27
+ var codepointClass = require("./codepoint-class");
27
28
 
28
29
  var GuardAgentRegistryError = defineClass("GuardAgentRegistryError", { alwaysPermanent: true });
29
30
 
@@ -120,7 +121,7 @@ function _checkName(name, profile) {
120
121
  throw new GuardAgentRegistryError("agent-registry/non-ascii",
121
122
  "guardAgentRegistry.validate: name contains non-ASCII codepoint at offset " + i);
122
123
  }
123
- if (c < 0x20 || c === 0x7F || c === 0x2F || c === 0x5C) { // C0 / DEL / slash / backslash
124
+ if (codepointClass.isForbiddenControlChar(c, { forbidTab: true }) || c === 0x2F || c === 0x5C) { // C0 / DEL / slash / backslash
124
125
  throw new GuardAgentRegistryError("agent-registry/bad-name-char",
125
126
  "guardAgentRegistry.validate: name contains forbidden char 0x" + c.toString(16));
126
127
  }
package/lib/guard-all.js CHANGED
@@ -59,6 +59,7 @@ var GUARDS = [
59
59
  require("./guard-xml"),
60
60
  require("./guard-markdown"),
61
61
  require("./guard-email"),
62
+ require("./guard-text"),
62
63
  ];
63
64
 
64
65
  // STANDALONE_GUARDS — guard-* primitives that don't fit content-type
@@ -127,12 +128,12 @@ function _verifyParity() {
127
128
  failures.push(g.NAME + ": missing gate(opts) function");
128
129
  }
129
130
  SHARED_PROFILES.forEach(function (p) {
130
- if (!g.PROFILES || !g.PROFILES[p]) {
131
+ if (!g.PROFILES || !Object.prototype.hasOwnProperty.call(g.PROFILES, p)) {
131
132
  failures.push(g.NAME + ": does not declare shared profile " + JSON.stringify(p));
132
133
  }
133
134
  });
134
135
  SHARED_POSTURES.forEach(function (p) {
135
- if (!g.COMPLIANCE_POSTURES || !g.COMPLIANCE_POSTURES[p]) {
136
+ if (!g.COMPLIANCE_POSTURES || !Object.prototype.hasOwnProperty.call(g.COMPLIANCE_POSTURES, p)) {
136
137
  failures.push(g.NAME + ": does not declare shared compliance posture " + JSON.stringify(p));
137
138
  }
138
139
  });
@@ -112,10 +112,7 @@ var MAGIC_SIGNATURES = Object.freeze([
112
112
 
113
113
  var PROFILES = Object.freeze({
114
114
  "strict": {
115
- bidiPolicy: "reject",
116
- controlPolicy: "reject",
117
- nullBytePolicy: "reject",
118
- zeroWidthPolicy: "reject",
115
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
119
116
  traversalPolicy: "reject",
120
117
  absolutePathPolicy: "reject",
121
118
  symlinkPolicy: "reject",
@@ -179,26 +176,12 @@ var PROFILES = Object.freeze({
179
176
  },
180
177
  });
181
178
 
182
- var DEFAULTS = Object.freeze(Object.assign({}, PROFILES["strict"], {
183
- mode: "enforce",
184
- maxRuntimeMs: C.TIME.seconds(10),
185
- }));
186
-
187
- var COMPLIANCE_POSTURES = Object.freeze({
188
- "hipaa": Object.assign({}, PROFILES["strict"], {
189
- forensicSnippetBytes: C.BYTES.bytes(256),
190
- }),
191
- "pci-dss": Object.assign({}, PROFILES["strict"], {
192
- forensicSnippetBytes: C.BYTES.bytes(256),
193
- }),
194
- "gdpr": Object.assign({}, PROFILES["balanced"], {
195
- forensicSnippetBytes: C.BYTES.bytes(128),
196
- }),
197
- "soc2": Object.assign({}, PROFILES["strict"], {
198
- forensicSnippetBytes: C.BYTES.bytes(512),
199
- }),
179
+ var DEFAULTS = gateContract.strictDefaults(PROFILES, {
180
+ maxRuntimeMs: C.TIME.seconds(10),
200
181
  });
201
182
 
183
+ var COMPLIANCE_POSTURES = gateContract.compliancePostures(PROFILES, { base: 256 });
184
+
202
185
  // ---- Helpers ----
203
186
 
204
187
  function _resolveOpts(opts) {
@@ -698,7 +681,8 @@ function validateEntries(entries, opts) {
698
681
  snippet: "entries must be an array" }],
699
682
  };
700
683
  }
701
- return gateContract.aggregateIssues(_detectIssues(entries, opts));
684
+ // "raw" contract — entries is an array the detector type-checks itself.
685
+ return gateContract.runIssueValidator(entries, opts, _detectIssues, "raw");
702
686
  }
703
687
 
704
688
  /**
@@ -777,13 +761,8 @@ function gate(opts) {
777
761
  return { ok: true, action: "serve" };
778
762
  }
779
763
  var rv = validateEntries(entries, opts);
780
- if (rv.issues.length === 0) return { ok: true, action: "serve" };
781
- var hasCritical = rv.issues.some(function (i) {
782
- return i.severity === "critical" || i.severity === "high";
783
- });
784
- if (!hasCritical) return { ok: true, action: "audit-only", issues: rv.issues };
785
- // Archive content has no safe sanitization — refuse.
786
- return { ok: false, action: "refuse", issues: rv.issues };
764
+ // Archive content has no safe sanitization serve / audit-only / refuse.
765
+ return gateContract.severityDisposition(rv.issues);
787
766
  });
788
767
  }
789
768
 
package/lib/guard-auth.js CHANGED
@@ -44,7 +44,6 @@
44
44
  var lazyRequire = require("./lazy-require");
45
45
  var gateContract = require("./gate-contract");
46
46
  var C = require("./constants");
47
- var numericBounds = require("./numeric-bounds");
48
47
  var guardJwt = require("./guard-jwt");
49
48
  var guardOauth = require("./guard-oauth");
50
49
  var cookies = require("./cookies");
@@ -59,30 +58,21 @@ var _err = GuardAuthError.factory;
59
58
 
60
59
  var PROFILES = Object.freeze({
61
60
  "strict": {
62
- bidiPolicy: "reject",
63
- controlPolicy: "reject",
64
- nullBytePolicy: "reject",
65
- zeroWidthPolicy: "reject",
61
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
66
62
  childProfile: "strict",
67
63
  requireAtLeastOne: true,
68
64
  maxBytes: C.BYTES.kib(64),
69
65
  maxRuntimeMs: C.TIME.seconds(2),
70
66
  },
71
67
  "balanced": {
72
- bidiPolicy: "reject",
73
- controlPolicy: "reject",
74
- nullBytePolicy: "reject",
75
- zeroWidthPolicy: "reject",
68
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
76
69
  childProfile: "balanced",
77
70
  requireAtLeastOne: false,
78
71
  maxBytes: C.BYTES.kib(128),
79
72
  maxRuntimeMs: C.TIME.seconds(2),
80
73
  },
81
74
  "permissive": {
82
- bidiPolicy: "reject", // BIDI refused at every profile
83
- controlPolicy: "reject", // controls refused at every profile
84
- nullBytePolicy: "reject", // null refused at every profile
85
- zeroWidthPolicy: "reject", // zero-width refused at every profile
75
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
86
76
  childProfile: "permissive",
87
77
  requireAtLeastOne: false,
88
78
  maxBytes: C.BYTES.kib(512),
@@ -90,35 +80,6 @@ var PROFILES = Object.freeze({
90
80
  },
91
81
  });
92
82
 
93
- var DEFAULTS = Object.freeze(Object.assign({}, PROFILES["strict"], {
94
- mode: "enforce",
95
- }));
96
-
97
- var COMPLIANCE_POSTURES = Object.freeze({
98
- "hipaa": Object.assign({}, PROFILES["strict"], {
99
- forensicSnippetBytes: C.BYTES.bytes(512),
100
- }),
101
- "pci-dss": Object.assign({}, PROFILES["strict"], {
102
- forensicSnippetBytes: C.BYTES.bytes(512),
103
- }),
104
- "gdpr": Object.assign({}, PROFILES["balanced"], {
105
- forensicSnippetBytes: C.BYTES.bytes(256),
106
- }),
107
- "soc2": Object.assign({}, PROFILES["strict"], {
108
- forensicSnippetBytes: C.BYTES.bytes(1024),
109
- }),
110
- });
111
-
112
- function _resolveOpts(opts) {
113
- return gateContract.resolveProfileAndPosture(opts, {
114
- profiles: PROFILES,
115
- compliancePostures: COMPLIANCE_POSTURES,
116
- defaults: DEFAULTS,
117
- errorClass: GuardAuthError,
118
- errCodePrefix: "auth",
119
- });
120
- }
121
-
122
83
  function _detectIssues(bundle, opts) {
123
84
  var issues = [];
124
85
  if (!bundle || typeof bundle !== "object") {
@@ -232,13 +193,9 @@ function _detectIssues(bundle, opts) {
232
193
  * rv.ok; // → false
233
194
  * rv.issues.some(function (i) { return i.source === "jwt"; }); // → true
234
195
  */
235
- function validate(input, opts) {
236
- opts = _resolveOpts(opts);
237
- numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
238
- ["maxBytes"],
239
- "guardAuth.validate", GuardAuthError, "auth.bad-opt");
240
- return gateContract.aggregateIssues(_detectIssues(input, opts));
241
- }
196
+ // validate is assembled by gateContract.defineGuard from `detect`
197
+ // (_detectIssues), with the maxBytes cap declared via `intOpts`.
198
+ // The @primitive block above documents the resulting ABI.
242
199
 
243
200
  /**
244
201
  * @primitive b.guardAuth.sanitize
@@ -266,19 +223,15 @@ function validate(input, opts) {
266
223
  * }, { profile: "balanced" });
267
224
  * clean.cookieHeader; // → "sid=abc123"
268
225
  */
269
- function sanitize(input, opts) {
270
- opts = _resolveOpts(opts);
271
- if (!input || typeof input !== "object") {
272
- throw _err("auth.bad-input", "sanitize requires bundle object");
273
- }
274
- var issues = _detectIssues(input, opts);
275
- for (var i = 0; i < issues.length; i += 1) {
276
- if (issues[i].severity === "critical" || issues[i].severity === "high") {
277
- throw _err(issues[i].ruleId || "auth.refused",
278
- "guardAuth.sanitize [" + issues[i].source + "]: " +
279
- issues[i].snippet);
280
- }
281
- }
226
+ // _sanitizeTransform the normalize tail applied by defineGuard's generated
227
+ // sanitize AFTER resolve -> detect -> throwOnRefusalSeverity (default severities
228
+ // ['critical','high']). The auth-bundle is composed of values the framework
229
+ // cannot safely mutate (forging a JWT alg / rewriting an OAuth state parameter /
230
+ // dropping cookies would silently disarm an actual attack token), so the
231
+ // transform is identity — the bundle is returned unchanged when no high/critical
232
+ // issue refused upstream. A non-object input refuses upstream via the high-
233
+ // severity auth.bad-input issue _detectIssues raises.
234
+ function _sanitizeTransform(input) {
282
235
  return input;
283
236
  }
284
237
 
@@ -313,25 +266,15 @@ function sanitize(input, opts) {
313
266
  * verdict.action; // → "refuse"
314
267
  */
315
268
  function gate(opts) {
316
- opts = _resolveOpts(opts);
269
+ opts = _guard.resolveOpts(opts);
317
270
  return gateContract.buildGuardGate(
318
271
  opts.name || "guardAuth:" + (opts.profile || "default"),
319
272
  opts,
320
273
  async function (ctx) {
321
274
  var bundle = ctx && (ctx.authBundle || ctx.auth);
322
275
  if (!bundle) return { ok: true, action: "serve" };
323
- var rv = validate(bundle, opts);
324
- if (rv.issues.length === 0) return { ok: true, action: "serve" };
325
- var hasCritical = rv.issues.some(function (i) {
326
- return i.severity === "critical";
327
- });
328
- var hasHigh = rv.issues.some(function (i) {
329
- return i.severity === "high";
330
- });
331
- if (!hasCritical && !hasHigh) {
332
- return { ok: true, action: "audit-only", issues: rv.issues };
333
- }
334
- return { ok: false, action: "refuse", issues: rv.issues };
276
+ var rv = module.exports.validate(bundle, opts);
277
+ return gateContract.severityDisposition(rv.issues);
335
278
  });
336
279
  }
337
280
 
@@ -367,15 +310,15 @@ var INTEGRATION_FIXTURES = Object.freeze({
367
310
  // surface (validate / sanitize / bespoke gate) passed through verbatim.
368
311
  // The custom KIND ("auth-bundle") is accepted because the bespoke gate
369
312
  // reads its own ctx fields (ctx.authBundle / ctx.auth).
370
- module.exports = gateContract.defineGuard({
313
+ var _guard = module.exports = gateContract.defineGuard({
371
314
  name: "auth",
372
315
  kind: "auth-bundle",
373
316
  errorClass: GuardAuthError,
374
317
  profiles: PROFILES,
375
- defaults: DEFAULTS,
376
- postures: COMPLIANCE_POSTURES,
318
+ base: 512,
377
319
  integrationFixtures: INTEGRATION_FIXTURES,
378
- validate: validate,
379
- sanitize: sanitize,
320
+ detect: _detectIssues,
321
+ sanitizeTransform: _sanitizeTransform,
322
+ intOpts: ["maxBytes"],
380
323
  gate: gate,
381
324
  });
package/lib/guard-cidr.js CHANGED
@@ -43,11 +43,9 @@
43
43
  * CIDR identifier-safety primitive (KIND="identifier").
44
44
  */
45
45
 
46
- var codepointClass = require("./codepoint-class");
47
46
  var lazyRequire = require("./lazy-require");
48
47
  var gateContract = require("./gate-contract");
49
48
  var C = require("./constants");
50
- var numericBounds = require("./numeric-bounds");
51
49
  var safeBuffer = require("./safe-buffer");
52
50
  var { GuardCidrError } = require("./framework-error");
53
51
 
@@ -102,10 +100,7 @@ var IPV6_RESERVED = Object.freeze([
102
100
 
103
101
  var PROFILES = Object.freeze({
104
102
  "strict": {
105
- bidiPolicy: "reject",
106
- controlPolicy: "reject",
107
- nullBytePolicy: "reject",
108
- zeroWidthPolicy: "reject",
103
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
109
104
  networkAlignmentPolicy: "reject",
110
105
  reservedRangesPolicy: "reject",
111
106
  ipv4MappedIpv6Policy: "reject",
@@ -115,10 +110,7 @@ var PROFILES = Object.freeze({
115
110
  maxRuntimeMs: C.TIME.seconds(2),
116
111
  },
117
112
  "balanced": {
118
- bidiPolicy: "reject",
119
- controlPolicy: "reject",
120
- nullBytePolicy: "reject",
121
- zeroWidthPolicy: "reject",
113
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
122
114
  networkAlignmentPolicy: "audit",
123
115
  reservedRangesPolicy: "audit",
124
116
  ipv4MappedIpv6Policy: "audit",
@@ -128,10 +120,7 @@ var PROFILES = Object.freeze({
128
120
  maxRuntimeMs: C.TIME.seconds(2),
129
121
  },
130
122
  "permissive": {
131
- bidiPolicy: "reject", // BIDI refused at every profile
132
- controlPolicy: "reject", // controls refused at every profile
133
- nullBytePolicy: "reject", // null refused at every profile
134
- zeroWidthPolicy: "reject", // zero-width refused at every profile
123
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
135
124
  networkAlignmentPolicy: "audit",
136
125
  reservedRangesPolicy: "allow",
137
126
  ipv4MappedIpv6Policy: "allow",
@@ -142,35 +131,6 @@ var PROFILES = Object.freeze({
142
131
  },
143
132
  });
144
133
 
145
- var DEFAULTS = Object.freeze(Object.assign({}, PROFILES["strict"], {
146
- mode: "enforce",
147
- }));
148
-
149
- var COMPLIANCE_POSTURES = Object.freeze({
150
- "hipaa": Object.assign({}, PROFILES["strict"], {
151
- forensicSnippetBytes: C.BYTES.bytes(128),
152
- }),
153
- "pci-dss": Object.assign({}, PROFILES["strict"], {
154
- forensicSnippetBytes: C.BYTES.bytes(128),
155
- }),
156
- "gdpr": Object.assign({}, PROFILES["balanced"], {
157
- forensicSnippetBytes: C.BYTES.bytes(64),
158
- }),
159
- "soc2": Object.assign({}, PROFILES["strict"], {
160
- forensicSnippetBytes: C.BYTES.bytes(256),
161
- }),
162
- });
163
-
164
- function _resolveOpts(opts) {
165
- return gateContract.resolveProfileAndPosture(opts, {
166
- profiles: PROFILES,
167
- compliancePostures: COMPLIANCE_POSTURES,
168
- defaults: DEFAULTS,
169
- errorClass: GuardCidrError,
170
- errCodePrefix: "cidr",
171
- });
172
- }
173
-
174
134
  // ---- Parsers ----
175
135
 
176
136
  function _parseIpv4(s) {
@@ -284,25 +244,9 @@ function _ipv6InReservedRange(groups, prefix) {
284
244
  // ---- Detection ----
285
245
 
286
246
  function _detectIssues(input, opts) {
287
- var issues = [];
288
- if (typeof input !== "string") {
289
- return [{ kind: "bad-input", severity: "high",
290
- ruleId: "cidr.bad-input",
291
- snippet: "cidr is not a string" }];
292
- }
293
- if (input.length === 0) {
294
- return [{ kind: "empty", severity: "high",
295
- ruleId: "cidr.empty",
296
- snippet: "cidr is empty" }];
297
- }
298
- if (Buffer.byteLength(input, "utf8") > opts.maxBytes) {
299
- return [{ kind: "cidr-cap", severity: "high",
300
- ruleId: "cidr.cidr-cap",
301
- snippet: "cidr input exceeds maxBytes " + opts.maxBytes }];
302
- }
303
-
304
- var charThreats = codepointClass.detectCharThreats(input, opts, "cidr");
305
- for (var ci = 0; ci < charThreats.length; ci += 1) issues.push(charThreats[ci]);
247
+ var pre = gateContract.detectStringInput(input, opts, { name: "cidr", cap: { bytes: opts.maxBytes } });
248
+ if (pre.done) return pre.issues;
249
+ var issues = pre.issues;
306
250
 
307
251
  // Split address from mask.
308
252
  var slashAt = input.indexOf("/");
@@ -464,21 +408,10 @@ function _detectIssues(input, opts) {
464
408
  * var clean = b.guardCidr.validate("8.8.8.0/24", { profile: "strict" });
465
409
  * clean.ok; // → true
466
410
  */
467
- function validate(input, opts) {
468
- opts = _resolveOpts(opts);
469
- numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
470
- ["maxBytes"],
471
- "guardCidr.validate", GuardCidrError, "cidr.bad-opt");
472
- if (typeof input !== "string") {
473
- return {
474
- ok: false,
475
- issues: [{ kind: "bad-input", severity: "high",
476
- ruleId: "cidr.bad-input",
477
- snippet: "cidr is not a string" }],
478
- };
479
- }
480
- return gateContract.aggregateIssues(_detectIssues(input, opts));
481
- }
411
+ // validate is assembled by gateContract.defineGuard from `detect`
412
+ // (_detectIssues) below — `validate(input, opts) = aggregateIssues(detect(
413
+ // input, resolveOpts(opts)))`, with the maxBytes cap declared via `intOpts`.
414
+ // The @primitive block above documents the resulting public ABI.
482
415
 
483
416
  /**
484
417
  * @primitive b.guardCidr.sanitize
@@ -505,13 +438,10 @@ function validate(input, opts) {
505
438
  * var v4 = b.guardCidr.sanitize("8.8.8.0/24", { profile: "strict" });
506
439
  * v4; // → "8.8.8.0/24"
507
440
  */
508
- function sanitize(input, opts) {
509
- opts = _resolveOpts(opts);
510
- if (typeof input !== "string") {
511
- throw _err("cidr.bad-input", "sanitize requires string input");
512
- }
513
- var issues = _detectIssues(input, opts);
514
- gateContract.throwOnRefusalSeverity(issues, { errorClass: GuardCidrError, codePrefix: "cidr" });
441
+ // _sanitizeTransform the guard-specific normalize applied by defineGuard's
442
+ // generated sanitize AFTER resolve → detect → throw-on-refusal. Input is an
443
+ // already-validated string at this point (a non-string refuses upstream).
444
+ function _sanitizeTransform(input) {
515
445
  // Normalize: lowercase IPv6 groups + canonical mask form.
516
446
  var slashAt = input.indexOf("/");
517
447
  var addr = slashAt === -1 ? input : input.slice(0, slashAt);
@@ -525,14 +455,8 @@ function sanitize(input, opts) {
525
455
  // single-sourced @abiTemplate (defineGuard) blocks in gate-contract.js,
526
456
  // instantiated per guard by the page generator.
527
457
 
528
- var INTEGRATION_FIXTURES = Object.freeze({
529
- kind: "identifier",
530
- benignBytes: Buffer.from("8.8.8.0/24", "utf8"),
531
- hostileBytes: Buffer.from("10.0.0.0/8", "utf8"),
532
- benignIdentifier: "8.8.8.0/24",
533
- // Hostile: RFC 1918 private range — refused at strict.
534
- hostileIdentifier: "10.0.0.0/8",
535
- });
458
+ // Hostile: RFC 1918 private range — refused at strict.
459
+ var INTEGRATION_FIXTURES = gateContract.identifierFixtures("8.8.8.0/24", "10.0.0.0/8");
536
460
 
537
461
  // Assembled from the gate-contract guard factory: error class, registry
538
462
  // exports (NAME / KIND / INTEGRATION_FIXTURES), buildProfile /
@@ -546,10 +470,10 @@ module.exports = gateContract.defineGuard({
546
470
  kind: "identifier",
547
471
  errorClass: GuardCidrError,
548
472
  profiles: PROFILES,
549
- defaults: DEFAULTS,
550
- postures: COMPLIANCE_POSTURES,
473
+ base: 128,
551
474
  integrationFixtures: INTEGRATION_FIXTURES,
552
- validate: validate,
553
- sanitize: sanitize,
475
+ detect: _detectIssues,
476
+ sanitizeTransform: _sanitizeTransform,
477
+ intOpts: ["maxBytes"],
554
478
  ctxFields: ["identifier", "cidr"],
555
479
  });