Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ go.work.sum
/internal/appsec @DataDog/asm-go @DataDog/apm-go
/contrib/**/*appsec*.go @DataDog/asm-go @DataDog/apm-go
/.github/workflows/appsec.yml @DataDog/asm-go @DataDog/apm-go
/contrib/envoyproxy @DataDog/asm-go @DataDog/apm-go

# datastreams
/datastreams @Datadog/data-streams-monitoring @DataDog/apm-go
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ The ASM Service Extension expose some configuration. The configuration can be tw

>**GCP requires that the default configuration for the Service Extension should not change.**

| Environment variable | Default value | Description |
|---|---|---|
| `DD_SERVICE_EXTENSION_HOST` | `0.0.0.0` | Host on where the gRPC and HTTP server should listen to. |
| `DD_SERVICE_EXTENSION_PORT` | `443` | Port used by the gRPC Server.<br>Envoy Google backend’s is only using secure connection to Service Extension. |
| `DD_SERVICE_EXTENSION_HEALTHCHECK_PORT` | `80` | Port used for the HTTP server for the health check. |
| Environment variable | Default value | Description |
|---|---------------|---------------------------------------------------------------------------------------------------------------|
| `DD_SERVICE_EXTENSION_HOST` | `0.0.0.0` | Host on where the gRPC and HTTP server should listen to. |
| `DD_SERVICE_EXTENSION_PORT` | `443` | Port used by the gRPC Server.<br>Envoy Google backend’s is only using secure connection to Service Extension. |
| `DD_SERVICE_EXTENSION_HEALTHCHECK_PORT` | `80` | Port used for the HTTP server for the health check. |
| `DD_SERVICE_EXTENSION_OBSERVABILITY_MODE` | `false` | Enable observability mode. This will process a request asynchronously (blocking would be disabled). |

> The Service Extension need to be connected to a deployed [Datadog agent](https://docs.datadoghq.com/agent).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,18 @@ func ipEnv(key string, def net.IP) net.IP {

return ip
}

// BoolEnv returns the parsed boolean value of an environment variable, or
// def otherwise.
func boolEnv(key string, def bool) bool {
vv, ok := os.LookupEnv(key)
if !ok {
return def
}
v, err := strconv.ParseBool(vv)
if err != nil {
log.Warn("Non-boolean value for env var %s, defaulting to %t. Parse failed with error: %v", key, def, err)
return def
}
return v
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,26 @@ type AppsecCalloutExtensionService struct {
}

type serviceExtensionConfig struct {
extensionPort string
extensionHost string
healthcheckPort string
extensionPort string
extensionHost string
healthcheckPort string
observabilityMode bool
}

func loadConfig() serviceExtensionConfig {
extensionPortInt := intEnv("DD_SERVICE_EXTENSION_PORT", 443)
healthcheckPortInt := intEnv("DD_SERVICE_EXTENSION_HEALTHCHECK_PORT", 80)
extensionHostStr := ipEnv("DD_SERVICE_EXTENSION_HOST", net.IP{0, 0, 0, 0}).String()
observabilityMode := boolEnv("DD_SERVICE_EXTENSION_OBSERVABILITY_MODE", false)

extensionPortStr := strconv.FormatInt(int64(extensionPortInt), 10)
healthcheckPortStr := strconv.FormatInt(int64(healthcheckPortInt), 10)

return serviceExtensionConfig{
extensionPort: extensionPortStr,
extensionHost: extensionHostStr,
healthcheckPort: healthcheckPortStr,
extensionPort: extensionPortStr,
extensionHost: extensionHostStr,
healthcheckPort: healthcheckPortStr,
observabilityMode: observabilityMode,
}
}

Expand All @@ -67,6 +70,12 @@ func main() {

config := loadConfig()

// If the observability mode is enabled, disable blocking
if config.observabilityMode {
_ = os.Setenv("_DD_APPSEC_BLOCKING_UNAVAILABLE", "true")
log.Debug("service_extension: observability mode enabled, disabling blocking\n")
}

if err := startService(config); err != nil {
log.Error("service_extension: %v\n", err)
os.Exit(1)
Expand Down Expand Up @@ -145,7 +154,12 @@ func startGPRCSsl(ctx context.Context, service extproc.ExternalProcessorServer,
grpcCredentials := credentials.NewServerTLSFromCert(&cert)
grpcServer := grpc.NewServer(grpc.Creds(grpcCredentials))

appsecEnvoyExternalProcessorServer := gocontrolplane.AppsecEnvoyExternalProcessorServerGCPServiceExtension(service)
appsecEnvoyExternalProcessorServer := gocontrolplane.AppsecEnvoyExternalProcessorServer(
service,
gocontrolplane.AppsecEnvoyConfig{
IsGCPServiceExtension: true,
BlockingUnavailable: config.observabilityMode,
})

go func() {
<-ctx.Done()
Expand Down
51 changes: 28 additions & 23 deletions contrib/envoyproxy/go-control-plane/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,22 @@ func init() {
instr = instrumentation.Load(instrumentation.PackageEnvoyProxyGoControlPlane)
}

type AppsecEnvoyConfig struct {
IsGCPServiceExtension bool
BlockingUnavailable bool
}

// appsecEnvoyExternalProcessorServer is a server that implements the Envoy ExternalProcessorServer interface.
type appsecEnvoyExternalProcessorServer struct {
envoyextproc.ExternalProcessorServer
isGCPServiceExtension bool
}

// AppsecEnvoyExternalProcessorServer creates and returns a new instance of appsecEnvoyExternalProcessorServer.
func AppsecEnvoyExternalProcessorServer(userImplementation envoyextproc.ExternalProcessorServer) envoyextproc.ExternalProcessorServer {
return &appsecEnvoyExternalProcessorServer{userImplementation, false}
config AppsecEnvoyConfig
}

func AppsecEnvoyExternalProcessorServerGCPServiceExtension(userImplementation envoyextproc.ExternalProcessorServer) envoyextproc.ExternalProcessorServer {
return &appsecEnvoyExternalProcessorServer{userImplementation, true}
func AppsecEnvoyExternalProcessorServer(userImplementation envoyextproc.ExternalProcessorServer, config AppsecEnvoyConfig) envoyextproc.ExternalProcessorServer {
return &appsecEnvoyExternalProcessorServer{
ExternalProcessorServer: userImplementation,
config: config,
}
}

type currentRequest struct {
Expand Down Expand Up @@ -123,9 +126,9 @@ func (s *appsecEnvoyExternalProcessorServer) Process(processServer envoyextproc.

switch v := processingRequest.Request.(type) {
case *envoyextproc.ProcessingRequest_RequestHeaders:
processingResponse, currentRequest, blocked, err = processRequestHeaders(ctx, v, s.isGCPServiceExtension)
processingResponse, currentRequest, blocked, err = processRequestHeaders(ctx, v, s.config)
case *envoyextproc.ProcessingRequest_ResponseHeaders:
processingResponse, err = processResponseHeaders(v, currentRequest)
processingResponse, err = processResponseHeaders(v, currentRequest, s.config)
currentRequest = nil // Request is done, reset the current request
}

Expand Down Expand Up @@ -199,7 +202,7 @@ func envoyExternalProcessingRequestTypeAssert(req *envoyextproc.ProcessingReques
}
}

func processRequestHeaders(ctx context.Context, req *envoyextproc.ProcessingRequest_RequestHeaders, isGCPServiceExtension bool) (*envoyextproc.ProcessingResponse, *currentRequest, bool, error) {
func processRequestHeaders(ctx context.Context, req *envoyextproc.ProcessingRequest_RequestHeaders, config AppsecEnvoyConfig) (*envoyextproc.ProcessingResponse, *currentRequest, bool, error) {
instr.Logger().Debug("external_processing: received request headers: %v\n", req.RequestHeaders)

request, err := newRequest(ctx, req)
Expand All @@ -208,7 +211,7 @@ func processRequestHeaders(ctx context.Context, req *envoyextproc.ProcessingRequ
}

var spanComponentName string
if isGCPServiceExtension {
if config.IsGCPServiceExtension {
spanComponentName = componentNameGCPServiceExtension
} else {
spanComponentName = componentNameEnvoy
Expand All @@ -226,7 +229,7 @@ func processRequestHeaders(ctx context.Context, req *envoyextproc.ProcessingRequ
}, fakeResponseWriter, request)

// Block handling: If triggered, we need to block the request, return an immediate response
if blocked {
if !config.BlockingUnavailable && blocked {
afterHandle()
return doBlockResponse(fakeResponseWriter), nil, true, nil
}
Expand Down Expand Up @@ -284,7 +287,7 @@ func propagationRequestHeaderMutation(span *tracer.Span) (*envoyextproc.Processi
}, nil
}

func processResponseHeaders(res *envoyextproc.ProcessingRequest_ResponseHeaders, currentRequest *currentRequest) (*envoyextproc.ProcessingResponse, error) {
func processResponseHeaders(res *envoyextproc.ProcessingRequest_ResponseHeaders, currentRequest *currentRequest, config AppsecEnvoyConfig) (*envoyextproc.ProcessingResponse, error) {
instr.Logger().Debug("external_processing: received response headers: %v\n", res.ResponseHeaders)

if currentRequest == nil {
Expand All @@ -302,19 +305,21 @@ func processResponseHeaders(res *envoyextproc.ProcessingRequest_ResponseHeaders,
var blocked bool

// Now we need to know if the request has been blocked, but we don't have any other way than to look for the operation and bind a blocking data listener to it
op, ok := dyngo.FromContext(currentRequest.ctx)
if ok {
dyngo.OnData(op, func(_ *actions.BlockHTTP) {
// We already wrote over the response writer, we need to reset it so the blocking handler can write to it
httptrace.ResetStatusCode(currentRequest.wrappedResponseWriter)
currentRequest.fakeResponseWriter.Reset()
blocked = true
})
if !config.BlockingUnavailable {
op, ok := dyngo.FromContext(currentRequest.ctx)
if ok {
dyngo.OnData(op, func(_ *actions.BlockHTTP) {
// We already wrote over the response writer, we need to reset it so the blocking handler can write to it
httptrace.ResetStatusCode(currentRequest.wrappedResponseWriter)
currentRequest.fakeResponseWriter.Reset()
blocked = true
})
}
}

currentRequest.afterHandle()

if blocked {
if !config.BlockingUnavailable && blocked {
response := doBlockResponse(currentRequest.fakeResponseWriter)
return response, nil
}
Expand Down
28 changes: 16 additions & 12 deletions contrib/envoyproxy/go-control-plane/envoy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"fmt"
"io"
"net"
"os"
"testing"

envoyextproc "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
Expand All @@ -33,7 +34,7 @@ func TestAppSec(t *testing.T) {
}

setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, false)
rig, err := newEnvoyAppsecRig(t, false, false, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -110,7 +111,7 @@ func TestBlockingWithUserRulesFile(t *testing.T) {
}

setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, false)
rig, err := newEnvoyAppsecRig(t, false, false, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -234,7 +235,7 @@ func TestBlockingWithUserRulesFile(t *testing.T) {

func TestGeneratedSpan(t *testing.T) {
setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, false)
rig, err := newEnvoyAppsecRig(t, false, false, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -323,7 +324,7 @@ func TestXForwardedForHeaderClientIp(t *testing.T) {
}

setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, false)
rig, err := newEnvoyAppsecRig(t, false, false, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -411,7 +412,7 @@ func TestMalformedEnvoyProcessing(t *testing.T) {
}

setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, false)
rig, err := newEnvoyAppsecRig(t, false, false, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -457,7 +458,7 @@ func TestAppSecAsGCPServiceExtension(t *testing.T) {
}

setup := func() (envoyextproc.ExternalProcessorClient, mocktracer.Tracer, func()) {
rig, err := newEnvoyAppsecRig(t, false, true)
rig, err := newEnvoyAppsecRig(t, false, true, false)
require.NoError(t, err)

mt := mocktracer.Start()
Expand Down Expand Up @@ -492,21 +493,24 @@ func TestAppSecAsGCPServiceExtension(t *testing.T) {
})
}

func newEnvoyAppsecRig(t *testing.T, traceClient bool, isGCPServiceExtension bool, interceptorOpts ...ddgrpc.Option) (*envoyAppsecRig, error) {
func newEnvoyAppsecRig(t *testing.T, traceClient bool, isGCPServiceExtension bool, blockingUnavailable bool, interceptorOpts ...ddgrpc.Option) (*envoyAppsecRig, error) {
t.Helper()

interceptorOpts = append([]ddgrpc.Option{ddgrpc.WithService("grpc")}, interceptorOpts...)

server := grpc.NewServer()
fixtureServer := new(envoyFixtureServer)

var appsecSrv envoyextproc.ExternalProcessorServer
if isGCPServiceExtension {
appsecSrv = AppsecEnvoyExternalProcessorServerGCPServiceExtension(fixtureServer)
} else {
appsecSrv = AppsecEnvoyExternalProcessorServer(fixtureServer)
if blockingUnavailable {
_ = os.Setenv("_DD_APPSEC_BLOCKING_UNAVAILABLE", "true")
}

var appsecSrv envoyextproc.ExternalProcessorServer
appsecSrv = AppsecEnvoyExternalProcessorServer(fixtureServer, AppsecEnvoyConfig{
IsGCPServiceExtension: isGCPServiceExtension,
BlockingUnavailable: blockingUnavailable,
})

envoyextproc.RegisterExternalProcessorServer(server, appsecSrv)

li, err := net.Listen("tcp", "127.0.0.1:0")
Expand Down
6 changes: 5 additions & 1 deletion contrib/envoyproxy/go-control-plane/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ func Example_server() {
srv := &envoyExtProcServer{}

// Register the appsec envoy external processor service
appsecSrv := AppsecEnvoyExternalProcessorServer(srv)
appsecSrv := AppsecEnvoyExternalProcessorServer(srv, AppsecEnvoyConfig{
IsGCPServiceExtension: false,
BlockingUnavailable: false,
})

extprocv3.RegisterExternalProcessorServer(s, appsecSrv)

// ... register your services
Expand Down
1 change: 1 addition & 0 deletions ddtrace/tracer/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func Start(opts ...StartOption) error {
appsecopts := make([]appsecConfig.StartOption, 0, len(t.config.appsecStartOptions)+1)
appsecopts = append(appsecopts, t.config.appsecStartOptions...)
appsecopts = append(appsecopts, appsecConfig.WithRCConfig(cfg), appsecConfig.WithMetaStructAvailable(t.config.agent.metaStructAvailable))

appsec.Start(appsecopts...)

// start instrumentation telemetry unless it is disabled through the
Expand Down
6 changes: 5 additions & 1 deletion go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -288,26 +288,31 @@ github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.0-rc.1 h1:yjO0
github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.0-rc.1/go.mod h1:+BnlaBR5kMqTFYwDEc1QW0f6zvLJKnwBAUbeC68HaVs=
github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.1 h1:EtwW+/CTXHaS9COioO/BS0u3HWW0H3sgLJ6Nqbgz7D8=
github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.1/go.mod h1:+BnlaBR5kMqTFYwDEc1QW0f6zvLJKnwBAUbeC68HaVs=
github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.2 h1:RKzJe4B8yQLZ5iC4tidfakKWQnFAeMCgoxJYXPsqQbo=
github.com/DataDog/datadog-agent/comp/trace/compression/def v0.64.2/go.mod h1:+BnlaBR5kMqTFYwDEc1QW0f6zvLJKnwBAUbeC68HaVs=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.0-rc.1 h1:Rx2o4Sk1IwkpZbZu5PoLaai8rQjegwJ/eieEjryaU10=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.0-rc.1/go.mod h1:mW8ei9lGT6E3uDsBLChNYIZ/GOUZNEwZh3Z+RaS/df4=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.1 h1:eXD6ROmH7Wgk3smKGpmiuYw33EgJfGZVe6sjS7mKlyc=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.1/go.mod h1:ybWnQ+wQHgzAT/jL9DSa1LGPJE0XMI0BJ7VuexArcqY=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.2 h1:VC9oiyjcjuBHfxWZcXXc1fwBygLXO33GzfbZeWNPBOY=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.64.2/go.mod h1:viv8Bvx5BE2YDnsWwemlGu6dsaT6tjBoK27eMXkvdeY=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.0-rc.1 h1:ADqb0FHp5TsTwk31aWy8hOp0XmizOsEKG6ByEIMfXYY=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.0-rc.1/go.mod h1:qtNBiygMkl/zGi5v+ejj65hRoCQLRJadybMCFidfDKQ=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.1 h1:cTzHRzIjNZgF9y+0rSOT9WGJIrSLwjhBO1pO6qxYdd4=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.1/go.mod h1:HxTeb4dEu471uHCLcmLzcajSFzTS7TFbPyqmlFyiSZI=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.2 h1:58UNufA8lcUb/0ggQAj6mzKxcTxuYVf71PQcrx+izHg=
github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.64.2/go.mod h1:X97j3rl2QnoOXanM23Qw1Esmz+bx+tu2ODnbZPdzzoc=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.0-rc.1 h1:GqHjzbYflWAKQLv/yoNeC54lsrcZgxbAlX2nzfJzx8M=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.0-rc.1/go.mod h1:xQ8Es4XKlrWKUYp/ZY67vXRAjOLmfrGqMlNZ471y/vM=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.1 h1:w8JQeOAi4RVU+PbQDttZw6jI1oLLDD6ngZFirF+9O9M=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.1/go.mod h1:0UOWX5H0khCj5or1JDaOLs3LnhOBuwv3Hhpe3fImBZk=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.2 h1:oIXXiS3AECT6JwyJsmbWN9P5ku57fogLkUDeka6uYl4=
github.com/DataDog/datadog-agent/pkg/util/cgroups v0.64.2/go.mod h1:ag/+5g879n3WZpcPr8yW7X4Lf83l3yz8qTsoeM1U7Qo=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.0-rc.1 h1:Qiiq60ysVOcEO3cO/2ffLyy1ZEZHU2ZybuJBACVvBSI=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.0-rc.1/go.mod h1:cY4100zn21kBb748mG0hDv9BfswD+tUw3p2M4XdUzAE=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.1 h1:1g0pL0Y3xiZ2ubg19EIvFPDLVF/Z8WaBc4L47eeqp9U=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.1/go.mod h1:cY4100zn21kBb748mG0hDv9BfswD+tUw3p2M4XdUzAE=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.2 h1:riYWM572c2zVBK6yMg1i2XfmGhmDtooM9+WXBGNXtHk=
github.com/DataDog/datadog-agent/pkg/util/pointer v0.64.2/go.mod h1:cY4100zn21kBb748mG0hDv9BfswD+tUw3p2M4XdUzAE=
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
github.com/DataDog/orchestrion v1.3.1/go.mod h1:vCQMJqwvQpJRfwxpd9gAL+zWmaF4R0OqOUK/ru+vmQo=
Expand All @@ -319,7 +324,6 @@ github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvK
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.2.1 h1:n6EPaDyLSvCEa3frruQvAiHuNp2dhBlMSmkEr+HuzGc=
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
Expand Down
6 changes: 6 additions & 0 deletions internal/appsec/appsec.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package appsec

import (
"fmt"
globalinternal "github.com/DataDog/dd-trace-go/v2/internal"
"sync"

appsecLog "github.com/DataDog/appsec-internal-go/log"
Expand Down Expand Up @@ -38,6 +39,11 @@ func RASPEnabled() bool {
// Start AppSec when enabled is enabled by both using the appsec build tag and
// setting the environment variable DD_APPSEC_ENABLED to true.
func Start(opts ...config.StartOption) {
// TODO: Add support to configure the tracer via a public interface
if globalinternal.BoolEnv("_DD_APPSEC_BLOCKING_UNAVAILABLE", false) {
opts = append(opts, config.WithBlockingUnavailable(true))
}

startConfig := config.NewStartConfig(opts...)

// AppSec can start either:
Expand Down
Loading
Loading