Skip to content

[APPSEC-61865] Add inferred span and AppSec calls for API Gateway#136

Draft
Strech wants to merge 32 commits intomainfrom
appsec-61865-add-inferred-span-for-api-gateway
Draft

[APPSEC-61865] Add inferred span and AppSec calls for API Gateway#136
Strech wants to merge 32 commits intomainfrom
appsec-61865-add-inferred-span-for-api-gateway

Conversation

@Strech
Copy link
Copy Markdown
Member

@Strech Strech commented Mar 25, 2026

What does this PR do?

Compute inferred span for AWS Lambda that suppose to be a service-entry span. In addition - initialize AppSec component (if possible), push events to it and flush captured security events.

Motivation

Part of Endpoint Discovery & Correlation from Inferred Spans RFC

Testing Guidelines

Additional Notes

I would need some assistance to get more context over testing.

Types of changes

  • Bug fix
  • New feature
  • Breaking change
  • Misc (docs, refactoring, dependency upgrade, etc.)

Strech and others added 15 commits March 18, 2026 17:44
Remove all AppSec lifecycle management (context creation,
Event.record, export_metrics, Context.deactivate) — now
owned by dd-trace-rb watcher. Listener becomes a dumb
data provider: just pushes raw event/response hashes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Lambda::AppSec owns full context lifecycle (create, activate,
record, export, deactivate). Lambda::Trace::InferredSpan owns
span creation and finishing. Listener becomes thin orchestrator.

AppSec context now targets the inferred span (service-entry),
so tags land there directly — tag propagation hack removed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove [DEBUG:inject_appsec] debug logging from inject_appsec_data
- Restore removed comments in send_end_invocation_request
- Revert unnecessary ::Datadog:: namespace prefixes in lambda.rb

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…vices check

F29: Move `instrument(:aws_lambda)` from per-invocation `AppSec.on_start`
to `configure_apm` after yield block. The `instrument` method is a no-op
when appsec is disabled (checks `enabled` internally), so no guard needed.
Matches Python's pattern of one-time initialization.

F30: Reuse `Datadog::Lambda.trace_managed_services?` in InferredSpan
instead of duplicating the ENV reading logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
F31: 44 new examples covering:
- AppSec.on_start: enabled/disabled, context creation, gateway push,
  fallback to active trace/span, missing security engine, error handling
- AppSec.on_finish: no active context, gateway push, Event.record,
  metrics/telemetry export, context deactivation, deactivation on error
- InferredSpan.create: managed services disabled, non-hash events,
  missing requestContext/stage/httpMethod, v1 span name/tags/resource_key,
  v2 span name/tags/resource_key, trace_digest continuation, empty domain,
  error handling
- InferredSpan.finish: nil span, statusCode tagging, non-hash response,
  nil response, error handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
F25: `Datadog::Tracing.trace()` returns a SpanOperation, not a
TraceOperation. Rename `@trace` to `@span` in Listener to reflect
the actual type. Remove stale class-level `@trace = nil`.

AppSec.on_start now always uses `Datadog::Tracing.active_trace` for
the TraceOperation (matching Rack's RequestMiddleware pattern) and
receives only the target span (inferred span) as an argument, with
fallback to `active_span`.

F26: Pass `@inferred_span || @span` to `inject_appsec_data` so the
extension reads tags from the span where AppSec actually sets them.

F32: Variable renamed from `@trace` to `@span`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Rewrite specs to test behavior instead of internals
* Remove obsolete appsec files
Split the god method into ApiGatewayV1/V2 parser classes with a uniform
interface, and rewire InferredSpan.create as a PARSERS dispatcher +
build_span builder. Existing behavior tests pass unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
http.status_code on the inferred span is not in the RFC and not checked
by system tests. Without it, finish() just delegates to span.finish —
the listener now calls @inferred_span&.finish directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread lib/datadog/lambda/inferred_span/api_gateway_v1.rb
Comment thread lib/datadog/lambda/inferred_span/api_gateway_v1.rb Outdated
Comment thread lib/datadog/lambda/trace/listener.rb Outdated
Comment thread lib/datadog/lambda/trace/listener.rb Outdated
Comment thread lib/datadog/lambda/inferred_span.rb Outdated
Comment thread lib/datadog/lambda/inferred_span.rb Outdated
Comment thread lib/datadog/lambda/inferred_span.rb Outdated
Comment thread lib/datadog/lambda/inferred_span.rb Outdated
Strech and others added 3 commits March 26, 2026 17:30
Removes hidden dependency on Datadog::Tracing.active_trace and
active_span — the listener now passes both explicitly. Span selection
policy (prefer inferred span over lambda span) moves to the caller.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DD_TRACE_MANAGED_SERVICES controls outbound AWS SDK call tracing,
not inbound inferred spans. The guard was added by mistake during
extraction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread lib/datadog/lambda/inferred_span/api_gateway_v2.rb Outdated
Comment thread lib/datadog/lambda/utils/extension.rb Outdated
Comment thread lib/datadog/lambda/appsec.rb Outdated
Comment thread lib/datadog/lambda/inferred_span.rb Outdated
Comment thread lib/datadog/lambda.rb
Comment thread test/datadog/lambda/inferred_span/api_gateway_v1.spec.rb Outdated
Comment thread test/datadog/lambda/inferred_span/api_gateway_v2.spec.rb Outdated
Comment thread test/datadog/lambda/utils/extension.spec.rb Outdated
Comment thread test/datadog/lambda/appsec.spec.rb
Comment thread test/datadog/lambda/appsec.spec.rb Outdated
Comment thread test/datadog/lambda/appsec.spec.rb Outdated
Comment thread test/datadog/lambda/appsec.spec.rb Outdated
Comment thread test/datadog/lambda/inferred_span.spec.rb Outdated
Comment thread test/datadog/lambda/inferred_span.spec.rb Outdated
Comment thread test/datadog/lambda/inferred_span.spec.rb
Strech and others added 5 commits March 26, 2026 18:52
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nstants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…in continue_from test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Strech Strech force-pushed the appsec-61865-add-inferred-span-for-api-gateway branch from 80f3ad5 to eee4562 Compare March 27, 2026 14:52
Strech and others added 2 commits March 27, 2026 16:31
Comment thread lib/datadog/lambda/trace/listener.rb Outdated
Comment thread lib/datadog/lambda/inferred_span/api_gateway_v2.rb
Comment thread test/datadog/lambda/inferred_span.spec.rb Outdated
@Strech Strech changed the title [APPSEC-61865] (WIP) Add inferred span and AppSec calls for API Gateway [APPSEC-61865] Add inferred span and AppSec calls for API Gateway Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant