Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASM Standalone Billing #3965

Merged
merged 36 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
03106a2
Add DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED env var (does nothing f…
vpellan Aug 12, 2024
000bf66
Add _dd.apm.enabled tag
vpellan Aug 13, 2024
fa4540d
Add APM rate limiting when ASM standalone is activated
vpellan Sep 13, 2024
fbfd4af
Add Datadog-Client-Computed-Stats header with ASM standalone
vpellan Sep 13, 2024
a617a2c
Moved hardcoded _dd.appsec/apm.enabled tags to Ext file
vpellan Sep 23, 2024
d0b5f33
Add _dd.p.appsec tag to traces containing appsec event
vpellan Sep 23, 2024
31d6326
Skip distributed tracing if standalone appsec is enabled and trace co…
vpellan Sep 27, 2024
a3a26d0
Reject trace if appsec event is not detected when asm standalone is a…
vpellan Sep 27, 2024
63ab56b
Force keep traces with appsec event
vpellan Sep 30, 2024
81d20f2
Add conditional access to scope.trace
vpellan Sep 30, 2024
091a27f
Force execute asm standalone system tests
vpellan Sep 30, 2024
b32f0f8
Add APPSEC_STANDALONE scenario to system-tests GH workflow
vpellan Oct 1, 2024
7549839
Refactored tagging in gateway watchers
vpellan Oct 1, 2024
c882353
Fix _dd.p.appsec condition in shared examples
vpellan Oct 1, 2024
e86c729
Remove checks not related to ASM standalone in RSpec shared example
vpellan Oct 1, 2024
3c4de1a
Apply PR review suggestions
vpellan Oct 3, 2024
f362662
Add /requestdownstream and /returnheaders endpoints to Rack, Rails an…
vpellan Oct 3, 2024
a7c3eed
- Added mocked agent and force trace formatting to test Datadog-Clien…
vpellan Oct 7, 2024
ee6dc53
Applied code review suggestions
vpellan Oct 7, 2024
72a1027
Renamed TAG_APPSEC_EVENT to TAG_DISTRIBUTED_APPSEC_EVENT
vpellan Oct 8, 2024
efcf8dd
Add comment for appsec _dd.apm.enabled=0 tag
vpellan Oct 8, 2024
9acdafb
Separated tagging and force_keep of traces in gateway watchers
vpellan Oct 8, 2024
452e7b4
Add comment to explain ASM standalone rate limiting
vpellan Oct 9, 2024
3ffaddd
Add Datadog::AppSec::Event.add_tags spec and sig
vpellan Oct 9, 2024
97d3eba
Add Datadog-Client-Computed-Stats test in Core::Remote::Transport::ht…
vpellan Oct 10, 2024
63c1b87
Added circuit_breaker 'should_skip_distributed_tracing' spec
vpellan Oct 10, 2024
8575ed2
Added rule_sampler spec tests when appsec standalone is activated
vpellan Oct 10, 2024
154f31d
Rename asm_standalone_reject? to appsec_standalone_reject? and add si…
vpellan Oct 10, 2024
56a6475
Fix typo in AppSec::Event.add_tags spec
vpellan Oct 10, 2024
5f9a239
Update Unreleased Changelog
vpellan Oct 17, 2024
22f18a8
Add correct sig to Datadog::AppSec::Event.add_tags and add_distribute…
vpellan Oct 17, 2024
4a2bf67
Replaced set_tag by set_metric for _dd.appsec.enabled and _dd.apm.ena…
vpellan Oct 17, 2024
e24310e
Move appsec_standalone_reject? to AppSec namespace
vpellan Oct 17, 2024
73f8af2
Rename AppSec::Event.add_tags to AppSec::Event.tag_and_keep! and move…
vpellan Oct 17, 2024
a2f973b
Changed RuleSampler initialization with ASM Standalone to Tracing::Co…
vpellan Oct 21, 2024
8e54f7d
revert system-tests branch to main
vpellan Oct 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/system-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ env:
REGISTRY: ghcr.io
REPO: ghcr.io/datadog/dd-trace-rb
ST_REF: main
FORCE_TESTS: -F tests/appsec/waf/test_addresses.py::Test_GraphQL -F tests/appsec/test_blocking_addresses.py::Test_BlockingGraphqlResolvers
FORCE_TESTS_SCENARIO: GRAPHQL_APPSEC
Comment on lines -15 to -16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we forgot to remove this when merging GraphQL changes? If so, would it be better to create a separate PR with these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line must be cleaned after the release of the specified version in the manifest. In the case of GraphQL Appsec, it should have been cleaned after 2.3.0 release, but it does not change anything after the release, as we are forcing the execution of a test that is already executed. Charles specified in the doc that "from time to time" you should removes all the -F from the CI (https://github.com/DataDog/system-tests/blob/main/docs/edit/egg-chicken-changes.md?plain=1#L34), so this is why I did not considered it a priority.
I guess that a clean way to do it would be to add a step in fast_castle.
We can do a separate PR but the way FORCE_TESTS_SCENARIO is implemented does not enable to force tests execution on multiple scenarios, so that would mean that I cannot force execute APPSEC_STANDALONE on this PR

FORCE_TESTS: -F tests/appsec/test_asm_standalone.py
FORCE_TESTS_SCENARIO: APPSEC_STANDALONE

jobs:
build-harness:
Expand Down Expand Up @@ -199,6 +199,7 @@ jobs:
- APPSEC_DISABLED
- APPSEC_BLOCKING_FULL_DENYLIST
- APPSEC_REQUEST_BLOCKING
- APPSEC_STANDALONE
include:
- library: ruby
app: rack
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Added

* AppSec: Add Experimental Standalone AppSec Threats billing ([#3965][])

## [2.4.0] - 2024-10-11

### Added
Expand Down
1 change: 1 addition & 0 deletions lib/datadog/appsec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require_relative 'appsec/extensions'
require_relative 'appsec/scope'
require_relative 'appsec/ext'
require_relative 'appsec/utils'

module Datadog
# Namespace for Datadog AppSec instrumentation
Expand Down
8 changes: 8 additions & 0 deletions lib/datadog/appsec/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ def self.add_settings!(base)
o.type :bool, nilable: true
o.env 'DD_APPSEC_SCA_ENABLED'
end

settings :standalone do
option :enabled do |o|
o.type :bool
o.env 'DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED'
o.default false
end
end
end
end
end
Expand Down
6 changes: 1 addition & 5 deletions lib/datadog/appsec/contrib/graphql/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ def watch_multiplex(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end

Expand Down
24 changes: 9 additions & 15 deletions lib/datadog/appsec/contrib/rack/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ def watch_request(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down Expand Up @@ -85,11 +83,9 @@ def watch_response(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down Expand Up @@ -129,11 +125,9 @@ def watch_request_body(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/datadog/appsec/contrib/rack/request_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ def add_appsec_tags(processor, scope)

return unless trace && span

span.set_tag('_dd.appsec.enabled', 1)
span.set_metric(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1)
# We add this tag when ASM standalone is enabled to make sure we don't bill APM
span.set_metric(Datadog::AppSec::Ext::TAG_APM_ENABLED, 0) if Datadog.configuration.appsec.standalone.enabled
span.set_tag('_dd.runtime_family', 'ruby')
span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)

Expand Down
8 changes: 3 additions & 5 deletions lib/datadog/appsec/contrib/rails/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ def watch_request_action(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down
16 changes: 6 additions & 10 deletions lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ def watch_request_dispatch(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down Expand Up @@ -84,11 +82,9 @@ def watch_request_routed(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down
24 changes: 24 additions & 0 deletions lib/datadog/appsec/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ def build_service_entry_tags(event_group)
end
# rubocop:enable Metrics/MethodLength

def tag_and_keep!(scope, waf_result)
# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if waf_result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

add_distributed_tags(scope.trace)
end

private

def compressed_and_base64_encoded(value)
Expand Down Expand Up @@ -165,6 +177,18 @@ def gzip(value)
gz.close
sio.string
end

# Propagate to downstream services the information that the current distributed trace is
# containing at least one ASM security event.
def add_distributed_tags(trace)
return unless trace

trace.set_tag(
Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
Datadog::Tracing::Sampling::Ext::Decision::ASM
)
trace.set_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT, '1')
marcotc marked this conversation as resolved.
Show resolved Hide resolved
end
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/appsec/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ module AppSec
module Ext
INTERRUPT = :datadog_appsec_interrupt
SCOPE_KEY = 'datadog.appsec.scope'

TAG_APPSEC_ENABLED = '_dd.appsec.enabled'
TAG_APM_ENABLED = '_dd.apm.enabled'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this constant really belong to Appsec module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so as the only time it is added to a trace is when ASM standalone is activated. Usually, we don't want disable APM, this is for now the only case when it is disabled.

TAG_DISTRIBUTED_APPSEC_EVENT = '_dd.p.appsec'
end
end
end
8 changes: 3 additions & 5 deletions lib/datadog/appsec/monitor/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ def watch_user_id(gateway = Instrumentation.gateway)
actions: result.actions
}

if scope.service_entry_span
scope.service_entry_span.set_tag('appsec.blocked', 'true') if result.actions.include?('block')
scope.service_entry_span.set_tag('appsec.event', 'true')
end

# We want to keep the trace in case of security event
scope.trace.keep! if scope.trace
Datadog::AppSec::Event.tag_and_keep!(scope, result)
scope.processor_context.events << event
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/datadog/appsec/utils.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative 'utils/trace_operation'

module Datadog
module AppSec
# Utilities for AppSec
Expand Down
15 changes: 15 additions & 0 deletions lib/datadog/appsec/utils/trace_operation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Datadog
module AppSec
module Utils
# Utility class to to AppSec-specific trace operations
class TraceOperation
def self.appsec_standalone_reject?(trace)
Datadog.configuration.appsec.standalone.enabled &&
(trace.nil? || trace.get_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT) != '1')
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/datadog/core/remote/transport/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ def default_headers
# Add container ID, if present.
container_id = Datadog::Core::Environment::Container.container_id
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id unless container_id.nil?
# Sending this header to the agent will disable metrics computation (and billing) on the agent side
# by pretending it has already been done on the library side.
if Datadog.configuration.appsec.standalone.enabled
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
end
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/datadog/core/transport/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module HTTP
#
# Setting this header to any non-empty value enables this feature.
HEADER_CLIENT_COMPUTED_TOP_LEVEL = 'Datadog-Client-Computed-Top-Level'
HEADER_CLIENT_COMPUTED_STATS = 'Datadog-Client-Computed-Stats'
HEADER_META_LANG = 'Datadog-Meta-Lang'
HEADER_META_LANG_VERSION = 'Datadog-Meta-Lang-Version'
HEADER_META_LANG_INTERPRETER = 'Datadog-Meta-Lang-Interpreter'
Expand Down
13 changes: 13 additions & 0 deletions lib/datadog/tracing/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ def build_sampler(settings)
return sampler
end

# AppSec events are sent to the backend using traces.
# Standalone ASM billing means that we don't want to charge clients for APM traces,
# so we want to send the minimum amount of traces possible (idealy only traces that contains security events),
# but for features such as API Security, we need to send at least one trace per minute,
# to keep the service alive on the backend side.
if settings.appsec.standalone.enabled
post_sampler = Tracing::Sampling::RuleSampler.new(
[Tracing::Sampling::SimpleRule.new(sample_rate: 1.0)],
rate_limiter: Datadog::Core::TokenBucket.new(1.0 / 60, 1.0),
default_sample_rate: 1.0 / 60
)
end

# Sampling rules are provided
if (rules = settings.tracing.sampling.rules)
post_sampler = Tracing::Sampling::RuleSampler.parse(
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/tracing/contrib/ethon/easy_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ def datadog_before_request(continue_from: nil)

datadog_tag_request

if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(datadog_trace)
datadog_trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end

if datadog_configuration[:distributed_tracing]
@datadog_original_headers ||= {}
Contrib::HTTP.inject(datadog_trace, @datadog_original_headers)
Expand Down
3 changes: 3 additions & 0 deletions lib/datadog/tracing/contrib/excon/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def request_call(datum)
trace = Tracing.active_trace
datum[:datadog_span] = span
annotate!(span, datum)
if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end
propagate!(trace, span, datum) if distributed_tracing?

span
Expand Down
3 changes: 3 additions & 0 deletions lib/datadog/tracing/contrib/faraday/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def call(env)

Tracing.trace(Ext::SPAN_REQUEST, on_error: request_options[:on_error]) do |span, trace|
annotate!(span, env, request_options)
if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end
propagate!(trace, span, env) if request_options[:distributed_tracing] && Tracing.enabled?
app.call(env).on_complete { |resp| handle_response(span, resp, request_options) }
end
Expand Down
9 changes: 9 additions & 0 deletions lib/datadog/tracing/contrib/http/circuit_breaker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ def internal_request?(request)
end

def should_skip_distributed_tracing?(client_config)
if Datadog.configuration.appsec.standalone.enabled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that we add a bunch of Datadog.configuration.appsec.standalone.enabled all over the tracing component which imposes a hard dependency between Tracing and AppSec internal details. What's especially worrying, is that in this case we reverse the dependency and now Tracing knows about AppSec internals (even though AppSec is supposed to be a client of Tracing).

So my question is for the Tracing team: do you think it would make sense to introduce some tracing settings to allow client products to tweak tracing behaviour even more? Like we do between CI and Tracing modules: Tracing exposes settings, CI configures them.

@marcotc what do you think?

Copy link
Contributor Author

@vpellan vpellan Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add more context: appsec standalone is still experimental and the env var/configuration might change name in the future, and the 'appsec' part of this setting name may disappear. What it do on the tracing part is disabling distributed tracing, adding a header to the payload sent to the agent, creating a 1 trace per minute rate limiter, and setting the sampling priority to 'reject' if there is an appsec event detected. Although the first 3 points aren't directly tied to appsec, the last one is, but it is still acting only on the traces.

# Skip distributed tracing so that we don't bill distributed traces in case of absence of
# upstream ASM event (_dd.p.appsec:1) and no local security event (which sets _dd.p.appsec:1 locally).
# If there is an ASM event, we still have to check if distributed tracing is enabled or not
return true unless Tracing.active_trace

return true if Tracing.active_trace.get_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT) != '1'
end

return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)

!Datadog.configuration.tracing[:http][:distributed_tracing]
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/tracing/contrib/http/instrumentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def request(req, body = nil, &block)
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
span.resource = req.method

if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
marcotc marked this conversation as resolved.
Show resolved Hide resolved
end

if Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
Contrib::HTTP.inject(trace, req)
end
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/tracing/contrib/httpclient/instrumentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def do_get_block(req, proxy, conn, &block)
span.service = service_name(host, request_options, client_config)
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND

if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end

if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
Contrib::HTTP.inject(trace, req.header)
end
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/tracing/contrib/httprb/instrumentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def perform(req, options)
span.service = service_name(host, request_options, client_config)
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND

if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end

Contrib::HTTP.inject(trace, req) if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)

# Add additional request specific tags to the span.
Expand Down
3 changes: 3 additions & 0 deletions lib/datadog/tracing/contrib/rest_client/request_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def execute(&block)
return super(&block) unless Tracing.enabled?

datadog_trace_request(uri) do |_span, trace|
if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
end
Contrib::HTTP.inject(trace, processed_headers) if datadog_configuration[:distributed_tracing]

super(&block)
Expand Down
Loading
Loading