update(proposals): address review comments and suggestions

Co-authored-by: Lorenzo Fontana <lo@linux.com>
Signed-off-by: Leonardo Di Donato <leodidonato@gmail.com>
This commit is contained in:
Leonardo Di Donato 2019-09-25 09:23:21 +00:00 committed by Leo Di Donato
parent 510d215558
commit 47ab5bf39d

View File

@ -2,50 +2,50 @@
<!-- toc --> <!-- toc -->
- [Summary](#summary) - [gRPC Falco Output](#grpc-falco-output)
- [Motivation](#motivation) - [Summary](#summary)
* [Goals](#goals) - [Motivation](#motivation)
* [Non-Goals](#non-goals) - [Goals](#goals)
- [Proposal](#proposal) - [Non-Goals](#non-goals)
* [Use cases](#use-cases) - [Proposal](#proposal)
* [Diagrams](#diagrams) - [Use cases](#use-cases)
* [Design Details](#design-details) - [Diagrams](#diagrams)
- [Design Details](#design-details)
<!-- tocstop --> <!-- tocstop -->
## Summary ## Summary
We intend to build a simple gRPC contract and SDKs - eg., [falco#785](https://github.com/falcosecurity/falco/issues/785) - to allow users receive and consume the alerts regarding the violated rules. We intend to build a simple gRPC server and SDKs - eg., [falco#785](https://github.com/falcosecurity/falco/issues/785) - to allow users receive and consume the alerts regarding the violated rules.
## Motivation ## Motivation
The most valuable information that Falco can give to its users are the alerts. The most valuable information that Falco can give to its users are the alerts.
An alert is given by Falco each time a rule is matched.
At the current moment, however, Falco can deliver alerts in a very basic way, for example by dumping
them to standard output.
For this reason, many Falco users asked, with issues - eg., [falco#528](https://github.com/falcosecurity/falco/issues/528) - or in the [slack channel]() if we can find a more consumable way to An alert is an "output" when it goes over a transport, and it is emitted by Falco every time a rule is matched.
implement Falco outputs in an extensible way.
At the current moment, however, Falco can deliver alerts in a very basic way, for example by dumping them to standard output.
For this reason, many Falco users asked, with issues - eg., [falco#528](https://github.com/falcosecurity/falco/issues/528) - or in the [slack channel](https://sysdig.slack.com) if we can find a more consumable way to implement Falco outputs in an extensible way.
The motivation behind this proposal is to design a new output implementation that can meet our user's needs. The motivation behind this proposal is to design a new output implementation that can meet our user's needs.
### Goals ### Goals
- To decouple the outputs from the Falco code base - To decouple the outputs from the Falco code base
- To design and implement an additional output containing a gRPC client - To design and implement an additional output mode by mean of a gRPC **streaming** server
- To keep it as simple as possible - To keep it as simple as possible
- To have a simple contract interface - To have a simple contract interface
- To only have the responsibility to route Falco output requests and responses - To only have the responsibility to route Falco output requests and responses
- To continue supporting the old output formats by implementing their same interface - To continue supporting the old output formats by implementing their same interface
- To be secure by default - To be secure by default (**mutual TLS** authentication)
- To be asynchronous and non-blocking - To be **asynchronous** and **non-blocking**
- To implement a Go SDK
### Non-Goals ### Non-Goals
- To substitute existing outputs (stdout, syslog, etc.) - To substitute existing outputs (stdout, syslog, etc.)
- To support connecting to multiple gRPC servers - To support different queing systems than the default (round-robin) one
- Users can have a single server multiplexing requests to multiple servers
- To support queuing mechanisms for message retransmission - To support queuing mechanisms for message retransmission
- Users can have a local gRPC relay server along with Falco that multiplexes connections and handles retires and backoff - Users can have a local gRPC relay server along with Falco that multiplexes connections and handles retires and backoff
- To change the output format - To change the output format
@ -53,7 +53,6 @@ The motivation behind this proposal is to design a new output implementation tha
- Users can already override rules changing their output messages - Users can already override rules changing their output messages
- To act as an orchestrator for Falco instances - To act as an orchestrator for Falco instances
## Proposal ## Proposal
### Use cases ### Use cases
@ -61,6 +60,7 @@ The motivation behind this proposal is to design a new output implementation tha
- Receive Falco events with a well-defined contract over wire - Receive Falco events with a well-defined contract over wire
- Integrate Falco events with existing alerting/paging mechanisms - Integrate Falco events with existing alerting/paging mechanisms
- Integrate Falco events with existing monitoring infrastructures/tools - Integrate Falco events with existing monitoring infrastructures/tools
- Falco outputs SDKs for different languages
### Diagrams ### Diagrams
@ -70,66 +70,44 @@ The following sequence diagram illustrates the flow happening for a single rule
### Design Details ### Design Details
- When an `Emit` results in an error the response contains and error code and message
- Errored emits MUST be handled by Falco by sending the same event in the standard output enriched with the info about the failed `Emit` RPC
- The RPC communication is asynchronous and non-blocking
- The RPC communication is made of two (`Output` and `Response`) bi-directional streams
- `Output` and `Response` messages are correlated through the `id` field
- The `id` field is crafted by the gRPC output client
- The communication is secured using TLS and the builtin client authentication mechanism
Here is the proto3 contracts definitions for the client and the server SDK. Here is the proto3 contracts definitions for the client and the server SDK.
```proto3 ```proto3
// Overview syntax = "proto3";
// The `FalcoOutputService` service defines the Emit RPC call import "google/protobuf/timestamp.proto";
// that is used to do a bidirectional stream of events between the output server and Falco. import "schema.proto";
// The `Output` message is the logical representation of the output model, package falco.output;
// it contains all the elements that Falco emits in an output along with the
// definitions for priorities and sources. It is given as an input to the Emit RPC call.
// The `Response` message is the logical representation of the response to an Emit option go_package = "github.com/falcosecurity/client-go/pkg/api/output";
// RPC call, it contains a message and the information on wether the server returned an error
// while handling the provided `Output`.
// The `Output` and `Response` messages are enriched with an unique identifier that is needed // The `subscribe` service defines the RPC call
// because of the asynchronous nature of the streams in order to correlate them. // to perform an output `request` which will lead to obtain an output `response`.
service service {
service FalcoOutputService { rpc subscribe(request) returns (stream response);
rpc Emit (stream Output) returns (stream Response);
} }
message Output { // The `request` message is the logical representation of the request model.
string id = 1; // It is the input of the `subscribe` service.
Timestamp time = 2; // It is used to configure the kind of subscription to the gRPC streaming server.
enum Priority { message request {
EMERGENCY = 0; bool keepalive = 1;
ALERT = 1; // string duration = 2; // TODO(leodido, fntlnz): not handled yet but keeping for reference.
CRITICAL = 2; // repeated string tags = 3; // TODO(leodido, fntlnz): not handled yet but keeping for reference.
ERROR = 3;
WARNING = 4;
NOTICE = 5;
INFORMATIONAL = 6;
DEBUG = 7;
}
Priority priority = 3;
enum Source {
SYSCALL = 0;
K8S_AUDIT = 1;
}
Source source = 4;
string rule = 5;
string format = 6;
string output = 7;
map<string, string> output_fields = 8;
} }
message Response { // The `response` message is the logical representation of the output model.
string id = 1; // It contains all the elements that Falco emits in an output along with the
int32 code = 2; // definitions for priorities and source.
string message = 3; message response {
google.protobuf.Timestamp time = 1;
falco.schema.priority priority = 2;
falco.schema.source source = 3;
string rule = 4;
string output = 5;
map<string, string> output_fields = 6;
// repeated string tags = 7; // TODO(leodido,fntlnz): tags not supported yet, keeping for reference
} }
``` ```