dd-trace 6.16.0 → 6.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci/diagnose.js +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +165 -0
- package/package.json +17 -16
- package/packages/datadog-esbuild/src/utils.js +0 -2
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +72 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +72 -24
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +16 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +141 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +22 -25
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +51 -12
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -16
- package/packages/datadog-instrumentations/src/playwright.js +238 -55
- package/packages/datadog-instrumentations/src/postgres.js +7 -0
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
- package/packages/datadog-instrumentations/src/webdriverio.js +23 -42
- package/packages/datadog-instrumentations/src/ws.js +0 -1
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
- package/packages/datadog-plugin-cucumber/src/index.js +10 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +13 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +39 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +76 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +10 -0
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-turbopack/index.js +0 -6
- package/packages/datadog-turbopack/src/loader.js +0 -16
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +2 -2
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +73 -67
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +24 -24
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +139 -10
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +40 -14
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +50 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/discovery.js +0 -1
- package/packages/dd-trace/src/evp_proxy/path.js +0 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +0 -2
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +639 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +30 -7
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/index.js +0 -4
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +0 -6
- package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +21 -20
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +21 -45
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
|
@@ -7,6 +7,8 @@ const {
|
|
|
7
7
|
getChatCompletionsOutputMessages,
|
|
8
8
|
getResponsesInputMessages,
|
|
9
9
|
getResponsesOutputMessages,
|
|
10
|
+
getStreamedChatCompletionsOutputMessages,
|
|
11
|
+
getStreamedResponsesOutputMessages,
|
|
10
12
|
} = require('../messages/openai')
|
|
11
13
|
const { decode } = require('../messages/utils')
|
|
12
14
|
const { SOURCE_AUTO } = require('../tags')
|
|
@@ -18,18 +20,21 @@ const responsesInterceptChannel = channel('dd-trace:openai:responses:intercept')
|
|
|
18
20
|
let isEnabled = false
|
|
19
21
|
let aiguard
|
|
20
22
|
let opts
|
|
23
|
+
let analyzeStreamResponses
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Subscribes AI Guard to the OpenAI interception channels.
|
|
24
27
|
*
|
|
25
28
|
* @param {object} aiguardInstance
|
|
26
29
|
* @param {boolean} block
|
|
30
|
+
* @param {boolean} analyzeStreams
|
|
27
31
|
*/
|
|
28
|
-
function enable (aiguardInstance, block) {
|
|
32
|
+
function enable (aiguardInstance, block, analyzeStreams) {
|
|
29
33
|
if (isEnabled) return
|
|
30
34
|
|
|
31
35
|
aiguard = aiguardInstance
|
|
32
36
|
opts = { block, source: SOURCE_AUTO, integration: 'openai' }
|
|
37
|
+
analyzeStreamResponses = analyzeStreams
|
|
33
38
|
|
|
34
39
|
chatCompletionsInterceptChannel.subscribe(onChatCompletions)
|
|
35
40
|
responsesInterceptChannel.subscribe(onResponses)
|
|
@@ -45,6 +50,7 @@ function disable () {
|
|
|
45
50
|
|
|
46
51
|
aiguard = undefined
|
|
47
52
|
opts = undefined
|
|
53
|
+
analyzeStreamResponses = undefined
|
|
48
54
|
isEnabled = false
|
|
49
55
|
}
|
|
50
56
|
|
|
@@ -52,7 +58,6 @@ function onChatCompletions (ctx) {
|
|
|
52
58
|
const inputMessages = getChatCompletionsInputMessages(ctx.arguments?.[0])
|
|
53
59
|
if (!inputMessages?.length) return
|
|
54
60
|
|
|
55
|
-
// `parse` and `asResponse` are both wrapped, and either may run more than once per call.
|
|
56
61
|
let inputEvaluation
|
|
57
62
|
ctx.beforeResult = () => {
|
|
58
63
|
if (!isEnabled) return
|
|
@@ -60,18 +65,27 @@ function onChatCompletions (ctx) {
|
|
|
60
65
|
return inputEvaluation
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
const isStream = ctx.arguments[0].stream
|
|
69
|
+
if (isStream && !analyzeStreamResponses) return
|
|
70
|
+
|
|
64
71
|
let outputEvaluation
|
|
65
72
|
ctx.onResult = body => {
|
|
66
73
|
if (!isEnabled) return body
|
|
67
74
|
|
|
75
|
+
if (isStream) {
|
|
76
|
+
outputEvaluation ??= interceptStream(body, chunks => {
|
|
77
|
+
return getStreamedChatCompletionsOutputMessages(chunks)
|
|
78
|
+
.map(message => [...inputMessages, message])
|
|
79
|
+
}, ctx)
|
|
80
|
+
return outputEvaluation
|
|
81
|
+
}
|
|
82
|
+
|
|
68
83
|
const conversations = decode(
|
|
69
84
|
() => getChatCompletionsOutputMessages(body).map(message => [...inputMessages, message]),
|
|
70
85
|
null,
|
|
71
86
|
'AIGuard: unable to decode OpenAI response body: %s'
|
|
72
87
|
)
|
|
73
|
-
if (conversations
|
|
74
|
-
if (conversations.length === 0) return body
|
|
88
|
+
if (!conversations?.length) return body
|
|
75
89
|
|
|
76
90
|
outputEvaluation ??= evaluate(ctx, aiguard, conversations, opts)
|
|
77
91
|
return outputEvaluation.then(() => body)
|
|
@@ -89,21 +103,81 @@ function onResponses (ctx) {
|
|
|
89
103
|
return inputEvaluation
|
|
90
104
|
}
|
|
91
105
|
|
|
106
|
+
const isStream = ctx.arguments[0].stream
|
|
107
|
+
if (isStream && !analyzeStreamResponses) return
|
|
108
|
+
|
|
92
109
|
let outputEvaluation
|
|
93
110
|
ctx.onResult = body => {
|
|
94
111
|
if (!isEnabled) return body
|
|
95
112
|
|
|
113
|
+
if (isStream) {
|
|
114
|
+
outputEvaluation ??= interceptStream(body, chunks => {
|
|
115
|
+
const outputMessages = getStreamedResponsesOutputMessages(chunks)
|
|
116
|
+
return outputMessages.length ? [[...inputMessages, ...outputMessages]] : []
|
|
117
|
+
}, ctx)
|
|
118
|
+
return outputEvaluation
|
|
119
|
+
}
|
|
120
|
+
|
|
96
121
|
const outputMessages = decode(
|
|
97
122
|
() => getResponsesOutputMessages(body),
|
|
98
123
|
null,
|
|
99
124
|
'AIGuard: unable to decode OpenAI response body: %s'
|
|
100
125
|
)
|
|
101
|
-
if (outputMessages
|
|
102
|
-
if (!outputMessages.length) return body
|
|
126
|
+
if (!outputMessages?.length) return body
|
|
103
127
|
|
|
104
128
|
outputEvaluation ??= evaluate(ctx, aiguard, [[...inputMessages, ...outputMessages]], opts)
|
|
105
129
|
return outputEvaluation.then(() => body)
|
|
106
130
|
}
|
|
107
131
|
}
|
|
108
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Uses the OpenAI SDK's stream splitting support to evaluate one branch and return the other.
|
|
135
|
+
*
|
|
136
|
+
* @param {object} stream
|
|
137
|
+
* @param {(chunks: Array<object>) => Array<Array<object>>} getConversations
|
|
138
|
+
* @param {object} ctx
|
|
139
|
+
* @returns {object|Promise<object>}
|
|
140
|
+
*/
|
|
141
|
+
function interceptStream (stream, getConversations, ctx) {
|
|
142
|
+
if (typeof stream?.tee !== 'function') return stream
|
|
143
|
+
|
|
144
|
+
let branches
|
|
145
|
+
try {
|
|
146
|
+
branches = stream.tee()
|
|
147
|
+
} catch {
|
|
148
|
+
return stream
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [evaluationStream, resultStream] = branches
|
|
152
|
+
return drainStream(evaluationStream).then(chunks => {
|
|
153
|
+
if (!isEnabled) return resultStream
|
|
154
|
+
const conversations = decode(
|
|
155
|
+
() => getConversations(chunks),
|
|
156
|
+
null,
|
|
157
|
+
'AIGuard: unable to decode the streamed OpenAI response: %s'
|
|
158
|
+
)
|
|
159
|
+
if (!conversations?.length) return resultStream
|
|
160
|
+
return evaluate(ctx, aiguard, conversations, opts).then(() => resultStream)
|
|
161
|
+
}, () => resultStream)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @param {object} stream
|
|
166
|
+
* @returns {Promise<Array<object>>}
|
|
167
|
+
*/
|
|
168
|
+
function drainStream (stream) {
|
|
169
|
+
const chunks = []
|
|
170
|
+
const iterator = stream[Symbol.asyncIterator]()
|
|
171
|
+
|
|
172
|
+
function readAll () {
|
|
173
|
+
return iterator.next().then(({ done, value }) => {
|
|
174
|
+
if (done) return chunks
|
|
175
|
+
chunks.push(value)
|
|
176
|
+
return readAll()
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return readAll()
|
|
181
|
+
}
|
|
182
|
+
|
|
109
183
|
module.exports = { enable, disable }
|
|
@@ -220,7 +220,6 @@ function partsToContent (parts, hasImages) {
|
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
222
|
* @param {Array<object>} parts
|
|
223
|
-
* @returns {boolean}
|
|
224
223
|
*/
|
|
225
224
|
function hasImageParts (parts) {
|
|
226
225
|
return parts.some(part => part.type === 'image_url')
|
|
@@ -267,7 +266,6 @@ function convertAnthropicToolResultContent (content) {
|
|
|
267
266
|
|
|
268
267
|
/**
|
|
269
268
|
* @param {unknown} content
|
|
270
|
-
* @returns {string}
|
|
271
269
|
*/
|
|
272
270
|
function convertServerToolResultContent (content) {
|
|
273
271
|
if (typeof content === 'string') return content || '[tool result]'
|
|
@@ -195,6 +195,68 @@ function getResponsesOutputMessages (body) {
|
|
|
195
195
|
return convertOpenAIResponseItemsToMessages(body?.output, 'assistant')
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Combines streamed chat completion deltas into regular output messages.
|
|
200
|
+
*
|
|
201
|
+
* @param {Array<object>} chunks
|
|
202
|
+
* @returns {Array<object>}
|
|
203
|
+
*/
|
|
204
|
+
function getStreamedChatCompletionsOutputMessages (chunks) {
|
|
205
|
+
const messages = new Map()
|
|
206
|
+
|
|
207
|
+
for (const chunk of chunks) {
|
|
208
|
+
if (!Array.isArray(chunk?.choices)) continue
|
|
209
|
+
for (const choice of chunk.choices) {
|
|
210
|
+
const delta = choice.delta
|
|
211
|
+
if (!delta) continue
|
|
212
|
+
|
|
213
|
+
const index = choice.index ?? 0
|
|
214
|
+
const message = messages.get(index) ?? { role: 'assistant' }
|
|
215
|
+
messages.set(index, message)
|
|
216
|
+
|
|
217
|
+
if (typeof delta.role === 'string') message.role = delta.role
|
|
218
|
+
if (typeof delta.content === 'string') message.content = (message.content ?? '') + delta.content
|
|
219
|
+
if (typeof delta.refusal === 'string') message.refusal = (message.refusal ?? '') + delta.refusal
|
|
220
|
+
|
|
221
|
+
if (delta.function_call) {
|
|
222
|
+
const functionCall = message.function_call ??= {}
|
|
223
|
+
functionCall.name ??= delta.function_call.name
|
|
224
|
+
if (typeof delta.function_call.arguments === 'string') {
|
|
225
|
+
functionCall.arguments = (functionCall.arguments ?? '') + delta.function_call.arguments
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!Array.isArray(delta.tool_calls)) continue
|
|
230
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
231
|
+
const toolCalls = message.tool_calls ??= []
|
|
232
|
+
const toolCall = toolCalls[toolCallDelta.index ?? 0] ??= { function: {} }
|
|
233
|
+
toolCall.id ??= toolCallDelta.id
|
|
234
|
+
toolCall.type ??= toolCallDelta.type
|
|
235
|
+
toolCall.function.name ??= toolCallDelta.function?.name
|
|
236
|
+
if (typeof toolCallDelta.function?.arguments === 'string') {
|
|
237
|
+
toolCall.function.arguments = (toolCall.function.arguments ?? '') + toolCallDelta.function.arguments
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const choices = [...messages.values()].map(message => {
|
|
244
|
+
if (message.tool_calls) message.tool_calls = message.tool_calls.filter(Boolean)
|
|
245
|
+
return { message }
|
|
246
|
+
})
|
|
247
|
+
return getChatCompletionsOutputMessages({ choices })
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Gets output messages from the final response snapshot in a Responses API stream.
|
|
252
|
+
*
|
|
253
|
+
* @param {Array<object>} chunks
|
|
254
|
+
* @returns {Array<object>}
|
|
255
|
+
*/
|
|
256
|
+
function getStreamedResponsesOutputMessages (chunks) {
|
|
257
|
+
return getResponsesOutputMessages(chunks.at(-1)?.response)
|
|
258
|
+
}
|
|
259
|
+
|
|
198
260
|
/**
|
|
199
261
|
* Converts one OpenAI reusable prompt variable value to message content.
|
|
200
262
|
*
|
|
@@ -348,7 +410,6 @@ function openAIResponseImageContentPart (part) {
|
|
|
348
410
|
* Extracts a stable text marker from an OpenAI file content part.
|
|
349
411
|
*
|
|
350
412
|
* @param {{file_id?: string|null, file_url?: string, filename?: string, file_data?: string}} part
|
|
351
|
-
* @returns {string}
|
|
352
413
|
*/
|
|
353
414
|
function openAIResponseFileContentPart (part) {
|
|
354
415
|
return part.file_id ?? part.file_url ?? part.filename ?? FILE_FALLBACK
|
|
@@ -362,5 +423,7 @@ module.exports = {
|
|
|
362
423
|
convertOpenAIResponsePromptToMessages,
|
|
363
424
|
getResponsesInputMessages,
|
|
364
425
|
getResponsesOutputMessages,
|
|
426
|
+
getStreamedChatCompletionsOutputMessages,
|
|
427
|
+
getStreamedResponsesOutputMessages,
|
|
365
428
|
openAIResponseContentToMessageContent,
|
|
366
429
|
}
|
|
@@ -49,7 +49,6 @@ function parsePath (path) {
|
|
|
49
49
|
* Reports whether a parsed path targets an allowed message string.
|
|
50
50
|
*
|
|
51
51
|
* @param {Array<{ name: string, index: number|undefined }>} segments
|
|
52
|
-
* @returns {boolean}
|
|
53
52
|
*/
|
|
54
53
|
function isRedactablePath (segments) {
|
|
55
54
|
const first = segments[0]
|
|
@@ -30,7 +30,7 @@ class AIGuard extends NoopAIGuard {
|
|
|
30
30
|
this.#tracer = tracer
|
|
31
31
|
this.#client = new AIGuardClient(config)
|
|
32
32
|
this.#reporter = new EvaluationReporter(config)
|
|
33
|
-
this.#redactionEnabled = config.
|
|
33
|
+
this.#redactionEnabled = config.aiguard.DD_AI_GUARD_REDACTION_ENABLED
|
|
34
34
|
this.#meta = { service: config.service, env: config.env }
|
|
35
35
|
this.#initialized = true
|
|
36
36
|
}
|
|
@@ -215,7 +215,6 @@ function compileRoute (route, parse, makeMatcher) {
|
|
|
215
215
|
* @param {number} g
|
|
216
216
|
* @param {Map<number, number>} groupParent
|
|
217
217
|
* @param {Set<number>} present
|
|
218
|
-
* @returns {boolean}
|
|
219
218
|
*/
|
|
220
219
|
function groupActive (g, groupParent, present) {
|
|
221
220
|
while (g !== 0) {
|
|
@@ -229,7 +228,6 @@ function groupActive (g, groupParent, present) {
|
|
|
229
228
|
* URL-encode chars outside the RFC-1103 static alphabet [A-Za-z0-9.-~_]. The 'u' flag iterates whole
|
|
230
229
|
* codepoints so surrogate pairs encode as correct multi-byte UTF-8.
|
|
231
230
|
* @param {string} str
|
|
232
|
-
* @returns {string}
|
|
233
231
|
*/
|
|
234
232
|
function encodeStaticSegment (str) {
|
|
235
233
|
return str.replaceAll(/[^A-Za-z0-9.\-~_]/gu, c => {
|
|
@@ -246,7 +244,6 @@ function encodeStaticSegment (str) {
|
|
|
246
244
|
/**
|
|
247
245
|
* URL-encode the 6 characters not allowed in a normalized param name (/?#+{}).
|
|
248
246
|
* @param {string} name
|
|
249
|
-
* @returns {string}
|
|
250
247
|
*/
|
|
251
248
|
function encodeParamName (name) {
|
|
252
249
|
return name.replaceAll(/[/?#+{}]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'))
|
|
@@ -256,7 +253,6 @@ function encodeParamName (name) {
|
|
|
256
253
|
* Render the normalized route for a given set of present optional groups.
|
|
257
254
|
* @param {CompiledRoute} compiled
|
|
258
255
|
* @param {Set<number>} present
|
|
259
|
-
* @returns {string}
|
|
260
256
|
*/
|
|
261
257
|
function renderRoute (compiled, present) {
|
|
262
258
|
const { segments, groupParent } = compiled
|
|
@@ -367,7 +363,6 @@ function resolvePresence (compiled, params) {
|
|
|
367
363
|
* Stable bitmask key for a present-group set (group ids are small, route-local).
|
|
368
364
|
* @param {number[]} optionalGroups
|
|
369
365
|
* @param {Set<number>} present
|
|
370
|
-
* @returns {number}
|
|
371
366
|
*/
|
|
372
367
|
function presenceBitmask (optionalGroups, present) {
|
|
373
368
|
let mask = 0
|
|
@@ -122,7 +122,6 @@ function sampleRequest (req, res, record = false) {
|
|
|
122
122
|
*
|
|
123
123
|
* @param {string|undefined} route
|
|
124
124
|
* @param {boolean} record
|
|
125
|
-
* @returns {boolean}
|
|
126
125
|
*/
|
|
127
126
|
function isRoutelessRecord (route, record) {
|
|
128
127
|
return record && route === undefined
|
|
@@ -130,7 +129,6 @@ function isRoutelessRecord (route, record) {
|
|
|
130
129
|
|
|
131
130
|
/**
|
|
132
131
|
* @param {number|string} statusCode
|
|
133
|
-
* @returns {boolean}
|
|
134
132
|
*/
|
|
135
133
|
function isNotFound (statusCode) {
|
|
136
134
|
return Number(statusCode) === 404
|
|
@@ -141,7 +139,6 @@ function isNotFound (statusCode) {
|
|
|
141
139
|
* @param {string|undefined} route A route string, an empty string (still a valid route), or
|
|
142
140
|
* `undefined`
|
|
143
141
|
* @param {number|string} statusCode
|
|
144
|
-
* @returns {string}
|
|
145
142
|
*/
|
|
146
143
|
function buildSamplingKey (method, route, statusCode) {
|
|
147
144
|
return method + (route ?? '') + statusCode
|
|
@@ -176,7 +173,6 @@ function getRouteOrEndpoint (context, statusCode) {
|
|
|
176
173
|
* regardless of the APM sampling decision.
|
|
177
174
|
*
|
|
178
175
|
* @param {DatadogSpan} rootSpan
|
|
179
|
-
* @returns {boolean}
|
|
180
176
|
*/
|
|
181
177
|
function isRejected (rootSpan) {
|
|
182
178
|
if (asmStandaloneEnabled) return false
|
|
@@ -204,9 +204,9 @@ function handleResults (actions, req, res, rootSpan, abortController) {
|
|
|
204
204
|
* @param {import('../../config/config-base')} [config] - Tracer configuration
|
|
205
205
|
*/
|
|
206
206
|
function setTemplates (config) {
|
|
207
|
-
templates.html.body = config?.appsec?.
|
|
208
|
-
templates.json.body = config?.appsec?.
|
|
209
|
-
templates.graphqlJson.body = config?.appsec?.
|
|
207
|
+
templates.html.body = config?.appsec?.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
|
|
208
|
+
templates.json.body = config?.appsec?.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
|
|
209
|
+
templates.graphqlJson.body = config?.appsec?.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON
|
|
210
210
|
|
|
211
211
|
for (const type of Object.keys(templates)) {
|
|
212
212
|
const template = templates[type]
|
|
@@ -102,7 +102,6 @@ function recordResponseBodyIgnored (req, tag) {
|
|
|
102
102
|
/**
|
|
103
103
|
* @param {import('http').IncomingMessage} originatingReq inbound request (for metrics).
|
|
104
104
|
* @param {import('http').IncomingMessage} res downstream response.
|
|
105
|
-
* @returns {boolean} whether downstream response body should be collected for AppSec.
|
|
106
105
|
*/
|
|
107
106
|
function evaluateResponseBodyCollection (originatingReq, res) {
|
|
108
107
|
const maxBytes = config.appsec.DD_API_SECURITY_MAX_DOWNSTREAM_BODY_BYTES
|
|
@@ -131,7 +130,6 @@ function evaluateResponseBodyCollection (originatingReq, res) {
|
|
|
131
130
|
* Probabilistic gate for downstream response body capture (rate + per-request cap).
|
|
132
131
|
* Only used from {@link planResponseBodyCollection}; does not increment {@link bodyAnalysisCount}.
|
|
133
132
|
* @param {import('http').IncomingMessage} req originating server request.
|
|
134
|
-
* @returns {boolean}
|
|
135
133
|
*/
|
|
136
134
|
function shouldSampleBody (req) {
|
|
137
135
|
globalRequestCounter = (globalRequestCounter + 1n) & UINT64_MAX
|
|
@@ -150,7 +148,6 @@ function shouldSampleBody (req) {
|
|
|
150
148
|
|
|
151
149
|
/**
|
|
152
150
|
* @param {import('http').IncomingMessage} res downstream HTTP response.
|
|
153
|
-
* @returns {boolean}
|
|
154
151
|
*/
|
|
155
152
|
function isRedirectResponse (res) {
|
|
156
153
|
const location = res.headers?.location || ''
|
|
@@ -271,7 +268,6 @@ function incrementDownstreamAnalysisCount (req) {
|
|
|
271
268
|
/**
|
|
272
269
|
* Returns the HTTP method to use for a downstream request, defaulting to GET.
|
|
273
270
|
* @param {string} method method supplied in the outgoing request options.
|
|
274
|
-
* @returns {string} validated HTTP method.
|
|
275
271
|
*/
|
|
276
272
|
function getMethod (method) {
|
|
277
273
|
return typeof method === 'string' && method ? method : 'GET'
|
|
@@ -351,6 +347,7 @@ module.exports = {
|
|
|
351
347
|
disable,
|
|
352
348
|
planResponseBodyCollection,
|
|
353
349
|
incrementDownstreamAnalysisCount,
|
|
350
|
+
extractMimeType,
|
|
354
351
|
extractRequestData,
|
|
355
352
|
extractResponseData,
|
|
356
353
|
}
|
|
@@ -31,7 +31,7 @@ let isEnabled = false
|
|
|
31
31
|
function enable (config, _tracer) {
|
|
32
32
|
if (isEnabled) return
|
|
33
33
|
|
|
34
|
-
iastTelemetry.configure(config, config.iast?.
|
|
34
|
+
iastTelemetry.configure(config, config.iast?.DD_IAST_TELEMETRY_VERBOSITY)
|
|
35
35
|
enableFsPlugin(IAST_MODULE)
|
|
36
36
|
enableAllAnalyzers(config)
|
|
37
37
|
enableTaintTracking(config.iast, iastTelemetry.verbosity)
|
|
@@ -73,7 +73,7 @@ const OPERATIONS = {
|
|
|
73
73
|
},
|
|
74
74
|
name: REPORT_VULNERABILITY,
|
|
75
75
|
initialTokenBucketSize () {
|
|
76
|
-
return typeof config.
|
|
76
|
+
return typeof config.DD_IAST_MAX_CONTEXT_OPERATIONS === 'number' ? config.DD_IAST_MAX_CONTEXT_OPERATIONS : 2
|
|
77
77
|
},
|
|
78
78
|
initContext: function (context) {
|
|
79
79
|
context.tokens[REPORT_VULNERABILITY] = this.initialTokenBucketSize()
|
|
@@ -146,8 +146,8 @@ function _resetGlobalContext () {
|
|
|
146
146
|
|
|
147
147
|
function acquireRequest (rootSpan) {
|
|
148
148
|
if (availableRequest > 0 && rootSpan) {
|
|
149
|
-
const sampling = config && typeof config.
|
|
150
|
-
? config.
|
|
149
|
+
const sampling = config && typeof config.DD_IAST_REQUEST_SAMPLING === 'number'
|
|
150
|
+
? config.DD_IAST_REQUEST_SAMPLING
|
|
151
151
|
: 30
|
|
152
152
|
if (rootSpan.context().toSpanId().slice(-2) <= sampling) {
|
|
153
153
|
availableRequest--
|
|
@@ -158,7 +158,7 @@ function acquireRequest (rootSpan) {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
function releaseRequest () {
|
|
161
|
-
if (availableRequest < config.
|
|
161
|
+
if (availableRequest < config.DD_IAST_MAX_CONCURRENT_REQUESTS) {
|
|
162
162
|
availableRequest++
|
|
163
163
|
}
|
|
164
164
|
}
|
|
@@ -174,7 +174,7 @@ function initializeRequestContext (iastContext) {
|
|
|
174
174
|
|
|
175
175
|
function configure (cfg) {
|
|
176
176
|
config = cfg
|
|
177
|
-
availableRequest = config.
|
|
177
|
+
availableRequest = config.DD_IAST_MAX_CONCURRENT_REQUESTS
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
function startGlobalContext () {
|
|
@@ -20,7 +20,7 @@ module.exports = {
|
|
|
20
20
|
kafkaContextPlugin.enable(config)
|
|
21
21
|
kafkaConsumerPlugin.enable(config)
|
|
22
22
|
|
|
23
|
-
setMaxTransactions(config.
|
|
23
|
+
setMaxTransactions(config.DD_IAST_MAX_CONCURRENT_REQUESTS)
|
|
24
24
|
},
|
|
25
25
|
disableTaintTracking () {
|
|
26
26
|
disableTaintOperations()
|
|
@@ -30,7 +30,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
|
|
|
30
30
|
configure (config) {
|
|
31
31
|
super.configure(config)
|
|
32
32
|
|
|
33
|
-
let rowsToTaint = this.iastConfig?.
|
|
33
|
+
let rowsToTaint = this.iastConfig?.DD_IAST_DB_ROWS_TO_TAINT
|
|
34
34
|
if (typeof rowsToTaint !== 'number') {
|
|
35
35
|
rowsToTaint = 1
|
|
36
36
|
}
|
|
@@ -97,7 +97,7 @@ function getPrepareStackTraceAccessor () {
|
|
|
97
97
|
|
|
98
98
|
function getCompileMethodFn (compileMethod) {
|
|
99
99
|
let delegate = function (content, filename) {
|
|
100
|
-
if (isDdTrace(filename) || !isPrivateModule(filename) || !config.iast?.
|
|
100
|
+
if (isDdTrace(filename) || !isPrivateModule(filename) || !config.iast?.DD_IAST_ENABLED) {
|
|
101
101
|
return compileMethod.apply(this, [content, filename])
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -163,7 +163,7 @@ function shimPrepareStackTrace () {
|
|
|
163
163
|
|
|
164
164
|
function enableRewriter (telemetryVerbosity) {
|
|
165
165
|
try {
|
|
166
|
-
if (config.iast?.
|
|
166
|
+
if (config.iast?.DD_IAST_ENABLED) {
|
|
167
167
|
const rewriter = getRewriter(telemetryVerbosity)
|
|
168
168
|
if (rewriter) {
|
|
169
169
|
shimPrepareStackTrace()
|
|
@@ -218,7 +218,7 @@ let enableEsmRewriter = function (telemetryVerbosity) {
|
|
|
218
218
|
telemetryVerbosity,
|
|
219
219
|
chainSourceMap: isFlagPresent('--enable-source-maps'),
|
|
220
220
|
orchestrionConfig,
|
|
221
|
-
iastEnabled: config?.iast?.
|
|
221
|
+
iastEnabled: config?.iast?.DD_IAST_ENABLED,
|
|
222
222
|
},
|
|
223
223
|
})
|
|
224
224
|
} catch (e) {
|
|
@@ -114,11 +114,10 @@ function digitRunEnd (value, from, length) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
117
|
+
* Returns the end of a plain integer or decimal literal, or `-1` to delegate exponents and radix literals to `NUMERIC`.
|
|
118
118
|
* @param {string} value
|
|
119
119
|
* @param {number} intEnd Index after the integer digit run measured by the caller.
|
|
120
120
|
* @param {number} length
|
|
121
|
-
* @returns {number} Index after the literal, or `-1` to defer to the `NUMERIC` regex.
|
|
122
121
|
*/
|
|
123
122
|
function scanPlainNumber (value, intEnd, length) {
|
|
124
123
|
// A digit run touching `x`/`b` is a radix prefix (`0x`, `0b`) — let the regex own it.
|
|
@@ -177,7 +176,6 @@ const FALL_THROUGH = -2 // not a literal start -> advance one character and reco
|
|
|
177
176
|
* @param {string} value
|
|
178
177
|
* @param {number} from
|
|
179
178
|
* @param {number} length
|
|
180
|
-
* @returns {number} Index of the first line terminator at or after `from`, else `length`.
|
|
181
179
|
*/
|
|
182
180
|
function lineEnd (value, from, length) {
|
|
183
181
|
for (let i = from; i < length; i++) {
|
|
@@ -196,7 +194,6 @@ function lineEnd (value, from, length) {
|
|
|
196
194
|
* @param {number} quote Char code of the opening delimiter, `'` or `"`.
|
|
197
195
|
* @param {boolean} conservativeBackslash Whether an odd backslash before a closing quote makes the
|
|
198
196
|
* remainder ambiguous and therefore unterminated.
|
|
199
|
-
* @returns {number} Index after the closing quote, or `UNTERMINATED`.
|
|
200
197
|
*/
|
|
201
198
|
function scanQuotedDoubled (value, start, length, quote, conservativeBackslash) {
|
|
202
199
|
let backslashCount = 0
|
|
@@ -229,7 +226,6 @@ function scanQuotedDoubled (value, start, length, quote, conservativeBackslash)
|
|
|
229
226
|
* @param {number} length
|
|
230
227
|
* @param {number} quote Char code of the opening delimiter, `'` or `"`.
|
|
231
228
|
* @param {boolean} doubled Whether two adjacent quotes escape each other.
|
|
232
|
-
* @returns {number} Index after the closing quote, or `UNTERMINATED`.
|
|
233
229
|
*/
|
|
234
230
|
function scanQuotedBackslash (value, start, length, quote, doubled) {
|
|
235
231
|
for (let i = start + 1; i < length; i++) {
|
|
@@ -269,12 +265,13 @@ function isPostgresEscapeString (value, quoteIndex) {
|
|
|
269
265
|
/**
|
|
270
266
|
* Oracle `q'X…X'`: `X` is one of `< ( { [` (closed by its mirror) or any other char (closed by
|
|
271
267
|
* itself). The body may span line terminators.
|
|
268
|
+
* The result is the index after the closing `X'`.
|
|
269
|
+
* It is `FALL_THROUGH` when `q'` ends the value or is followed by a line terminator.
|
|
270
|
+
* Oracle forbids whitespace as the delimiter, so this case is a plain string instead of a quote opener.
|
|
271
|
+
* It is `UNTERMINATED` when no closing delimiter exists.
|
|
272
272
|
* @param {string} value
|
|
273
273
|
* @param {number} start
|
|
274
274
|
* @param {number} length
|
|
275
|
-
* @returns {number} Index after the closing `X'`; `FALL_THROUGH` when `q'` is at the end of the value
|
|
276
|
-
* or followed by a line terminator — Oracle forbids whitespace as the delimiter, so that `'` is a
|
|
277
|
-
* plain string, not a quote opener; or `UNTERMINATED`.
|
|
278
275
|
*/
|
|
279
276
|
function scanOracleQuote (value, start, length) {
|
|
280
277
|
const delimiter = value.charCodeAt(start + 2)
|
|
@@ -294,11 +291,12 @@ function scanOracleQuote (value, start, length) {
|
|
|
294
291
|
* Postgres `$tag$ … $tag$`, where `tag` is empty or an identifier. The body may span line
|
|
295
292
|
* terminators — PL/pgSQL function bodies routinely do, and treating a newline as the end of the
|
|
296
293
|
* literal would leave the rest of a multi-line body unredacted.
|
|
294
|
+
* The result is the index after the closing tag.
|
|
295
|
+
* It is `FALL_THROUGH` when no second `$` exists.
|
|
296
|
+
* It is `UNTERMINATED` when the opening tag is malformed or has no close.
|
|
297
297
|
* @param {string} value
|
|
298
298
|
* @param {number} start
|
|
299
299
|
* @param {number} length
|
|
300
|
-
* @returns {number} Index after the closing tag; `FALL_THROUGH` when no second `$` exists; or
|
|
301
|
-
* `UNTERMINATED` when the opening tag is malformed or has no close.
|
|
302
300
|
*/
|
|
303
301
|
function scanDollarQuote (value, start, length) {
|
|
304
302
|
const tagEnd = value.indexOf('$', start + 1)
|
|
@@ -24,8 +24,8 @@ const MAX_EVIDENCE_LENGTH = 32_768
|
|
|
24
24
|
|
|
25
25
|
class SensitiveHandler {
|
|
26
26
|
constructor () {
|
|
27
|
-
this._namePattern = new RegExp(/** @type {string} */ (defaults['iast.
|
|
28
|
-
this._valuePattern = new RegExp(/** @type {string} */ (defaults['iast.
|
|
27
|
+
this._namePattern = new RegExp(/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_NAME_PATTERN']), 'gmi')
|
|
28
|
+
this._valuePattern = new RegExp(/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_VALUE_PATTERN']), 'gmi')
|
|
29
29
|
|
|
30
30
|
this._sensitiveAnalyzers = new Map()
|
|
31
31
|
this._sensitiveAnalyzers.set(vulnerabilities.CODE_INJECTION, taintedRangeBasedSensitiveAnalyzer)
|
|
@@ -13,7 +13,10 @@ const REGEX_FOR_STRINGIFY_SENSITIVE_NOT_STRING = new RegExp(String.raw`"${STRING
|
|
|
13
13
|
const REGEX_FOR_STRINGIFY_SENSITIVE = new RegExp(String.raw`${STRINGIFY_SENSITIVE_KEY}_\d+_(\d+)_`)
|
|
14
14
|
const REGEX_FOR_STRINGIFY_RANGE = new RegExp(String.raw`(${STRINGIFY_RANGE_KEY}_\d+_)`)
|
|
15
15
|
|
|
16
|
-
const sensitiveValueRegex = new RegExp(
|
|
16
|
+
const sensitiveValueRegex = new RegExp(
|
|
17
|
+
/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_VALUE_PATTERN']),
|
|
18
|
+
'gmi'
|
|
19
|
+
)
|
|
17
20
|
|
|
18
21
|
function iterateObject (target, fn, levelKeys = [], depth = 10, visited = new Set()) {
|
|
19
22
|
for (const key of Object.keys(target)) {
|
|
@@ -138,15 +138,15 @@ function replaceCallSiteFromSourceMap (callsite) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
function start (config, _tracer) {
|
|
141
|
-
deduplicationEnabled = config.iast.
|
|
142
|
-
stackTraceEnabled = config.iast.
|
|
143
|
-
stackTraceMaxDepth = config.appsec.
|
|
144
|
-
maxStackTraces = config.appsec.
|
|
141
|
+
deduplicationEnabled = config.iast.DD_IAST_DEDUPLICATION_ENABLED
|
|
142
|
+
stackTraceEnabled = config.iast.DD_IAST_STACK_TRACE_ENABLED
|
|
143
|
+
stackTraceMaxDepth = config.appsec.DD_APPSEC_MAX_STACK_TRACE_DEPTH
|
|
144
|
+
maxStackTraces = config.appsec.DD_APPSEC_MAX_STACK_TRACES
|
|
145
145
|
|
|
146
146
|
vulnerabilitiesFormatter.setRedactVulnerabilities(
|
|
147
|
-
config.iast.
|
|
148
|
-
config.iast.
|
|
149
|
-
config.iast.
|
|
147
|
+
config.iast.DD_IAST_REDACTION_ENABLED,
|
|
148
|
+
config.iast.DD_IAST_REDACTION_NAME_PATTERN,
|
|
149
|
+
config.iast.DD_IAST_REDACTION_VALUE_PATTERN
|
|
150
150
|
)
|
|
151
151
|
if (deduplicationEnabled) {
|
|
152
152
|
startClearCacheTimer()
|
|
@@ -87,7 +87,7 @@ function enable (_config) {
|
|
|
87
87
|
appsecTelemetry.enable(_config)
|
|
88
88
|
graphql.enable()
|
|
89
89
|
|
|
90
|
-
if (_config.appsec.
|
|
90
|
+
if (_config.appsec.DD_APPSEC_RASP_ENABLED) {
|
|
91
91
|
rasp.enable(_config)
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -101,7 +101,7 @@ function enable (_config) {
|
|
|
101
101
|
|
|
102
102
|
apiSecurity.configure(_config)
|
|
103
103
|
|
|
104
|
-
UserTracking.setCollectionMode(_config.appsec.
|
|
104
|
+
UserTracking.setCollectionMode(_config.appsec.DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE, false)
|
|
105
105
|
|
|
106
106
|
httpRequest.setConfig(_config)
|
|
107
107
|
|