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

feat: automate AppSec enablement setup (e.g: AWS_LAMBDA_RUNTIME_API) #143

Merged
merged 6 commits into from
Oct 30, 2023
Merged
Changes from 3 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
29 changes: 29 additions & 0 deletions ddlambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,15 @@ const (
// WrapLambdaHandlerInterface is used to instrument your lambda functions.
// It returns a modified handler that can be passed directly to the lambda.StartHandler function from aws-lambda-go.
func WrapLambdaHandlerInterface(handler lambda.Handler, cfg *Config) lambda.Handler {
setupAppSec()
listeners := initializeListeners(cfg)
return wrapper.WrapHandlerInterfaceWithListeners(handler, listeners...)
}

// WrapFunction is used to instrument your lambda functions.
// It returns a modified handler that can be passed directly to the lambda.Start function from aws-lambda-go.
func WrapFunction(handler interface{}, cfg *Config) interface{} {
setupAppSec()
listeners := initializeListeners(cfg)
return wrapper.WrapHandlerWithListeners(handler, listeners...)
}
Expand Down Expand Up @@ -289,3 +291,30 @@ func (cfg *Config) toMetricsConfig(isExtensionRunning bool) metrics.Config {

return mc
}

// setupAppSec checks if DD_SERVERLESS_APPSEC_ENABLED is set (to true) and when that
// is the case, redirects `AWS_LAMBDA_RUNTIME_API` to the agent extension, and turns
// on universal instrumentation unless it was already configured by the customer, so
// that the HTTP constext (invocation details span tags) is avaialble on AppSec traces.
func setupAppSec() {
const ServerlessAppSecEnabledEnvVar = "DD_SERVERLESS_APPSEC_ENABLED"
const AwsLambdaRuntimeApiEnvVar = "AWS_LAMBDA_RUNTIME_API"
const DatadogAgentUrl = "127.0.0.1:9000"
Copy link
Contributor

Choose a reason for hiding this comment

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

These should probably be globals.

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 don't suppose those would be tremendously useful outside of this particular scope and since they're constants I don't see much of a point hoisting them up into the module namespace. I can do that if that is a strong style preference...


enabled := false
if env := os.Getenv(ServerlessAppSecEnabledEnvVar); env != "" {
if on, err := strconv.ParseBool(env); err == nil {
enabled = on
}
}

if !enabled {
return
}

_ = os.Setenv(AwsLambdaRuntimeApiEnvVar, DatadogAgentUrl)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should consider checking that the extension is indeed present before doing this redirect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How do you suggest doing this? Just a file presence check? I could do that...


if val := os.Getenv(UniversalInstrumentation); val == "" {
_ = os.Setenv(UniversalInstrumentation, "1")
}
RomainMuller marked this conversation as resolved.
Show resolved Hide resolved
}
Loading