Skip to content

Conversation

duncanista
Copy link
Contributor

No description provided.

@duncanista duncanista force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from a93c4e8 to 2ec14e9 Compare June 3, 2025 18:35
@duncanista duncanista force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from 346a130 to ba7a1da Compare June 6, 2025 17:36
@RomainMuller RomainMuller force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from 0e3ae0b to ba7a1da Compare July 7, 2025 16:11
@RomainMuller RomainMuller force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from 97a4a9e to e0902ba Compare July 7, 2025 16:42
@RomainMuller RomainMuller force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from a177439 to cd8e2cf Compare July 9, 2025 10:39
async fn extract(self) -> HttpData;
}

pub(super) async fn extract_request_address_data(body: &Bytes) -> Option<(HttpData, RequestType)> {
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 remember you mentioned maybe we want to eventually consolidate this with the triggers – overall, great

Deserializing into type might be slow since payloads can technically be up to 6MB

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, next file is doing a similar check from triggers code

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 see that specific logic, as you mentioned privately, was ported from Go, maybe for the ones that already exist here in the triggers, could we use that same logic and for the events that we don't cover for inferred spans, I.E. Kong, we maintain the Go port?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the current approach is more complex than necessary -- rust deserialization is more strict than Go's (i.e, unlike in Go, not everything is deemed optional)... Probably we can simply do the "try deserializing into the candidate types until one works".

The Kong payload we probably just need to carry a specific model struct for; but I am struggling to find documentation for what shape it's supposed to have from Kong... More research warranted.

Comment on lines 60 to 65
for (key, value) in appsec_context.tags() {
self.invocation_span
.meta
.entry(key.clone())
.or_insert(value.clone());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can't we use extend here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Extend will replace existing keys with values found in the iterator, and I precisely want this NOT to happen.


// Note: We intentionally don't set `actor.ip` because we don't have a definitive signal here.

//TODO(romain.marcadier): Figure out whether we can set "_dd.runtime_family" here; and to what value.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

if there is a set of valid values, we can talk about how and when to set it, we get the specific runtime at a later point of init, but we guarantee it will arrive

Copy link
Contributor

Choose a reason for hiding this comment

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

There is indeed... Valid values are:

  • nodejs
  • ruby
  • jvm
  • dotnet
  • go
  • php
  • python

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 see, we can do this at a later stage, but it should be possible as we get the set of runtimes with specific keys, we can just map them to the family later

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My main concern is if there's a better way to tie contexts, I won't know until I inspect the code thoroughly, but so far this looks good

Copy link
Contributor

Choose a reason for hiding this comment

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

I am definitely open to suggestions on that front... The cold start handling is the main reason it is done this way (because its derection relies on the buffer being empty).

@RomainMuller RomainMuller force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from 639307e to cec9428 Compare July 21, 2025 14:56
debug!("Starting ASM processor");

if is_standalone() {
info!(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should this be a warn?

Copy link
Contributor

Choose a reason for hiding this comment

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

In principle this is the result of an intentional action by the user... so I doubt it's relevant to warn here? But I don't feel all too strongly about that.

Comment on lines +17 to +23
let mime_type = match content_type
.unwrap_or("application/json")
.parse::<mime::Mime>()
{
Ok(mime) => mime,
Err(e) => return Err(e.into()),
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would this actually error at any moment since we're always setting the default as application/json which in theory should always parse successfully?

Copy link
Contributor

Choose a reason for hiding this comment

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

You can't assume the body is even valid JSON -- it comes from the client-side of the chain... Folks make mistakes!

@@ -390,7 +408,8 @@ impl Processor {
_ = offsets.process_chan_tx.send(());
}

// todo(duncanista): Add missing metric tags for ASM
context.absorb_appsec_tags();
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 think we could, since this is important part, make this method receive a mutable span which it will add the tags to.

Maybe in the processor, or trace agent, whichever seems fit, we detect if a span is the Lambda span and we absorb the tags there. This would make it work for all runtimes, WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes I think this is the way forward, really. And this logic can can probably be moved to the appsec::Processor as well.

@RomainMuller RomainMuller force-pushed the jordan.gonzalez/appsec/support-application-and-api-protection branch from 3db3c34 to 23d8fb0 Compare July 25, 2025 13:30
@duncanista duncanista changed the title feat: serverless App & API Protection poc: App & API Protection Jul 25, 2025
@RomainMuller
Copy link
Contributor

Superceded by #755

@RomainMuller RomainMuller deleted the jordan.gonzalez/appsec/support-application-and-api-protection branch August 5, 2025 07:54
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.

2 participants