dd-trace 5.57.1 → 5.58.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.
Files changed (56) hide show
  1. package/LICENSE-3rdparty.csv +2 -1
  2. package/init.js +1 -4
  3. package/package.json +6 -4
  4. package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
  5. package/packages/datadog-instrumentations/src/child_process.js +1 -1
  6. package/packages/datadog-instrumentations/src/graphql.js +9 -0
  7. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  8. package/packages/datadog-instrumentations/src/jest.js +1 -1
  9. package/packages/datadog-instrumentations/src/mysql2.js +6 -6
  10. package/packages/datadog-instrumentations/src/next.js +3 -1
  11. package/packages/datadog-instrumentations/src/oracledb.js +24 -2
  12. package/packages/datadog-instrumentations/src/tedious.js +12 -17
  13. package/packages/datadog-plugin-aws-sdk/src/base.js +51 -1
  14. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  15. package/packages/datadog-plugin-cypress/src/support.js +19 -25
  16. package/packages/datadog-plugin-graphql/src/tools/index.js +0 -2
  17. package/packages/datadog-plugin-graphql/src/tools/signature.js +0 -2
  18. package/packages/datadog-plugin-graphql/src/tools/transforms.js +0 -2
  19. package/packages/datadog-plugin-http/src/client.js +3 -4
  20. package/packages/datadog-plugin-http2/src/client.js +9 -8
  21. package/packages/datadog-plugin-langchain/src/handlers/chain.js +1 -1
  22. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +1 -1
  23. package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +1 -1
  24. package/packages/datadog-plugin-oracledb/src/connection-parser.js +35 -0
  25. package/packages/datadog-plugin-oracledb/src/index.js +15 -17
  26. package/packages/datadog-plugin-tedious/src/index.js +10 -9
  27. package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +6 -4
  28. package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +9 -0
  29. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +5 -2
  30. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -0
  31. package/packages/dd-trace/src/appsec/reporter.js +61 -7
  32. package/packages/dd-trace/src/appsec/rule_manager.js +63 -171
  33. package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -5
  34. package/packages/dd-trace/src/appsec/telemetry/common.js +1 -1
  35. package/packages/dd-trace/src/appsec/telemetry/index.js +8 -0
  36. package/packages/dd-trace/src/appsec/telemetry/waf.js +5 -3
  37. package/packages/dd-trace/src/appsec/waf/diagnostics.js +15 -0
  38. package/packages/dd-trace/src/appsec/waf/index.js +47 -6
  39. package/packages/dd-trace/src/appsec/waf/waf_manager.js +22 -12
  40. package/packages/dd-trace/src/config.js +11 -4
  41. package/packages/dd-trace/src/constants.js +1 -2
  42. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  43. package/packages/dd-trace/src/heap_snapshots.js +58 -0
  44. package/packages/dd-trace/src/llmobs/noop.js +1 -1
  45. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  46. package/packages/dd-trace/src/log/log.js +1 -1
  47. package/packages/dd-trace/src/opentracing/span.js +1 -1
  48. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  49. package/packages/dd-trace/src/payload-tagging/tagging.js +2 -2
  50. package/packages/dd-trace/src/plugins/outbound.js +7 -0
  51. package/packages/dd-trace/src/profiling/profilers/wall.js +2 -2
  52. package/packages/dd-trace/src/proxy.js +4 -0
  53. package/packages/dd-trace/src/service-naming/schemas/definition.js +2 -9
  54. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +2 -1
  55. package/packages/dd-trace/src/supported-configurations.json +3 -0
  56. package/packages/dd-trace/src/payload-tagging/jsonpath-plus.js +0 -2094
@@ -2,14 +2,26 @@
2
2
 
3
3
  const { storage } = require('../../../../datadog-core')
4
4
  const log = require('../../log')
5
+ const Reporter = require('../reporter')
6
+
7
+ class WafUpdateError extends Error {
8
+ constructor (diagnosticErrors) {
9
+ super('WafUpdateError')
10
+ this.name = 'WafUpdateError'
11
+ this.diagnosticErrors = diagnosticErrors
12
+ }
13
+ }
5
14
 
6
15
  const waf = {
7
16
  wafManager: null,
8
17
  init,
9
18
  destroy,
10
- update,
19
+ updateConfig,
20
+ removeConfig,
21
+ checkAsmDdFallback,
11
22
  run: noop,
12
- disposeContext: noop
23
+ disposeContext: noop,
24
+ WafUpdateError
13
25
  }
14
26
 
15
27
  function init (rules, config) {
@@ -34,14 +46,43 @@ function destroy () {
34
46
  waf.disposeContext = noop
35
47
  }
36
48
 
37
- function update (newRules) {
38
- // TODO: check race conditions between Appsec enable/disable and WAF updates, the whole RC state management in general
49
+ function checkAsmDdFallback () {
50
+ if (!waf.wafManager) throw new Error('Cannot update disabled WAF')
51
+
52
+ try {
53
+ waf.wafManager.setAsmDdFallbackConfig()
54
+ } catch {
55
+ log.error('[ASM] Could not apply default ruleset back as fallback')
56
+ }
57
+ }
58
+
59
+ function updateConfig (product, configId, configPath, config) {
60
+ if (!waf.wafManager) throw new Error('Cannot update disabled WAF')
61
+
62
+ try {
63
+ if (product === 'ASM_DD') {
64
+ waf.wafManager.removeConfig(waf.wafManager.constructor.defaultWafConfigPath)
65
+ }
66
+
67
+ const updateSucceeded = waf.wafManager.updateConfig(configPath, config)
68
+ Reporter.reportWafConfigUpdate(product, configId, waf.wafManager.ddwaf.diagnostics, waf.wafManager.ddwafVersion)
69
+
70
+ if (!updateSucceeded) {
71
+ throw new WafUpdateError(waf.wafManager.ddwaf.diagnostics)
72
+ }
73
+ } catch (err) {
74
+ log.error('[ASM] Could not update config from RC')
75
+ throw err
76
+ }
77
+ }
78
+
79
+ function removeConfig (configPath) {
39
80
  if (!waf.wafManager) throw new Error('Cannot update disabled WAF')
40
81
 
41
82
  try {
42
- waf.wafManager.update(newRules)
83
+ waf.wafManager.removeConfig(configPath)
43
84
  } catch (err) {
44
- log.error('[ASM] Could not apply rules from remote config')
85
+ log.error('[ASM] Could not remove config from RC')
45
86
  throw err
46
87
  }
47
88
  }
@@ -7,11 +7,14 @@ const WAFContextWrapper = require('./waf_context_wrapper')
7
7
  const contexts = new WeakMap()
8
8
 
9
9
  class WAFManager {
10
+ static get defaultWafConfigPath () { return 'datadog/00/ASM_DD/default/config' }
11
+
10
12
  constructor (rules, config) {
11
13
  this.config = config
12
14
  this.wafTimeout = config.wafTimeout
13
15
  this.ddwaf = this._loadDDWAF(rules)
14
16
  this.rulesVersion = this.ddwaf.diagnostics.ruleset_version
17
+ this.defaultRules = rules
15
18
 
16
19
  Reporter.reportWafInit(this.ddwafVersion, this.rulesVersion, this.ddwaf.diagnostics.rules, true)
17
20
  }
@@ -23,7 +26,7 @@ class WAFManager {
23
26
  this.ddwafVersion = DDWAF.version()
24
27
 
25
28
  const { obfuscatorKeyRegex, obfuscatorValueRegex } = this.config
26
- return new DDWAF(rules, { obfuscatorKeyRegex, obfuscatorValueRegex })
29
+ return new DDWAF(rules, WAFManager.defaultWafConfigPath, { obfuscatorKeyRegex, obfuscatorValueRegex })
27
30
  } catch (err) {
28
31
  this.ddwafVersion = this.ddwafVersion || 'unknown'
29
32
  Reporter.reportWafInit(this.ddwafVersion, 'unknown')
@@ -51,20 +54,27 @@ class WAFManager {
51
54
  return wafContext
52
55
  }
53
56
 
54
- update (newRules) {
55
- try {
56
- this.ddwaf.update(newRules)
57
+ setRulesVersion () {
58
+ if (this.ddwaf.diagnostics.ruleset_version) {
59
+ this.rulesVersion = this.ddwaf.diagnostics.ruleset_version
60
+ }
61
+ }
57
62
 
58
- if (this.ddwaf.diagnostics.ruleset_version) {
59
- this.rulesVersion = this.ddwaf.diagnostics.ruleset_version
60
- }
63
+ setAsmDdFallbackConfig () {
64
+ if (!this.ddwaf.configPaths.some(cp => cp.includes('ASM_DD'))) {
65
+ this.updateConfig(WAFManager.defaultWafConfigPath, this.defaultRules)
66
+ }
67
+ }
61
68
 
62
- Reporter.reportWafUpdate(this.ddwafVersion, this.rulesVersion, true)
63
- } catch (error) {
64
- Reporter.reportWafUpdate(this.ddwafVersion, 'unknown', false)
69
+ updateConfig (path, rules) {
70
+ const updateResult = this.ddwaf.createOrUpdateConfig(rules, path)
71
+ this.setRulesVersion()
72
+ return updateResult
73
+ }
65
74
 
66
- throw error
67
- }
75
+ removeConfig (path) {
76
+ this.ddwaf.removeConfig(path)
77
+ this.setRulesVersion()
68
78
  }
69
79
 
70
80
  destroy () {
@@ -16,7 +16,7 @@ const { updateConfig } = require('./telemetry')
16
16
  const telemetryMetrics = require('./telemetry/metrics')
17
17
  const { isInServerlessEnvironment, getIsGCPFunction, getIsAzureFunction } = require('./serverless')
18
18
  const {
19
- ORIGIN_KEY, GRPC_CLIENT_ERROR_STATUSES, GRPC_SERVER_ERROR_STATUSES, INSTRUMENTED_BY_SSI
19
+ ORIGIN_KEY, GRPC_CLIENT_ERROR_STATUSES, GRPC_SERVER_ERROR_STATUSES
20
20
  } = require('./constants')
21
21
  const { appendRules } = require('./payload-tagging/config')
22
22
  const { getEnvironmentVariable, getEnvironmentVariables } = require('./config-helper')
@@ -529,6 +529,9 @@ class Config {
529
529
  defaults['grpc.client.error.statuses'] = GRPC_CLIENT_ERROR_STATUSES
530
530
  defaults['grpc.server.error.statuses'] = GRPC_SERVER_ERROR_STATUSES
531
531
  defaults.headerTags = []
532
+ defaults['heapSnapshot.count'] = 0
533
+ defaults['heapSnapshot.destination'] = ''
534
+ defaults['heapSnapshot.interval'] = 3600
532
535
  defaults.hostname = '127.0.0.1'
533
536
  defaults['iast.dbRowsToTaint'] = 1
534
537
  defaults['iast.deduplicationEnabled'] = true
@@ -713,6 +716,9 @@ class Config {
713
716
  DD_GRPC_CLIENT_ERROR_STATUSES,
714
717
  DD_GRPC_SERVER_ERROR_STATUSES,
715
718
  JEST_WORKER_ID,
719
+ DD_HEAP_SNAPSHOT_COUNT,
720
+ DD_HEAP_SNAPSHOT_DESTINATION,
721
+ DD_HEAP_SNAPSHOT_INTERVAL,
716
722
  DD_IAST_DB_ROWS_TO_TAINT,
717
723
  DD_IAST_DEDUPLICATION_ENABLED,
718
724
  DD_IAST_ENABLED,
@@ -896,6 +902,9 @@ class Config {
896
902
  this._setIntegerRangeSet(env, 'grpc.client.error.statuses', DD_GRPC_CLIENT_ERROR_STATUSES)
897
903
  this._setIntegerRangeSet(env, 'grpc.server.error.statuses', DD_GRPC_SERVER_ERROR_STATUSES)
898
904
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
905
+ env['heapSnapshot.count'] = maybeInt(DD_HEAP_SNAPSHOT_COUNT)
906
+ this._setString(env, 'heapSnapshot.destination', DD_HEAP_SNAPSHOT_DESTINATION)
907
+ env['heapSnapshot.interval'] = maybeInt(DD_HEAP_SNAPSHOT_INTERVAL)
899
908
  this._setString(env, 'hostname', DD_AGENT_HOST)
900
909
  env['iast.dbRowsToTaint'] = maybeInt(DD_IAST_DB_ROWS_TO_TAINT)
901
910
  this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
@@ -916,6 +925,7 @@ class Config {
916
925
  this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
917
926
  this._setBoolean(env, 'iast.stackTrace.enabled', DD_IAST_STACK_TRACE_ENABLED)
918
927
  this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
928
+ this._setString(env, 'instrumentationSource', DD_INJECTION_ENABLED ? 'ssi' : 'manual')
919
929
  this._setBoolean(env, 'injectForce', DD_INJECT_FORCE)
920
930
  this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
921
931
  this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
@@ -1141,9 +1151,6 @@ class Config {
1141
1151
  opts['iast.securityControlsConfiguration'] = options.iast?.securityControlsConfiguration
1142
1152
  this._setBoolean(opts, 'iast.stackTrace.enabled', options.iast?.stackTrace?.enabled)
1143
1153
  this._setString(opts, 'iast.telemetryVerbosity', options.iast && options.iast.telemetryVerbosity)
1144
- if (options[INSTRUMENTED_BY_SSI]) {
1145
- this._setString(opts, 'instrumentationSource', options[INSTRUMENTED_BY_SSI])
1146
- }
1147
1154
  this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
1148
1155
  this._setBoolean(opts, 'legacyBaggageEnabled', options.legacyBaggageEnabled)
1149
1156
  this._setBoolean(opts, 'llmobs.agentlessEnabled', options.llmobs?.agentlessEnabled)
@@ -53,6 +53,5 @@ module.exports = {
53
53
  SPAN_POINTER_DIRECTION: Object.freeze({
54
54
  UPSTREAM: 'u',
55
55
  DOWNSTREAM: 'd'
56
- }),
57
- INSTRUMENTED_BY_SSI: Symbol('_dd.instrumented.by.ssi')
56
+ })
58
57
  }
@@ -19,7 +19,7 @@ const maxActiveRequests = 8
19
19
  let activeRequests = 0
20
20
 
21
21
  function parseUrl (urlObjOrString) {
22
- if (typeof urlObjOrString === 'object') return urlToHttpOptions(urlObjOrString)
22
+ if (urlObjOrString !== null && typeof urlObjOrString === 'object') return urlToHttpOptions(urlObjOrString)
23
23
 
24
24
  const url = urlToHttpOptions(new URL(urlObjOrString))
25
25
 
@@ -0,0 +1,58 @@
1
+ 'use strict'
2
+
3
+ const { join } = require('path')
4
+ const { setImmediate, setTimeout } = require('timers/promises')
5
+ const { format } = require('util')
6
+ const { writeHeapSnapshot } = require('v8')
7
+ const { threadId } = require('worker_threads')
8
+ const log = require('./log')
9
+
10
+ async function scheduleSnapshot (config, total) {
11
+ if (total > config.heapSnapshot.count) return
12
+
13
+ await setTimeout(config.heapSnapshot.interval * 1000, null, { ref: false })
14
+ await clearMemory()
15
+ writeHeapSnapshot(getName(config.heapSnapshot.destination))
16
+ await scheduleSnapshot(config, total + 1)
17
+ }
18
+
19
+ async function clearMemory () {
20
+ if (!globalThis.gc) return
21
+ globalThis.gc()
22
+ await setImmediate()
23
+ globalThis.gc() // Run full GC a second time for anything missed in first GC.
24
+ }
25
+
26
+ function pad (value) {
27
+ return String(value).padStart(2, 0)
28
+ }
29
+
30
+ function getName (destination) {
31
+ const date = new Date()
32
+ const filename = format(
33
+ 'Heap-%s%s%s-%s%s%s-%s-%s.heapsnapshot',
34
+ date.getFullYear(),
35
+ pad(date.getMonth()),
36
+ pad(date.getDate()),
37
+ pad(date.getHours()),
38
+ pad(date.getMinutes()),
39
+ pad(date.getSeconds()),
40
+ process.pid,
41
+ threadId
42
+ )
43
+
44
+ return join(destination, filename)
45
+ }
46
+
47
+ module.exports = {
48
+ async start (config) {
49
+ const destination = config.heapSnapshot.destination
50
+
51
+ try {
52
+ await scheduleSnapshot(config, 1)
53
+ log.debug('Wrote heap snapshots to %s.', destination)
54
+ } catch (e) {
55
+ log.error('Failed to write heap snapshots to %s.', destination, e)
56
+ }
57
+ }
58
+ }
@@ -39,7 +39,7 @@ class NoopLLMObs {
39
39
  const llmobs = this
40
40
  return function (target, ctxOrPropertyKey, descriptor) {
41
41
  if (!ctxOrPropertyKey) return target
42
- if (typeof ctxOrPropertyKey === 'object') {
42
+ if (typeof ctxOrPropertyKey === 'object') { // eslint-disable-line eslint-rules/eslint-safe-typeof-object
43
43
  const ctx = ctxOrPropertyKey
44
44
  if (ctx.kind !== 'method') return target
45
45
 
@@ -165,7 +165,7 @@ class LLMObsSpanProcessor {
165
165
  carrier[key] = UNSERIALIZABLE_VALUE_TEXT
166
166
  continue
167
167
  }
168
- if (typeof value === 'object') {
168
+ if (value !== null && typeof value === 'object') {
169
169
  add(value, carrier[key] = {})
170
170
  } else {
171
171
  carrier[key] = value
@@ -32,7 +32,7 @@ class Log {
32
32
  if (firstArg) {
33
33
  if (typeof firstArg === 'string') {
34
34
  message = firstArg
35
- } else if (typeof firstArg === 'object') {
35
+ } else if (typeof firstArg === 'object') { // eslint-disable-line eslint-rules/eslint-safe-typeof-object
36
36
  message = String(firstArg.message || firstArg)
37
37
  } else if (typeof firstArg === 'function') {
38
38
  delegate = firstArg
@@ -220,7 +220,7 @@ class DatadogSpan {
220
220
  addEvent (name, attributesOrStartTime, startTime) {
221
221
  const event = { name }
222
222
  if (attributesOrStartTime) {
223
- if (typeof attributesOrStartTime === 'object') {
223
+ if (typeof attributesOrStartTime === 'object') { // eslint-disable-line eslint-rules/eslint-safe-typeof-object
224
224
  event.attributes = this._sanitizeEventAttributes(attributesOrStartTime)
225
225
  } else {
226
226
  startTime = attributesOrStartTime
@@ -5,7 +5,7 @@ const {
5
5
  PAYLOAD_TAG_RESPONSE_PREFIX
6
6
  } = require('../constants')
7
7
 
8
- const jsonpath = require('./jsonpath-plus.js').JSONPath
8
+ const jsonpath = require('jsonpath-plus').JSONPath
9
9
 
10
10
  const { tagsFromObject } = require('./tagging')
11
11
 
@@ -36,7 +36,7 @@ function tagsFromObject (object, opts) {
36
36
  return
37
37
  }
38
38
 
39
- if (depth >= maxDepth && typeof object === 'object') {
39
+ if (depth >= maxDepth && object !== null && typeof object === 'object') {
40
40
  tagCount += 1
41
41
  result[prefix] = truncated
42
42
  return
@@ -65,7 +65,7 @@ function tagsFromObject (object, opts) {
65
65
  result[prefix] = object.slice(0, 5000)
66
66
  }
67
67
 
68
- if (typeof object === 'object') {
68
+ if (typeof object === 'object') { // eslint-disable-line eslint-rules/eslint-safe-typeof-object
69
69
  for (const [key, value] of Object.entries(object)) {
70
70
  if (redactedKeys.has(key.toLowerCase())) {
71
71
  tagCount += 1
@@ -8,6 +8,7 @@ const {
8
8
  } = require('../constants')
9
9
  const TracingPlugin = require('./tracing')
10
10
  const { exitTags } = require('../../../datadog-code-origin')
11
+ const { storage } = require('../../../datadog-core')
11
12
 
12
13
  const COMMON_PEER_SVC_SOURCE_TAGS = [
13
14
  'net.peer.name',
@@ -93,6 +94,12 @@ class OutboundPlugin extends TracingPlugin {
93
94
  finish (ctx) {
94
95
  const span = ctx?.currentStore?.span || this.activeSpan
95
96
  this.tagPeerService(span)
97
+
98
+ if (this._tracerConfig?._isInServerlessEnvironment()) {
99
+ const peerHostname = storage('peerServerless').getStore()?.peerHostname
100
+ if (peerHostname) span.setTag('peer.service', peerHostname)
101
+ }
102
+
96
103
  super.finish(...arguments)
97
104
  }
98
105
 
@@ -213,10 +213,10 @@ class NativeWallProfiler {
213
213
  }
214
214
 
215
215
  _updateContext (context) {
216
- if (typeof context.spanId === 'object') {
216
+ if (context.spanId !== null && typeof context.spanId === 'object') {
217
217
  context.spanId = context.spanId.toString(10)
218
218
  }
219
- if (typeof context.rootSpanId === 'object') {
219
+ if (context.rootSpanId !== null && typeof context.rootSpanId === 'object') {
220
220
  context.rootSpanId = context.rootSpanId.toString(10)
221
221
  }
222
222
  if (context.webTags !== undefined && context.endpoint === undefined) {
@@ -100,6 +100,10 @@ class Tracer extends NoopProxy {
100
100
  require('./crashtracking').start(config)
101
101
  }
102
102
 
103
+ if (config.heapSnapshot.count > 0) {
104
+ require('./heap_snapshots').start(config)
105
+ }
106
+
103
107
  telemetry.start(config, this._pluginManager)
104
108
 
105
109
  if (config.dogstatsd) {
@@ -3,20 +3,13 @@ class SchemaDefinition {
3
3
  this.schema = schema
4
4
  }
5
5
 
6
- getSchemaItem (type, kind, plugin) {
7
- const schema = this.schema
8
- if (schema && schema[type] && schema[type][kind] && schema[type][kind][plugin]) {
9
- return schema[type][kind][plugin]
10
- }
11
- }
12
-
13
6
  getOpName (type, kind, plugin, opts) {
14
- const item = this.getSchemaItem(type, kind, plugin)
7
+ const item = this.schema[type][kind][plugin]
15
8
  return item.opName(opts)
16
9
  }
17
10
 
18
11
  getServiceName (type, kind, plugin, opts) {
19
- const item = this.getSchemaItem(type, kind, plugin)
12
+ const item = this.schema[type][kind][plugin]
20
13
  return item.serviceName(opts)
21
14
  }
22
15
  }
@@ -14,7 +14,8 @@ const mySQLNaming = {
14
14
 
15
15
  function withFunction ({ tracerService, pluginConfig, params }) {
16
16
  if (typeof pluginConfig.service === 'function') {
17
- return pluginConfig.service(params)
17
+ const result = pluginConfig.service(params)
18
+ return typeof result === 'string' && result.length > 0 ? result : tracerService
18
19
  }
19
20
  return configWithFallback({ tracerService, pluginConfig })
20
21
  }
@@ -78,6 +78,9 @@
78
78
  "DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA": ["A"],
79
79
  "DD_GRPC_CLIENT_ERROR_STATUSES": ["A"],
80
80
  "DD_GRPC_SERVER_ERROR_STATUSES": ["A"],
81
+ "DD_HEAP_SNAPSHOT_COUNT": ["A"],
82
+ "DD_HEAP_SNAPSHOT_INTERVAL": ["A"],
83
+ "DD_HEAP_SNAPSHOT_DESTINATION": ["A"],
81
84
  "DD_IAST_DB_ROWS_TO_TAINT": ["A"],
82
85
  "DD_IAST_DEDUPLICATION_ENABLED": ["A"],
83
86
  "DD_IAST_ENABLED": ["A"],