falco icon indicating copy to clipboard operation
falco copied to clipboard

[Proposal] Allow for custom outputs wrapper fields

Open incertum opened this issue 1 year ago • 19 comments

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 avatar Jul 08 '24 18:07 incertum

@falcosecurity/falco-maintainers

incertum avatar Jul 08 '24 18:07 incertum

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 https://github.com/falcosecurity/falco/issues/3235. Maybe, we can design the two things at the same time

just my 2 cents

leogr avatar Jul 18 '24 14:07 leogr

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.

leogr avatar Jul 18 '24 14:07 leogr

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 avatar Jul 18 '24 18:07 incertum

/milestone 0.39.0

/assign

incertum avatar Jul 18 '24 18:07 incertum

@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.

leogr avatar Aug 29 '24 09:08 leogr

@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.

incertum avatar Aug 30 '24 03:08 incertum

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).

leogr avatar Aug 30 '24 08:08 leogr

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.

sgaist avatar Aug 30 '24 09:08 sgaist

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

Issif avatar Aug 30 '24 12:08 Issif

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). :thinking:

leogr avatar Aug 30 '24 12:08 leogr

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.

incertum avatar Aug 31 '24 23:08 incertum

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

leogr avatar Sep 02 '24 08:09 leogr

/milestone 0.40.0

FedeDP avatar Sep 16 '24 08:09 FedeDP

Issues go stale after 90d of inactivity.

Mark the issue as fresh with /remove-lifecycle stale.

Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Provide feedback via https://github.com/falcosecurity/community.

/lifecycle stale

poiana avatar Dec 15 '24 10:12 poiana

Not yet entirely sure about this. Pushing to the following release.

/remove-lifecycle stale /milestone 0.41.0

leogr avatar Dec 16 '24 08:12 leogr

Issues go stale after 90d of inactivity.

Mark the issue as fresh with /remove-lifecycle stale.

Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Provide feedback via https://github.com/falcosecurity/community.

/lifecycle stale

poiana avatar Mar 16 '25 10:03 poiana

/remove-lifecycle stale

FedeDP avatar Mar 17 '25 08:03 FedeDP

/milestone 0.42.0

FedeDP avatar May 27 '25 13:05 FedeDP

Issues go stale after 90d of inactivity.

Mark the issue as fresh with /remove-lifecycle stale.

Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Provide feedback via https://github.com/falcosecurity/community.

/lifecycle stale

poiana avatar Aug 25 '25 16:08 poiana

Stale issues rot after 30d of inactivity.

Mark the issue as fresh with /remove-lifecycle rotten.

Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Provide feedback via https://github.com/falcosecurity/community.

/lifecycle rotten

poiana avatar Oct 24 '25 10:10 poiana

Rotten issues close after 30d of inactivity.

Reopen the issue with /reopen.

Mark the issue as fresh with /remove-lifecycle rotten.

Provide feedback via https://github.com/falcosecurity/community. /close

poiana avatar Nov 23 '25 10:11 poiana

@poiana: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.

Reopen the issue with /reopen.

Mark the issue as fresh with /remove-lifecycle rotten.

Provide feedback via https://github.com/falcosecurity/community. /close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

poiana avatar Nov 23 '25 10:11 poiana