@blamejs/blamejs-shop 0.4.31 → 0.4.32
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/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +392 -278
- package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
- package/lib/vendor/blamejs/.gitignore +6 -0
- package/lib/vendor/blamejs/CHANGELOG.md +26 -0
- package/lib/vendor/blamejs/MIGRATING.md +43 -0
- package/lib/vendor/blamejs/README.md +8 -6
- package/lib/vendor/blamejs/SECURITY.md +19 -3
- package/lib/vendor/blamejs/api-snapshot.json +2190 -664
- package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
- package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
- package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
- package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
- package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
- package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
- package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
- package/lib/vendor/blamejs/index.js +4 -0
- package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
- package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
- package/lib/vendor/blamejs/lib/api-key.js +158 -77
- package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
- package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
- package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
- package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
- package/lib/vendor/blamejs/lib/audit.js +259 -123
- package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
- package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
- package/lib/vendor/blamejs/lib/backup/index.js +45 -10
- package/lib/vendor/blamejs/lib/break-glass.js +355 -147
- package/lib/vendor/blamejs/lib/cache.js +174 -105
- package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
- package/lib/vendor/blamejs/lib/cli.js +19 -14
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
- package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
- package/lib/vendor/blamejs/lib/cluster.js +119 -71
- package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
- package/lib/vendor/blamejs/lib/compliance.js +206 -4
- package/lib/vendor/blamejs/lib/consent.js +82 -29
- package/lib/vendor/blamejs/lib/constants.js +27 -11
- package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
- package/lib/vendor/blamejs/lib/db-query.js +882 -260
- package/lib/vendor/blamejs/lib/db-schema.js +228 -44
- package/lib/vendor/blamejs/lib/db.js +249 -99
- package/lib/vendor/blamejs/lib/dsr.js +385 -55
- package/lib/vendor/blamejs/lib/error-page.js +14 -1
- package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
- package/lib/vendor/blamejs/lib/external-db.js +549 -34
- package/lib/vendor/blamejs/lib/file-upload.js +52 -7
- package/lib/vendor/blamejs/lib/framework-error.js +20 -1
- package/lib/vendor/blamejs/lib/framework-files.js +73 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
- package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
- package/lib/vendor/blamejs/lib/guard-all.js +1 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
- package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
- package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
- package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
- package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
- package/lib/vendor/blamejs/lib/guard-email.js +47 -69
- package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
- package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
- package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
- package/lib/vendor/blamejs/lib/guard-html.js +53 -108
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
- package/lib/vendor/blamejs/lib/guard-image.js +46 -103
- package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
- package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
- package/lib/vendor/blamejs/lib/guard-json.js +38 -108
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
- package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
- package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
- package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
- package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
- package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
- package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
- package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
- package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
- package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
- package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
- package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
- package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
- package/lib/vendor/blamejs/lib/guard-template.js +35 -172
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-time.js +32 -154
- package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
- package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
- package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
- package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
- package/lib/vendor/blamejs/lib/http-client.js +37 -9
- package/lib/vendor/blamejs/lib/inbox.js +120 -107
- package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
- package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
- package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
- package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
- package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
- package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
- package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
- package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
- package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
- package/lib/vendor/blamejs/lib/mail-store.js +293 -154
- package/lib/vendor/blamejs/lib/mail.js +8 -4
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
- package/lib/vendor/blamejs/lib/migrations.js +108 -66
- package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
- package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
- package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
- package/lib/vendor/blamejs/lib/observability.js +124 -0
- package/lib/vendor/blamejs/lib/otel-export.js +12 -3
- package/lib/vendor/blamejs/lib/outbox.js +184 -83
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
- package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
- package/lib/vendor/blamejs/lib/queue-local.js +225 -140
- package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
- package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
- package/lib/vendor/blamejs/lib/queue.js +7 -0
- package/lib/vendor/blamejs/lib/redact.js +68 -11
- package/lib/vendor/blamejs/lib/redis-client.js +160 -31
- package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
- package/lib/vendor/blamejs/lib/retention.js +101 -40
- package/lib/vendor/blamejs/lib/router.js +212 -5
- package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
- package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
- package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
- package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
- package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
- package/lib/vendor/blamejs/lib/safe-url.js +170 -3
- package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
- package/lib/vendor/blamejs/lib/scheduler.js +35 -12
- package/lib/vendor/blamejs/lib/seeders.js +122 -74
- package/lib/vendor/blamejs/lib/session-stores.js +42 -14
- package/lib/vendor/blamejs/lib/session.js +175 -77
- package/lib/vendor/blamejs/lib/sql.js +3842 -0
- package/lib/vendor/blamejs/lib/sse.js +26 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
- package/lib/vendor/blamejs/lib/static.js +177 -34
- package/lib/vendor/blamejs/lib/subject.js +96 -49
- package/lib/vendor/blamejs/lib/vault/index.js +3 -2
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
- package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
- package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
- package/lib/vendor/blamejs/lib/websocket.js +35 -5
- package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
- package/lib/vendor/blamejs/package.json +2 -2
- package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
- package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
- package/lib/vendor/blamejs/scripts/check-services.js +21 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
- package/lib/vendor/blamejs/scripts/release.js +398 -38
- package/lib/vendor/blamejs/test/00-primitives.js +117 -0
- package/lib/vendor/blamejs/test/10-state.js +140 -14
- package/lib/vendor/blamejs/test/20-db.js +65 -2
- package/lib/vendor/blamejs/test/helpers/db.js +9 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
- package/lib/vendor/blamejs/test/helpers/services.js +21 -0
- package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
- package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
- package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
- package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
- package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
- package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
- package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
- package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
- package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
- package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
- package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
- package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
- package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
- package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
- package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
- package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
- package/lib/vendor/blamejs/test/smoke.js +79 -21
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
- package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
- package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
- package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
- package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
- package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
- package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
- package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
- package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
- package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
- package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
- package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
- package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
- package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
- package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
- package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fuzz target: b.guardSql (validate / sanitize)
|
|
4
|
+
*
|
|
5
|
+
* Targets the raw-SQL guard's tokenizer-first contract: the encoding
|
|
6
|
+
* gate (string / Buffer-or-refuse), the comment-strip + literal-mask
|
|
7
|
+
* normalizer, and the injection / exfil / OS-reach detector pipeline.
|
|
8
|
+
*
|
|
9
|
+
* validate() must NEVER throw on arbitrary bytes - it classifies and
|
|
10
|
+
* returns { ok, issues }; any throw out of it is a finding. sanitize()
|
|
11
|
+
* refuses unrepairable input with GuardSqlError (code prefix "sql.").
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
var b = require("..");
|
|
15
|
+
var expected = require("./_expected");
|
|
16
|
+
|
|
17
|
+
function expectedRefusal(e) {
|
|
18
|
+
if (expected.isExpected(e)) return true;
|
|
19
|
+
if (e && typeof e.code === "string" && e.code.indexOf("sql.") === 0) return true;
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports.fuzz = function (data) {
|
|
24
|
+
// No-throw classification contract (default + strict profiles).
|
|
25
|
+
b.guardSql.validate(data);
|
|
26
|
+
b.guardSql.validate(data, { profile: "strict" });
|
|
27
|
+
|
|
28
|
+
// Refusal path: sanitize throws GuardSqlError on hostile / unrepairable
|
|
29
|
+
// input; anything else is an unexpected crash.
|
|
30
|
+
try {
|
|
31
|
+
b.guardSql.sanitize(data);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
if (expectedRefusal(e)) return;
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -120,6 +120,7 @@ var clusterStorage = require("./lib/cluster-storage");
|
|
|
120
120
|
var safeAsync = require("./lib/safe-async");
|
|
121
121
|
var handlers = require("./lib/handlers");
|
|
122
122
|
var safeSql = require("./lib/safe-sql");
|
|
123
|
+
var sql = require("./lib/sql");
|
|
123
124
|
var chainWriter = require("./lib/chain-writer");
|
|
124
125
|
var safeBuffer = require("./lib/safe-buffer");
|
|
125
126
|
var safeDecompress = require("./lib/safe-decompress").safeDecompress;
|
|
@@ -181,6 +182,7 @@ var guardSvg = require("./lib/guard-svg");
|
|
|
181
182
|
var guardFilename = require("./lib/guard-filename");
|
|
182
183
|
var guardMessageId = require("./lib/guard-message-id");
|
|
183
184
|
var guardSmtpCommand = require("./lib/guard-smtp-command");
|
|
185
|
+
var guardSql = require("./lib/guard-sql");
|
|
184
186
|
var guardImapCommand = require("./lib/guard-imap-command");
|
|
185
187
|
var guardPop3Command = require("./lib/guard-pop3-command");
|
|
186
188
|
var guardManageSieveCommand = require("./lib/guard-managesieve-command");
|
|
@@ -520,6 +522,7 @@ module.exports = {
|
|
|
520
522
|
safeAsync: safeAsync,
|
|
521
523
|
handlers: handlers,
|
|
522
524
|
safeSql: safeSql,
|
|
525
|
+
sql: sql,
|
|
523
526
|
chainWriter: chainWriter,
|
|
524
527
|
safeBuffer: safeBuffer,
|
|
525
528
|
safeDecompress: safeDecompress,
|
|
@@ -569,6 +572,7 @@ module.exports = {
|
|
|
569
572
|
guardFilename: guardFilename,
|
|
570
573
|
guardMessageId: guardMessageId,
|
|
571
574
|
guardSmtpCommand: guardSmtpCommand,
|
|
575
|
+
guardSql: guardSql,
|
|
572
576
|
guardImapCommand: guardImapCommand,
|
|
573
577
|
guardPop3Command: guardPop3Command,
|
|
574
578
|
guardManageSieveCommand: guardManageSieveCommand,
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* b.agent._envelopeMac — internal shared keyed-MAC mechanism for
|
|
4
|
+
* authenticating agent cross-process envelopes (`b.agent.postureChain`
|
|
5
|
+
* delegation envelopes, `b.agent.eventBus` wire envelopes, and any
|
|
6
|
+
* future agent boundary that carries security-relevant fields over a
|
|
7
|
+
* shared transport).
|
|
8
|
+
*
|
|
9
|
+
* The threat is uniform across these boundaries: an attacker with write
|
|
10
|
+
* access to the shared transport (queue / pubsub) can forge or tamper an
|
|
11
|
+
* envelope's authority-bearing fields — posture set, tenant id, topic —
|
|
12
|
+
* because schema/shape validation alone proves nothing about
|
|
13
|
+
* authenticity. The defense is a keyed MAC (HMAC-SHA3-512) over the
|
|
14
|
+
* canonical bytes of exactly those fields, keyed off the vault master so
|
|
15
|
+
* an attacker without the vault key cannot forge it and a vault rotation
|
|
16
|
+
* invalidates every in-flight MAC.
|
|
17
|
+
*
|
|
18
|
+
* Each calling domain supplies a stable `label` (domain separation) and
|
|
19
|
+
* the canonical bytes of the fields it protects; the key derivation,
|
|
20
|
+
* HMAC construction, and constant-time comparison live here so there is
|
|
21
|
+
* a single mechanism to audit, not one per agent module.
|
|
22
|
+
*
|
|
23
|
+
* Internal — operator-facing surface is each primitive's envelope
|
|
24
|
+
* sign/verify behaviour; this is the implementation detail.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
var nodeCrypto = require("node:crypto");
|
|
28
|
+
var lazyRequire = require("./lazy-require");
|
|
29
|
+
var { defineClass } = require("./framework-error");
|
|
30
|
+
var bCrypto = require("./crypto");
|
|
31
|
+
|
|
32
|
+
var vault = lazyRequire(function () { return require("./vault"); });
|
|
33
|
+
|
|
34
|
+
var AgentEnvelopeMacError = defineClass("AgentEnvelopeMacError", { alwaysPermanent: true });
|
|
35
|
+
|
|
36
|
+
var ENVELOPE_MAC_KEY_BYTES = 32; // HMAC-SHA3-512 keyed bytes
|
|
37
|
+
|
|
38
|
+
// Per-label memoized keys — each domain-separation label derives its own
|
|
39
|
+
// sub-key from the vault master so a MAC minted for one boundary can
|
|
40
|
+
// never validate on another. Memoization is process-local; a vault
|
|
41
|
+
// rotation implies an operator restart (which clears the cache).
|
|
42
|
+
var _macKeyCache = Object.create(null);
|
|
43
|
+
|
|
44
|
+
// Resolve (and memoize) the MAC sub-key for a domain-separation `label`,
|
|
45
|
+
// derived from the vault master. Throws when the vault is not
|
|
46
|
+
// initialized — there is no key to authenticate with, so callers MUST
|
|
47
|
+
// treat that as fail-closed for any cross-tenant / authority decision
|
|
48
|
+
// rather than proceeding unauthenticated.
|
|
49
|
+
function resolveKey(label) {
|
|
50
|
+
if (typeof label !== "string" || label.length === 0) {
|
|
51
|
+
throw new AgentEnvelopeMacError("agent-envelope-mac/bad-label",
|
|
52
|
+
"resolveKey: label must be a non-empty string");
|
|
53
|
+
}
|
|
54
|
+
if (_macKeyCache[label]) return _macKeyCache[label];
|
|
55
|
+
var v;
|
|
56
|
+
try { v = vault(); } catch (_e) { v = null; }
|
|
57
|
+
if (!v || typeof v.getKeysJson !== "function") {
|
|
58
|
+
throw new AgentEnvelopeMacError("agent-envelope-mac/vault-not-initialized",
|
|
59
|
+
"envelope MAC: vault must be initialized before agent envelopes can be authenticated " +
|
|
60
|
+
"(operator wires b.vault.init() at boot)");
|
|
61
|
+
}
|
|
62
|
+
var keysJson;
|
|
63
|
+
try { keysJson = v.getKeysJson(); }
|
|
64
|
+
catch (e) {
|
|
65
|
+
throw new AgentEnvelopeMacError("agent-envelope-mac/vault-not-initialized",
|
|
66
|
+
"envelope MAC: vault.getKeysJson threw — " + (e && e.message ? e.message : String(e)));
|
|
67
|
+
}
|
|
68
|
+
var rootBytes = Buffer.from(bCrypto.sha3Hash(keysJson), "hex");
|
|
69
|
+
var input = Buffer.concat([
|
|
70
|
+
Buffer.from(label, "utf8"),
|
|
71
|
+
Buffer.from([0x00]),
|
|
72
|
+
rootBytes,
|
|
73
|
+
]);
|
|
74
|
+
_macKeyCache[label] = bCrypto.kdf(input, ENVELOPE_MAC_KEY_BYTES);
|
|
75
|
+
return _macKeyCache[label];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Compute the base64 HMAC-SHA3-512 of `canonicalBytes` under the
|
|
79
|
+
// `label`'s vault-derived sub-key.
|
|
80
|
+
function sign(label, canonicalBytes) {
|
|
81
|
+
var key = resolveKey(label);
|
|
82
|
+
return nodeCrypto.createHmac("sha3-512", key).update(canonicalBytes).digest().toString("base64");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Constant-time verify that `mac` (base64) is the correct HMAC for
|
|
86
|
+
// `canonicalBytes` under the `label`'s sub-key. Returns false for a
|
|
87
|
+
// missing / malformed `mac`; propagates AgentEnvelopeMacError from
|
|
88
|
+
// resolveKey when the vault is absent so the caller fails closed rather
|
|
89
|
+
// than treating a missing key as a verification pass.
|
|
90
|
+
function verify(label, canonicalBytes, mac) {
|
|
91
|
+
if (typeof mac !== "string" || mac.length === 0) return false;
|
|
92
|
+
var expected = sign(label, canonicalBytes);
|
|
93
|
+
return bCrypto.timingSafeEqual(mac, expected);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
resolveKey: resolveKey,
|
|
98
|
+
sign: sign,
|
|
99
|
+
verify: verify,
|
|
100
|
+
AgentEnvelopeMacError: AgentEnvelopeMacError,
|
|
101
|
+
ENVELOPE_MAC_KEY_BYTES: ENVELOPE_MAC_KEY_BYTES,
|
|
102
|
+
// Test-only — flush the memoized per-label MAC keys after a vault reset.
|
|
103
|
+
_resetForTest: function () { _macKeyCache = Object.create(null); },
|
|
104
|
+
};
|
|
@@ -67,11 +67,25 @@ var { defineClass } = require("./framework-error");
|
|
|
67
67
|
var guardEventBusTopic = require("./guard-event-bus-topic");
|
|
68
68
|
var guardEventBusPayload = require("./guard-event-bus-payload");
|
|
69
69
|
var agentAudit = require("./agent-audit");
|
|
70
|
+
var envelopeMac = require("./agent-envelope-mac");
|
|
71
|
+
var safeJson = require("./safe-json");
|
|
72
|
+
var bCrypto = require("./crypto");
|
|
70
73
|
|
|
71
74
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
72
75
|
|
|
73
76
|
var AgentEventBusError = defineClass("AgentEventBusError", { alwaysPermanent: true });
|
|
74
77
|
|
|
78
|
+
// Wire-envelope authentication. An attacker with pubsub write access can
|
|
79
|
+
// set _tenantId to a victim subscriber's tenant + a schema-valid payload
|
|
80
|
+
// and forge a cross-tenant event; the tenant/posture/schema checks at the
|
|
81
|
+
// consumer prove SHAPE, not authenticity. Defense is a keyed MAC over the
|
|
82
|
+
// envelope's authority-bearing fields, minted at publish and verified at
|
|
83
|
+
// the consumer BEFORE the tenant/schema checks. The key derivation +
|
|
84
|
+
// HMAC live in the shared b.agent.envelopeMac mechanism (one keyed-MAC
|
|
85
|
+
// mechanism for every agent boundary); this label domain-separates the
|
|
86
|
+
// event-bus MAC from the posture-chain MAC.
|
|
87
|
+
var ENVELOPE_MAC_LABEL = "blamejs.agent.eventBus/v1";
|
|
88
|
+
|
|
75
89
|
/**
|
|
76
90
|
* @primitive b.agent.eventBus.create
|
|
77
91
|
* @signature b.agent.eventBus.create(opts)
|
|
@@ -88,6 +102,7 @@ var AgentEventBusError = defineClass("AgentEventBusError", { alwaysPermanent: tr
|
|
|
88
102
|
* pubsub: { publish, subscribe, unsubscribe }, // required
|
|
89
103
|
* audit: b.audit namespace, // optional
|
|
90
104
|
* permissions: b.permissions instance, // optional
|
|
105
|
+
* requireMac: boolean, // default: true — keyed-MAC envelope auth; false only for single-process unit tests with no vault
|
|
91
106
|
*
|
|
92
107
|
* @example
|
|
93
108
|
* var bus = b.agent.eventBus.create({ pubsub: myPubsub });
|
|
@@ -109,12 +124,18 @@ function create(opts) {
|
|
|
109
124
|
var auditImpl = opts.audit || audit();
|
|
110
125
|
var permissions = opts.permissions || null;
|
|
111
126
|
var topics = new Map();
|
|
127
|
+
// Envelope MAC (M6): default ON. Only single-process unit tests with no
|
|
128
|
+
// vault should opt out. When off, the cross-tenant MAC gate is bypassed
|
|
129
|
+
// and that is audit-visible at publish + delivery; production /
|
|
130
|
+
// multi-process / queue-spanning deployments leave the default so a
|
|
131
|
+
// pubsub-write attacker can't forge a cross-tenant event.
|
|
132
|
+
var requireMac = opts.requireMac !== false;
|
|
112
133
|
|
|
113
134
|
return {
|
|
114
135
|
registerTopic: function (name, topicOpts) { return _registerTopic(topics, name, topicOpts || {}, auditImpl); },
|
|
115
136
|
unregisterTopic: function (name) { return _unregisterTopic(topics, name, auditImpl); },
|
|
116
|
-
publish: function (name, payload, pOpts) { return _publish(topics, opts.pubsub, name, payload, pOpts || {}, permissions, auditImpl); },
|
|
117
|
-
subscribe: function (name, handler, sOpts) { return _subscribe(topics, opts.pubsub, name, handler, sOpts || {}, permissions, auditImpl); },
|
|
137
|
+
publish: function (name, payload, pOpts) { return _publish(topics, opts.pubsub, name, payload, pOpts || {}, permissions, auditImpl, requireMac); },
|
|
138
|
+
subscribe: function (name, handler, sOpts) { return _subscribe(topics, opts.pubsub, name, handler, sOpts || {}, permissions, auditImpl, requireMac); },
|
|
118
139
|
listTopics: function (args) { return _listTopics(topics, args || {}, permissions); },
|
|
119
140
|
AgentEventBusError: AgentEventBusError,
|
|
120
141
|
guards: {
|
|
@@ -201,7 +222,30 @@ function _listTopics(topics, args, permissions) {
|
|
|
201
222
|
|
|
202
223
|
// ---- Publish --------------------------------------------------------------
|
|
203
224
|
|
|
204
|
-
|
|
225
|
+
// Canonical bytes the MAC covers: _topic, _tenantId, _posture,
|
|
226
|
+
// _publishedAt, and a hash of the payload (so the payload can't be
|
|
227
|
+
// swapped without invalidating the MAC, without copying the whole
|
|
228
|
+
// payload into the signed preimage). Field set matches the consumer's
|
|
229
|
+
// authority decision inputs. Built as an ordered [key,value] tuple list
|
|
230
|
+
// so the canonical preimage is stable regardless of source key order.
|
|
231
|
+
function _macField(value, kind) {
|
|
232
|
+
if (kind === "string") return typeof value === "string" ? value : null;
|
|
233
|
+
if (kind === "number") return typeof value === "number" ? value : null;
|
|
234
|
+
return value === undefined ? null : value; // pass-through (posture)
|
|
235
|
+
}
|
|
236
|
+
function _envelopeMacBytes(wrapped) {
|
|
237
|
+
var payloadForHash = wrapped.payload === undefined ? null : wrapped.payload;
|
|
238
|
+
var tuples = [
|
|
239
|
+
["_topic", _macField(wrapped._topic, "string")],
|
|
240
|
+
["_tenantId", _macField(wrapped._tenantId, "string")],
|
|
241
|
+
["_posture", _macField(wrapped._posture, "any")],
|
|
242
|
+
["_publishedAt", _macField(wrapped._publishedAt, "number")],
|
|
243
|
+
["payloadHash", bCrypto.sha3Hash(safeJson.canonical(payloadForHash))],
|
|
244
|
+
];
|
|
245
|
+
return Buffer.from(safeJson.canonical(tuples), "utf8");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function _publish(topics, pubsub, name, payload, pOpts, permissions, auditImpl, requireMac) {
|
|
205
249
|
guardEventBusTopic.validate(name);
|
|
206
250
|
var entry = topics.get(name);
|
|
207
251
|
if (!entry) {
|
|
@@ -256,6 +300,32 @@ async function _publish(topics, pubsub, name, payload, pOpts, permissions, audit
|
|
|
256
300
|
_publishedAt: Date.now(),
|
|
257
301
|
payload: payload,
|
|
258
302
|
};
|
|
303
|
+
// Authenticate the envelope's authority-bearing fields with a keyed MAC
|
|
304
|
+
// (M6). The consumer verifies this BEFORE the tenant/schema checks, so a
|
|
305
|
+
// pubsub-write attacker can't forge a cross-tenant event. If the vault
|
|
306
|
+
// isn't initialized there's no key to mint with — fail closed at publish
|
|
307
|
+
// (requireMac default) rather than emit an unauthenticatable envelope
|
|
308
|
+
// onto the bus. requireMac:false is the single-process unit-test escape
|
|
309
|
+
// hatch and is audit-visible.
|
|
310
|
+
try {
|
|
311
|
+
wrapped._mac = envelopeMac.sign(ENVELOPE_MAC_LABEL, _envelopeMacBytes(wrapped));
|
|
312
|
+
} catch (e) {
|
|
313
|
+
if (requireMac) {
|
|
314
|
+
_safeAudit(auditImpl, "agent.event_bus.publish_denied", pOpts.actor || null, {
|
|
315
|
+
topic: name, reason: "envelope-mac-unavailable",
|
|
316
|
+
});
|
|
317
|
+
throw new AgentEventBusError("agent-event-bus/envelope-mac-unavailable",
|
|
318
|
+
"publish: cannot authenticate the event envelope — " +
|
|
319
|
+
((e && e.message) || String(e)) +
|
|
320
|
+
" (vault must be initialized so the bus MAC key is derivable, or " +
|
|
321
|
+
"set requireMac:false for single-process unit tests)");
|
|
322
|
+
}
|
|
323
|
+
// Escape hatch: no key + requireMac disabled → emit unauthenticated.
|
|
324
|
+
wrapped._mac = null;
|
|
325
|
+
_safeAudit(auditImpl, "agent.event_bus.mac_bypassed", pOpts.actor || null, {
|
|
326
|
+
topic: name, reason: "require-mac-disabled", phase: "publish",
|
|
327
|
+
});
|
|
328
|
+
}
|
|
259
329
|
await pubsub.publish(name, wrapped);
|
|
260
330
|
_safeAudit(auditImpl, "agent.event_bus.published", pOpts.actor, {
|
|
261
331
|
topic: name, posture: entry.posture,
|
|
@@ -265,7 +335,7 @@ async function _publish(topics, pubsub, name, payload, pOpts, permissions, audit
|
|
|
265
335
|
|
|
266
336
|
// ---- Subscribe ------------------------------------------------------------
|
|
267
337
|
|
|
268
|
-
async function _subscribe(topics, pubsub, name, handler, sOpts, permissions, auditImpl) {
|
|
338
|
+
async function _subscribe(topics, pubsub, name, handler, sOpts, permissions, auditImpl, requireMac) {
|
|
269
339
|
guardEventBusTopic.validate(name);
|
|
270
340
|
var entry = topics.get(name);
|
|
271
341
|
if (!entry) {
|
|
@@ -320,6 +390,37 @@ async function _subscribe(topics, pubsub, name, handler, sOpts, permissions, aud
|
|
|
320
390
|
{ topic: name, reason: "malformed-envelope" });
|
|
321
391
|
return;
|
|
322
392
|
}
|
|
393
|
+
// Envelope authentication FIRST (M6): verify the keyed MAC over the
|
|
394
|
+
// authority-bearing fields (_topic / _tenantId / _posture /
|
|
395
|
+
// _publishedAt / payload-hash) BEFORE trusting _tenantId / _posture
|
|
396
|
+
// for any routing or schema decision. A pubsub-write attacker who
|
|
397
|
+
// forges _tenantId (cross-tenant routing) or tampers _posture / the
|
|
398
|
+
// payload produces a MAC mismatch and the delivery drops. If the
|
|
399
|
+
// vault key is unavailable, verify() throws — we fail CLOSED (drop),
|
|
400
|
+
// never deliver an unauthenticatable envelope cross-tenant.
|
|
401
|
+
// requireMac:false is the single-process unit-test escape hatch and
|
|
402
|
+
// is audit-visible.
|
|
403
|
+
if (requireMac) {
|
|
404
|
+
var macOk = false;
|
|
405
|
+
try {
|
|
406
|
+
macOk = envelopeMac.verify(ENVELOPE_MAC_LABEL, _envelopeMacBytes(wrapped), wrapped._mac);
|
|
407
|
+
} catch (_e) {
|
|
408
|
+
macOk = false;
|
|
409
|
+
}
|
|
410
|
+
if (!macOk) {
|
|
411
|
+
_safeAudit(auditImpl, "agent.event_bus.cross_tenant_drop", sOpts.actor, {
|
|
412
|
+
topic: name,
|
|
413
|
+
publisherTenant: typeof wrapped._tenantId === "string" ? wrapped._tenantId : null,
|
|
414
|
+
subscriberTenant: subscriberTenant,
|
|
415
|
+
reason: "envelope-mac-invalid",
|
|
416
|
+
});
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
} else {
|
|
420
|
+
_safeAudit(auditImpl, "agent.event_bus.mac_bypassed", sOpts.actor, {
|
|
421
|
+
topic: name, reason: "require-mac-disabled", phase: "delivery",
|
|
422
|
+
});
|
|
423
|
+
}
|
|
323
424
|
// Tenant-scope check: subscriber's tenantId must match the
|
|
324
425
|
// publisher's tenantId from the wire envelope. If the envelope
|
|
325
426
|
// lacks _tenantId (publisher omitted), that's a tampered or
|
|
@@ -51,15 +51,13 @@
|
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
53
|
var lazyRequire = require("./lazy-require");
|
|
54
|
-
var nodeCrypto = require("node:crypto");
|
|
55
54
|
var { defineClass } = require("./framework-error");
|
|
56
55
|
var guardPostureChain = require("./guard-posture-chain");
|
|
57
56
|
var agentAudit = require("./agent-audit");
|
|
58
57
|
var safeJson = require("./safe-json");
|
|
59
|
-
var
|
|
58
|
+
var envelopeMac = require("./agent-envelope-mac");
|
|
60
59
|
|
|
61
60
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
62
|
-
var vault = lazyRequire(function () { return require("./vault"); });
|
|
63
61
|
|
|
64
62
|
var AgentPostureChainError = defineClass("AgentPostureChainError", { alwaysPermanent: true });
|
|
65
63
|
|
|
@@ -70,44 +68,16 @@ var BUILTIN_REGIMES = Object.freeze(["hipaa", "pci-dss", "gdpr", "soc2"]);
|
|
|
70
68
|
// strips postureSet to [] and re-sends a saga / sub-agent envelope
|
|
71
69
|
// can bypass the downgrade refusal in _validate (which only checks
|
|
72
70
|
// SHAPE, not authenticity). Defense is a keyed MAC over the canonical
|
|
73
|
-
// envelope bytes, computed at appendHop and verified at validate.
|
|
71
|
+
// envelope bytes, computed at appendHop and verified at validate. The
|
|
72
|
+
// key derivation + HMAC construction live in the shared
|
|
73
|
+
// b.agent.envelopeMac mechanism (one keyed-MAC mechanism for every
|
|
74
|
+
// agent boundary); this label domain-separates the posture-chain MAC.
|
|
74
75
|
var ENVELOPE_MAC_LABEL = "blamejs.agent.postureChain/v1";
|
|
75
|
-
var ENVELOPE_MAC_KEY_BYTES = 32; // HMAC-SHA3-512 keyed bytes
|
|
76
76
|
// Hop count cap defends infinite recursion across
|
|
77
77
|
// agent delegation. 16 is the spec default; operators can lower via
|
|
78
78
|
// opts.maxHopCount but never raise (audit fan-out without a cap is a
|
|
79
79
|
// DoS class).
|
|
80
80
|
var DEFAULT_MAX_HOP_COUNT = 16; // hop count cap
|
|
81
|
-
var _macKeyCache = null; // memoized per-vault-master key
|
|
82
|
-
|
|
83
|
-
function _resolveMacKey() {
|
|
84
|
-
// Lazy derivation keyed off the vault master. Operator rotating
|
|
85
|
-
// vault keys invalidates every in-flight MAC — desired property.
|
|
86
|
-
// Memoization is process-local; if vault rotates within the same
|
|
87
|
-
// process the operator restarts (vault rotation already implies it).
|
|
88
|
-
if (_macKeyCache) return _macKeyCache;
|
|
89
|
-
var v;
|
|
90
|
-
try { v = vault(); } catch (_e) { v = null; }
|
|
91
|
-
if (!v || typeof v.getKeysJson !== "function") {
|
|
92
|
-
throw new AgentPostureChainError("agent-posture-chain/vault-not-initialized",
|
|
93
|
-
"envelope MAC: vault must be initialized before posture-chain envelopes can be authenticated " +
|
|
94
|
-
"(operator wires b.vault.init() at boot)");
|
|
95
|
-
}
|
|
96
|
-
var keysJson;
|
|
97
|
-
try { keysJson = v.getKeysJson(); }
|
|
98
|
-
catch (e) {
|
|
99
|
-
throw new AgentPostureChainError("agent-posture-chain/vault-not-initialized",
|
|
100
|
-
"envelope MAC: vault.getKeysJson threw — " + (e && e.message ? e.message : String(e)));
|
|
101
|
-
}
|
|
102
|
-
var rootBytes = Buffer.from(bCrypto.sha3Hash(keysJson), "hex");
|
|
103
|
-
var input = Buffer.concat([
|
|
104
|
-
Buffer.from(ENVELOPE_MAC_LABEL, "utf8"),
|
|
105
|
-
Buffer.from([0x00]),
|
|
106
|
-
rootBytes,
|
|
107
|
-
]);
|
|
108
|
-
_macKeyCache = bCrypto.kdf(input, ENVELOPE_MAC_KEY_BYTES);
|
|
109
|
-
return _macKeyCache;
|
|
110
|
-
}
|
|
111
81
|
|
|
112
82
|
function _envelopeMacBytes(envelope) {
|
|
113
83
|
// Sign every field that downstream consumers verify off the wire,
|
|
@@ -124,15 +94,11 @@ function _envelopeMacBytes(envelope) {
|
|
|
124
94
|
}
|
|
125
95
|
|
|
126
96
|
function _signEnvelope(envelope) {
|
|
127
|
-
|
|
128
|
-
var mac = nodeCrypto.createHmac("sha3-512", key).update(_envelopeMacBytes(envelope)).digest();
|
|
129
|
-
return mac.toString("base64");
|
|
97
|
+
return envelopeMac.sign(ENVELOPE_MAC_LABEL, _envelopeMacBytes(envelope));
|
|
130
98
|
}
|
|
131
99
|
|
|
132
100
|
function _verifyEnvelopeMac(envelope) {
|
|
133
|
-
|
|
134
|
-
var expected = _signEnvelope(envelope);
|
|
135
|
-
return bCrypto.timingSafeEqual(envelope._mac, expected);
|
|
101
|
+
return envelopeMac.verify(ENVELOPE_MAC_LABEL, _envelopeMacBytes(envelope), envelope._mac);
|
|
136
102
|
}
|
|
137
103
|
|
|
138
104
|
/**
|
|
@@ -362,5 +328,5 @@ module.exports = {
|
|
|
362
328
|
chain: guardPostureChain,
|
|
363
329
|
},
|
|
364
330
|
// Test-only — flush the memoized MAC key after a vault reset.
|
|
365
|
-
_resetForTest: function () {
|
|
331
|
+
_resetForTest: function () { envelopeMac._resetForTest(); },
|
|
366
332
|
};
|
|
@@ -43,6 +43,7 @@ var lazyRequire = require("./lazy-require");
|
|
|
43
43
|
var contentCredentials = lazyRequire(function () { return require("./content-credentials"); });
|
|
44
44
|
var audit = require("./audit");
|
|
45
45
|
var { defineClass } = require("./framework-error");
|
|
46
|
+
var gateContract = require("./gate-contract");
|
|
46
47
|
|
|
47
48
|
var AiContentDetectError = defineClass("AiContentDetectError", { alwaysPermanent: true });
|
|
48
49
|
|
|
@@ -64,16 +65,14 @@ var COMPLIANCE_POSTURES = Object.freeze({
|
|
|
64
65
|
"nist-ai-rmf": "balanced",
|
|
65
66
|
});
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return PROFILES[DEFAULT_PROFILE];
|
|
76
|
-
}
|
|
68
|
+
var _resolveProfile = gateContract.makeProfileResolver({
|
|
69
|
+
profiles: PROFILES,
|
|
70
|
+
postures: COMPLIANCE_POSTURES,
|
|
71
|
+
defaults: DEFAULT_PROFILE,
|
|
72
|
+
errorClass: AiContentDetectError,
|
|
73
|
+
codePrefix: "ai-content-detect",
|
|
74
|
+
byObject: true,
|
|
75
|
+
});
|
|
77
76
|
|
|
78
77
|
/**
|
|
79
78
|
* @primitive b.ai.aiContentDetect.report
|