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

[Proposal] Allow for custom outputs wrapper fields #3277

Open
incertum opened this issue Jul 8, 2024 · 14 comments
Open

[Proposal] Allow for custom outputs wrapper fields #3277

incertum opened this issue Jul 8, 2024 · 14 comments
Assignees
Milestone

Comments

@incertum
Copy link
Contributor

incertum commented Jul 8, 2024

Motivation

Falco currently sends alerts/logs with a predefined set of wrapper fields, some of which are configurable (such as tags, etc.).

For example:

{
  "hostname": "test-host",
  "priority": "Informational",
  "rule": "Test",
  "source": "syscall",
  "time": "2024-07-03T14:24:51.979324400Z",
  "output_fields": {}
}

Feature

For certain use cases, the end user may need to add custom static wrapper fields similar to hostname. We could support the following:

  • Static key and value
  • Static key and resolved value (such as an environment variable)

falco.yaml brainstorming: @LucaGuerra you always have great ideas on how to design the new falco.yaml UX, any ideas?

outputs_static_fields:
- key: my_static_outputs_field1
  value: "outputs_field1_string_value"
- key: my_static_outputs_field2
  value: ${CUSTOM_ENV_TO_BE_RESOLVED}

Dynamic custom fields that can change for each event or rule would not be supported. For such use cases, a custom plugin should be developed.

We have had similar requests in the past, but I can’t find the best issues to reference right now.

@incertum
Copy link
Contributor Author

incertum commented Jul 8, 2024

@falcosecurity/falco-maintainers

@leogr
Copy link
Member

leogr commented Jul 18, 2024

I'm in favor of something like that. Some time ago, I thought I would make a plugin for that, but I never did it. Now, I agree it makes sense to have this feature built-in to Falco for static fields.

Also, see that this may be somehow related to #3235. Maybe, we can design the two things at the same time

just my 2 cents

@leogr
Copy link
Member

leogr commented Jul 18, 2024

PS

I would consider force outputting these static fields under a specific class (e.g., labels.*) to avoid polluting the global space and avoid possible clashing.

@incertum
Copy link
Contributor Author

incertum commented Jul 18, 2024

I'm in favor of something like that. Some time ago, I thought I would make a plugin for that, but I never did it. Now, I agree it makes sense to have this feature built-in to Falco for static fields.

👍

Also, see that this may be somehow related to #3235. Maybe, we can design the two things at the same time

yes this would be great!

I would consider force outputting these static fields under a specific class (e.g., labels.*) to avoid polluting the global space and avoid possible clashing.

Edit: We can offer prefixes. For my use however, the name needs to be in an exact way, can't have a prefix.

@incertum
Copy link
Contributor Author

/milestone 0.39.0

/assign

@leogr
Copy link
Member

leogr commented Aug 29, 2024

@incertum

I would consider force outputting these static fields under a specific class (e.g., labels.*) to avoid polluting the global space and avoid possible clashing.

Edit: We can offer prefixes. For my use however, the name needs to be in an exact way, can't have a prefix.

Can you provide a real use case for not having a prefix?

Let me explain: I wanted to avoid polluting the root keys in the JSON because this can create clashes in the future (e.g., think about one user who uses a custom key named a, then—at some point later—we introduce a new key named a). That said, if we have a compelling use case, I totally agree we have to find a clean solution.

@incertum
Copy link
Contributor Author

@incertum

I would consider force outputting these static fields under a specific class (e.g., labels.*) to avoid polluting the global space and avoid possible clashing.

Edit: We can offer prefixes. For my use however, the name needs to be in an exact way, can't have a prefix.

Can you provide a real use case for not having a prefix?

Let me explain: I wanted to avoid polluting the root keys in the JSON because this can create clashes in the future (e.g., think about one user who uses a custom key named a, then—at some point later—we introduce a new key named a). That said, if we have a compelling use case, I totally agree we have to find a clean solution.

That's a great call out. The one use case that comes to mind is that your downstream systems requires a very specific key and it has to string match exactly. But I agree we would need to have rule(s) for name clashes in place.

@leogr
Copy link
Member

leogr commented Aug 30, 2024

That's a great call out. The one use case that comes to mind is that your downstream systems requires a very specific key and it has to string match exactly. But I agree we would need to have rule(s) for name clashes in place.

If we don't want to namespace the key, I see only two compelling solutions:

  1. Allow user-defined keys to shadow predefined keys. This will allow full flexibility, but with great power comes great responsibility.
  2. Emit an error when a user-defined key clashes with predefined keys. This will prevent misconfiguration (and headaches). However, it can disrupt the remote event if we introduce a predefined key that a user is already using for another purpose (and in such cases, there will be no easy workaround).

@sgaist
Copy link
Contributor

sgaist commented Aug 30, 2024

I am going to play the Devil's advocate but if downstream requires fields that would otherwise be used by Falco or not namespaced, shouldn't there be a translation unit like https://docs.fluentd.org/ be put between Falco and that downstream to rearrange the output ? It might be a cannon for shooting a fly though.

@Issif
Copy link
Member

Issif commented Aug 30, 2024

Hi,

I think this is a feature of falcosidekick for years. For whom don't know the project, it's a proxy forwarder between a fleet of Falco and third parties.

You have for now 2 settings:

  • customfields: inject a static value in the output_fields section of the json payload from Falco. this value can be set at bootstrap with an env variable (by adding a % sign before the name)
  • templatedfields: inject a value in the the output_fields section of the json payload from Falco following a Go template, useful to set a default value, split or concatenate strings. the usable inputs are the already existing output_fields.

Here's a dummy example:

customfields:
  Akey: "AValue"
  Bkey: "BValue"
  Ckey: "%ENV_VAR"
templatedfields:
  "k8s.ns.labels.foo": '{{ or (index . "k8s.ns.labels.foo") "bar" }}' # keep the value of the 'k8s.ns.labels.foo' or set it with 'bar'

The config of Falcosidekick is here.

Moreover, I'll replicate these behaviors to inject tags to the payload, as requested by an end-user.

I chose to inject values into the output_fields section and not in a new one to be sure to be compliant with any third party already consuming the Falco events. The templatedfields setting, with its possibility to not set the key when it has already a value is a solution to avoid overrides.

Here's a real use case from a member of our community:

  • 2 clusters: dev, obsrv
  • in dev:
    • installs of falco + falcosidekick
  • in obsrv:
    • install of falco + falcosidekick + falcosidekick-ui
  • goal: get all events, from both clusters, into the same falcosidekick-ui, with a field to know the cluster name

Solution:

  • config for falcosidekick in dev:
     falcosidekick:
       config:
         customfields:
            cluster.name=dev
         webhook:
           url: http://obsrv:2801 # to forward the events to the second cluster
  • config for falcosidekick in obsrv:
     falcosidekick:
       config:
         templatefields:
            cluster.name='{{ or (index . "cluster.name") "obsrv" }}'
     webui:
     	enabled: true

@leogr
Copy link
Member

leogr commented Aug 30, 2024

shouldn't there be a translation unit like https://docs.fluentd.org/ be put between Falco and that downstream to rearrange the output ?

I chose to inject values into the output_fields section and not in a new one to be sure to be compliant with any third party already consuming the Falco events.

These are both good reasons not to implement this. And I'm wondering if it is worth implementing this feature (even though I'm still not against it). 🤔

@incertum
Copy link
Contributor Author

Thanks Sam, Thomas and Leo. Hearing all of your concerns. We can think more about it.

The good news is that with Luca's patch static fields from for example ENV variables can now be appended to the output_fields sub JSON.

@leogr
Copy link
Member

leogr commented Sep 2, 2024

@incertum I'd propose to move this for 0.40. Would it work for you?

@FedeDP
Copy link
Contributor

FedeDP commented Sep 16, 2024

/milestone 0.40.0

@poiana poiana modified the milestones: 0.39.0, 0.40.0 Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants