Open cfryanr opened 2 weeks ago
Attention: Patch coverage is 80.71895%
with 59 lines
in your changes missing coverage. Please review.
Project coverage is 30.89%. Comparing base (
dd80627
) to head (b2873cf
).
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
WIP for implementing audit logging. Early draft for proof of concept and discussion.
This draft differs from the proposal document, which is over two years old. In that doc, I proposed that we do a bunch of extra work to make a fancy sidecar container that would allow us to seperate the audit logs from the regular error/warning/debug/info/trace logs, to make it easier for admin users to export their audit logs seperately. However, much time has passed since then and I no longer believe that is nessessary. Fluentbit and other log exporting tools have improved since then. Fluentbit now includes tools which allow you to separate lines from a pod log and send those special lines to a different destination (example of that shown below).
Instead, this PR outputs the new audit log events into the regular pod log, and makes them easy to grep by always including
"auditEvent":true
on every log line which is for an audit event.The key/values in audit event logs are:
auditEvent
equal totrue
level
, which for audit line will always be equal toinfo
timestamp
caller
(line of code which caused the log)message
which for audit lines is effectively the event type. The value will always be one the messages declared as an enum inaudit_events.go
, which is effectively a catalog of all possible audit event types. No string interpolation should ever be done into themessage
value.stacktrace
key whose value shows a full Go stacktrace for the caller. This is the case for all lines of our pod logs, and audit lines are no exception.auditID
which is a unique ID for every HTTP request, to allow multiple lines of audit events to be correlated when they came from a single HTTP request. This audit ID is also returned to the client as an HTTP response header to allow for correlation between the request as observed by the client and the logs as observed by the administrator.sessionID
which is the unique ID of a stored Pinniped Supervisor session, to allow audit events to be correlated which relate to a single session even when they are caused by different requests or controllers. E.g. samesessionID
across fresh login, token exchange, refreshes, and session garbage collection.message
).Other changes compared to the original proposal doc:
message
instead of proposedevent
, etc.).Note that aggregated API endpoints, such as the Concierge's TokenCredentialRequest, already support Kubernetes audit logging. Additionally, they already have some trace logging using the
k8s.io/utils/trace
package, but those logs only appear in our pod logs if the user has configured the log level to beinfo
or higher (not by default). If we add our own audit logging to these endpoints, then ideally theauditID
would match that shown in the Kubernetes audit logs to allow for correlation between the pod logs and the audit logs. The approach taken in this PR works that way.Here is an example Pinniped audit log event from a Concierge pod for a TokenCredentialRequest. Note that this has been piped through
jq
for pretty printing purposes.And here are the two audit log events from the Kubernetes API audit log for the same TokenCredentialRequest request, shown for when Kube API audit logging is configured to the
metadata
level. They show that this was an anonymous request, but they have no way of knowing how Pinniped resolved the identity of the user (which is shown by the Pinniped audit log above). Note that they have the same unique audit ID as above, even though they are not found in the same log file. Note that these have been piped throughjq
for pretty printing purposes.Note that for manual testing, Kubernetes API audit logs can be enabled in Kind clusters: https://kind.sigs.k8s.io/docs/user/auditing.
Here is an example snippet from a custom
values.yaml
for the Fluentbit Helm Chart showing how to route Pinniped audit logs to a different destination. This example is not for production use because the output destination is stdout. See comments below for more info.Release note:
Audit logging will be a user-facing feature for admin users and needs release notes and documentation.