Skip to content

[APPSEC-61864] Add AppSec AWS Lambda contrib#5663

Merged
Strech merged 24 commits into
masterfrom
appsec-61864-add-appsec-aws-lambda-contrib
May 8, 2026
Merged

[APPSEC-61864] Add AppSec AWS Lambda contrib#5663
Strech merged 24 commits into
masterfrom
appsec-61864-add-appsec-aws-lambda-contrib

Conversation

@Strech

@Strech Strech commented May 4, 2026

Copy link
Copy Markdown
Member

What does this PR do?

This PR will add handling of AWS Lambda pushing messages to the gateway.

Motivation:

This is an AppSec part of the Endpoint Discovery & Correlation from Inferred Spans RFC

Change log entry

Yes. Add AWS Lambda contrib

Additional Notes:

This PR was generated with a help of AI, but rewritten by hand.

How to test the change?

CI + ST

Strech and others added 12 commits May 4, 2026 13:55
The request and response watchers crash with NoMethodError when
AppSec::Context is not active. Skip WAF processing and continue
the gateway stack instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Replace manual JSON/form-urlencoded parsing with Body.parse and
MediaType.parse. This adds telemetry on parse errors, preserves
duplicate URL-encoded keys as arrays, and adds missing require
for base64.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
API Gateway v1 provides pre-decoded queryStringParameters but no
raw query string. Manual string concatenation produced invalid URIs
when values contained special characters like & or spaces.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Move all AppSec logic (context lifecycle, WAF, Event.record,
finalization) from datadog-lambda-rb into dd-trace-rb watcher.
Producer (datadog-lambda-rb) becomes a dumb data provider that
pushes raw PORO hashes through the gateway.

Delete Request and Response gateway classes — parsing logic
now lives in the watcher as private helpers.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Move Lambda payload parsing and WAF address building into
a dedicated AwsLambda::WAFAddresses module. Watcher becomes
a thin orchestrator that delegates data transformation.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Remove activate_context and finalize from watcher — context
creation, Event.record, export, and deactivation now owned by
Lambda::AppSec in datadog-lambda-rb. Watcher keeps only WAF
logic (handle_request + handle_response).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Lambda now owns request data via AppSec::Request. The Watcher
receives DataContainer payloads and unwraps .data for WAFAddresses.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
AWS Lambda events can have explicit null values for fields like
queryStringParameters. Hash#fetch returns nil when the key exists
with a nil value, causing URI.encode_www_form to crash on nil.map.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@Strech
Strech requested review from a team as code owners May 4, 2026 12:01
@Strech
Strech marked this pull request as draft May 4, 2026 12:01
@dd-octo-sts dd-octo-sts Bot added integrations Involves tracing integrations appsec Application Security monitoring product labels May 4, 2026
@dd-octo-sts

dd-octo-sts Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Thank you for updating Change log entry section 👏

Visited at: 2026-05-04 12:02:33 UTC

@dd-octo-sts

dd-octo-sts Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Typing analysis

Note: Ignored files are excluded from the next sections.

Untyped methods

This PR introduces 7 partially typed methods. It increases the percentage of typed methods from 61.75% to 61.77% (+0.02%).

Partially typed methods (+7-0)Introduced:
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:6
└── def self?.from_request: (::Hash[::String, untyped] payload) -> ::Hash[::String, untyped]
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:8
└── def self?.from_response: (::Hash[::String, untyped]? payload) -> ::Hash[::String, untyped]
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:10
└── def self?.parse_headers: (::Hash[::String, untyped] payload) -> ::Hash[::String, ::String]
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:12
└── def self?.parse_cookies: (::Hash[::String, untyped] payload, ::Hash[::String, ::String] headers) -> ::Hash[::String, ::String?]?
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:14
└── def self?.build_fullpath: (::Hash[::String, untyped] payload) -> ::String?
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:16
└── def self?.build_query_string: (::Hash[::String, untyped] payload) -> ::String?
sig/datadog/appsec/contrib/aws_lambda/waf_addresses.rbs:20
└── def self?.parse_body: (::Hash[::String, untyped] payload, ::Hash[::String, ::String] headers) -> untyped

If you believe a method or an attribute is rightfully untyped or partially typed, you can add # untyped:accept on the line before the definition to remove it from the stats.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6474970492

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb Outdated
Strech and others added 3 commits May 4, 2026 14:56
- Add missing require 'uri' (crashes on Ruby 3.3+ for v1 payloads)
- Fix build_query_string to prefer multiValueQueryStringParameters,
  consistent with parse_query (URI.encode_www_form handles arrays)
- Switch watcher from Context.active to payload.context, matching
  other AppSec watchers that read context from the gateway payload
- Rename handle_request/handle_response to watch_request/watch_response
  to match codebase naming convention
- Fix from_response nil guard to idiomatic default parameter
- Integration#compatible? now delegates to super

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Remove stale activate_context and finalize signatures from watcher
- Rename handle_* to watch_* matching Ruby implementation
- Use fully qualified gateway type matching Rack watcher pattern
- compatible? returns bool (not literal true) matching other integrations
- Replace untyped with any for intentionally polymorphic Lambda payloads
- Fix from_response signature for default parameter

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Use instance_double with verified classes (SecurityEngine::Result,
  TraceOperation, SpanOperation) instead of unverified double
- Inline nil context in subject instead of let override
- Move local variables in .watch test to let statements
- Fix let ordering in patcher spec (caller before callee)

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@pr-commenter

pr-commenter Bot commented May 4, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-05-06 19:08:04

Comparing candidate commit b6f988b in PR branch appsec-61864-add-appsec-aws-lambda-contrib with baseline commit 65b7637 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 45 metrics, 1 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Comment thread lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/integration.rb
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb Outdated
Comment thread sig/datadog/appsec/contrib/aws_lambda/integration.rbs Outdated
Comment thread sig/datadog/appsec/contrib/aws_lambda/integration.rbs Outdated
Comment thread spec/datadog/appsec/contrib/aws_lambda/gateway/watcher_spec.rb Outdated
Comment thread spec/datadog/appsec/contrib/aws_lambda/gateway/watcher_spec.rb Outdated
Comment thread spec/datadog/appsec/contrib/aws_lambda/waf_addresses_spec.rb
Comment thread spec/datadog/appsec/contrib/aws_lambda/waf_addresses_spec.rb Outdated
Strech and others added 4 commits May 4, 2026 16:22
Stop injecting fake values (200 status, GET method, / path) when
AWS event fields are missing — let WAF handle absent addresses via
compact. Rename parse_body local to body, simplify guard returns,
reorder requires, and update RBS nullability. In specs: rename
appsec_context to context, remove events let indirection, pre-compute
base64 fixture.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Return early from from_response when payload is nil or empty
instead of computing empty hashes for WAF.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Drop v1/v2 fallback chains — WAFAddresses now reads standard keys
(method, path, source_ip, query, query_string, etc.) produced by
lambda-rb's event normalizer. Unify cookie parsing for both v2
cookie arrays and v1 Cookie header. Remove extract_method and
parse_query methods that were just fallback wrappers.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Comment thread lib/datadog/appsec/contrib/aws_lambda/integration.rb
Strech and others added 3 commits May 6, 2026 10:46
The caller always provides the argument; nil is handled by the guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Add description to the WAFAddresses module
@Strech
Strech marked this pull request as ready for review May 6, 2026 09:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: afc234367b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/datadog/appsec/contrib/aws_lambda/integration.rb
@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented May 6, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 44.53%
Overall Coverage: 97.15% (-0.02%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: b6f988b | Docs | Datadog PR Page | Give us feedback!

Strech and others added 2 commits May 6, 2026 14:56
V2 events now carry `query` from lambda-rb normalizer. Add realistic V2
test and keep the query_string-only fallback path covered separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@Strech
Strech merged commit e16e4ea into master May 8, 2026
585 checks passed
@Strech
Strech deleted the appsec-61864-add-appsec-aws-lambda-contrib branch May 8, 2026 09:01
@dd-octo-sts dd-octo-sts Bot added this to the 2.33.0 milestone May 8, 2026
@Strech Strech mentioned this pull request May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

appsec Application Security monitoring product integrations Involves tracing integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants