falco
falco copied to clipboard
[Proposal] Allow for custom outputs wrapper fields
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.
@falcosecurity/falco-maintainers
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
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.
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.
/milestone 0.39.0
/assign
@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
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 nameda). 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.
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:
- Allow user-defined keys to shadow predefined keys. This will allow full flexibility, but with great power comes great responsibility.
- 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).
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.
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 theoutput_fieldssection 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 theoutput_fieldssection 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 existingoutput_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
- installs of
- in
obsrv:- install of
falco+falcosidekick+falcosidekick-ui
- install of
- goal: get all events, from both clusters, into the same
falcosidekick-ui, with a field to know thecluster 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
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_fieldssection 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:
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 I'd propose to move this for 0.40. Would it work for you?
/milestone 0.40.0
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
Not yet entirely sure about this. Pushing to the following release.
/remove-lifecycle stale /milestone 0.41.0
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
/remove-lifecycle stale
/milestone 0.42.0
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
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
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: 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.